检测技术试验报告.docx
《检测技术试验报告.docx》由会员分享,可在线阅读,更多相关《检测技术试验报告.docx(20页珍藏版)》请在冰点文库上搜索。
检测技术试验报告
基于51单片机温度自保护的直流电机控制系统
一、实验目的
1.了解直流电机控制的基本方法。
2.通过本实验课程,进一步掌握单片机的基本原理、以及扩展微机系统多种接口的基本方法,具有基于微机和单片机系统进行软硬件综合设计和实现的能力。
3.了解微机系统的基本软硬件结构,熟悉和掌握单片机系统串行口、并行口、定时器/计数器、中断和LCD液晶显示接口等一些基本芯片的使用方法,掌握基于89C51系列单片机指令系统的汇编语言程序设计或C语言程序设计和调试方法。
二、实验原理和内容
本系统使用到的硬件模块有:
LCD12864M液晶、简单I/O、DS18B20温度测控、蜂鸣器、直流电机、PWM电压功放器、LED指示灯等。
8051单片机是标准的40引脚双列直插式集成电路芯片,P0.0~P0.7P0口8位双向口线(在引脚的39~32号端子)。
P1.0~P1.7P1口8位双向口线(在引脚的1~8号端子)。
P2.0~P2.7P2口8位双向口线(在引脚的21~28号端子)。
P3.0~P3.7P3口8位双向口线(在引脚的10~17号端子)。
本实验通过利用定时器T0,控制IO口输出高电平和低电平的时间,产生PWM方波来控制直流电机转速。
通过DS18B20温度测控读取当前温度,如果在电机运转过程中,温度超过警报温度,则电机停止旋转。
下面简要的介绍下本系统的各个模块:
ØDS18B20是DALLAS生产的一线制串行接口数字式温度计。
它的温度测量范围是-55C~125C,-10C~85C内误差为正负0.5C;9-12位转换精度,转换时间100ms-750ms,通常为500ms。
本系统利用DS18B20对电机温度进行实时的模拟检测采集。
ØLCD12864M是将液晶显示器件、连接件、集成电路、背光源结构装配在一起的组件。
它的分辨率为128×64,可显示图形或4行共32个16×16点阵的汉字,并且内置8192个16×16点阵的汉字库、128个字符、64×256点阵的显示RAM。
12864M与单片机之间使用串行接口方式(PSB=0),RS(CS)为串行的片选信号,R/W(SID)为串行数据口,E(CLK)为串行同步时钟。
串行数据传送一帧分三个字节:
串行控制指令、数据的高4位和数据的低4位。
ØPWM是通过定时器T0,控制IO口输出高电平的时间TH和低电平的时间TL,其占空比为TH/(TH+TL)。
ØLED指示灯链接P2口,当P2位口输出低电平时,指示灯电亮,用以指示速度档。
当温度超过警报温度时,P2反复输出高电平和低电平,指示灯闪烁报警。
Ø蜂鸣器接P1^7口,当温度超过警报温度时,P1^7输出低电平,蜂鸣器警报。
三、实验设备和软件平台
硬件:
实验箱(一台)、示波器(一台)、单片机仿真器(一台)、连接线(若干)
软件:
星研集成环境软件
四、实验各模块连接结构
1、系统的总体框架图:
2、实验连线:
LCD液晶:
CS—P1^0
SID—P1^1
SCLK—P1^2
PSB—P1^3
拨码开关:
P0
LED灯:
P2
蜂鸣器:
P1^7
PWM:
P1^6
温度DS18B20:
P3^5
五、实验注意事项及总结
在本系统的调试完善过程中,发现了不少的问题,主要有:
1、在调试时,要把P2调为I/O模式。
2、晶振要设置为12MHZ。
3、不要带电操作实验箱。
4、不能存太多全局变量,会使51单片机内部RAM不够,导致地址溢出,程序出错。
5、各种芯片初始化要十分注意,特别是温度DS18B20的初始化过程中不能有中断出现,而步进电机是需要定时中断来定时驱动的,很难让它们不互相影响,这也是在实验中为什么有时会出现温度很大或为零的原因。
最好的解决方法就是不使用中断。
六、附录——实验程序
//头文件
#include
#include
#include
#include
//*******************接线说明******************************************
/*液晶:
CS—P1^0SID—P1^1SCLK—P1^2PSB—P1^3
调速档拨码开关:
—P0
指示灯:
—P2
蜂鸣器:
—P1^7
*/
//宏定义
#defineucharunsignedchar
#defineuintunsignedint
//函数声明
voidLCDString(unsignedchar*pStr);
voidW_1byte(unsignedcharRW,unsignedcharRS,unsignedcharW_data);
voidAlarm(void);
//警报温度大小定义
#defineTEMPERATURE_ALARM21.0
//液晶接口
sbitCS=P1^0;
sbitSID=P1^1;
sbitSCLK=P1^2;
sbitPSB=P1^3;
//温度//TOUT接T1,T1口即为P3.5
sbitDQ=P3^5;
unsignedintT;//温度测量
floatradio;//占空比
unsignedchartimeH=0x3c,timeL=0xb0;
unsignedintflag0;//PWM标志位
unsignedintflag1;//温度警报标志,1for超过
//蜂鸣器
sbitBeeper=P1^7;
//直流电机CTRL接功放E2的OUT(OUT1),功放E2的IN(IN1)接P1.6
sbitDianji=P1^6;
//液晶显示器显示的内容
codeunsignedcharlcd_data80[]={"MotorControl"};
codeunsignedcharlcd_data88[]={"ALM温度:
21.0"};
//存储测量温度值
unsignedcharTemp_Value[]={0x00,0x00};
//延时
voiddelay(unsignedchari)
{
while(i--)
{;}
}
//温度测量模块
//初始化
unsignedcharInit_DS18B20()
{
unsignedcharstatus;
DQ=1;
delay(8);
DQ=0;
delay(90);
DQ=1;
delay(8);
status=DQ;
delay(100);
DQ=1;
returnstatus;
}
//读字节
unsignedcharReadOneByte()
{
unsignedchari,dat=0;
DQ=1;_nop_();
for(i=0;i<8;i++)
{
DQ=0;
dat>>=1;
DQ=1;
_nop_();_nop_();
if(DQ)dat|=0x80;
delay(30);
DQ=1;
}
returndat;
}
//写字节
voidWriteOneByte(unsignedchardat)
{
unsignedchari;
for(i=0;i<8;i++)
{
DQ=0;
DQ=dat&0x01;
delay(5);
DQ=1;
dat>>=1;
}
}
//读取温度值
voidRead_Temperature()
{
if(Init_DS18B20()!
=1);
{
WriteOneByte(0xcc);
WriteOneByte(0x44);
Init_DS18B20();
delay(100);
WriteOneByte(0xcc);
WriteOneByte(0xbe);
Temp_Value[0]=ReadOneByte();
Temp_Value[1]=ReadOneByte();
}
}
//温度值显示及警报操作
voidDisplay_Temperature()
{
bitflag;
ucharDisplayBuf[20];
ucharNotAlarmBuf[20];
ucharlsb,msb;
uinttemp,t1;
floatt2;
msb=Temp_Value[1];//Signbyte+lsbit
lsb=Temp_Value[0];//Tempdatapluslsb
if((msb&0xF0)>0)
{//判断是否为负温度
flag=1;
}
else
{
flag=0;
}
if(flag)
{//如果为负温度取反加1
temp=((uint)msb<<8)|lsb;
temp=~temp+1;
msb=temp/256;
lsb=temp%256;
}
t1=msb<<4;
t1|=(lsb>>4);//t1为温度值的整数部分
t2=(lsb&0x0F)*0.0625+t1;
T=t1;
//液晶显示当前温度值
sprintf(DisplayBuf,"电机温度:
%2.1f℃\0",t2);
W_1byte(0,0,0x88);
LCDString(DisplayBuf);
//判断温度是否超过警报值
if(t2>=TEMPERATURE_ALARM)
{
Alarm();//警报函数
flag1=1;
}
else
{
flag1=0;//温度正常情况操作,液晶显示,电机转动,蜂鸣器关闭
sprintf(NotAlarmBuf,"设定占空比:
%2.0f%%",radio);
W_1byte(0,0,0x98);
LCDString(NotAlarmBuf);
Beeper=1;
}
}
//LCD液晶显示
//函数作用:
负责向SID串行写入8个bit位
voidWrite_8bits(unsignedintW_bits)
{
unsignedinti;
unsignedintTemp_data;
for(i=0;i<8;i++)
{
Temp_data=W_bits;
Temp_data<<=i;
if((Temp_data&0x80)==0)//bit7iszero
{
SID=0;
_nop_();
SCLK=1;
_nop_();
_nop_();
SCLK=0;
_nop_();
SID=0;
}
else//bit7isone
{
SID=1;
_nop_();
SCLK=1;
_nop_();
_nop_();
SCLK=0;
_nop_();
SID=0;
}
}
}
//函数作用:
写一个字节的数据到12864液晶,包括指令和数据
//说明:
RW=1,从液晶读数据到MCU;RW=0,写一个数据到液晶;
//(一般RW都设为0,即只向液晶写数据,不读数据)
//RS="1",写入的是数据;RS=0,写入的是指令;
//一般模式:
RW=0,RS=1;写数据
//RW="0",RS=0;写指令
voidW_1byte(unsignedcharRW,unsignedcharRS,unsignedcharW_data)
{
unsignedintH_data,L_data,S_ID=0xf8;//11111RWRS0
if(RW==0)
{
S_ID&=~0x04;
}
else//if(RW==1)
{
S_ID|=0X04;
}
if(RS==0)
{
S_ID&=~0x02;
}
else//if(RS==1)
{
S_ID|=0X02;
}
H_data=W_data;
H_data&=0xf0;//屏蔽低4位的数据
L_data=W_data;//xxxx0000格式
L_data&=0x0f;//屏蔽高4位的数据
L_data<<=4;//xxxx0000格式
CS=1;
Write_8bits(S_ID);//发送S_ID
Write_8bits(H_data);//发送H_data
Write_8bits(L_data);//发送L_data
CS=0;
}
//向液晶屏写入字符串
voidLCDString(unsignedchar*pStr)
{
for(;*pStr!
='\0';pStr++)
W_1byte(0,1,*pStr);
}
//LCD初始化
voidLCD_init(void)
{
unsignedcharcmd;
cmd=0x30;//功能设置8位数据,基本指令
W_1byte(0,0,cmd);delay
(2);cmd=0x0C;//显示状态ON,游标OFF,反白OFF
W_1byte(0,0,cmd);//写指令
delay
(2);
cmd=0x01;//清除显示
W_1byte(0,0,cmd);//写指令
delay
(2);
cmd=0x02;//地址归位
W_1byte(0,0,cmd);//写指令
delay
(2);cmd=0x80;//设置DDRAM地址
W_1byte(0,0,cmd);//写指令
delay
(2);//延时
}
//LCD初始化
voidinit_LCD()
{
//SP=0X60;//*指针地址
CS=0;
SCLK=0;
SID=0;
PSB=0;
LCD_init();
}
//将一、二行字符串写入LCD
voidLCD_mess_display()
{
unsignedchari;
W_1byte(0,0,0x80);
_nop_();
for(i=0;lcd_data80[i]!
='\0';i++)
{
W_1byte(0,1,lcd_data80[i]);
}
W_1byte(0,0,0x90);
for(i=0;lcd_data88[i]!
='\0';i++)
{
W_1byte(0,1,lcd_data88[i]);
}
}
//LCD显示
voidDisplayLcd()
{
LCD_mess_display();
delay(100);
}
//LCD显示温度
voidShowTemperature()
{
Read_Temperature();
Display_Temperature();
}
//温度警报
voidAlarm(void)
{
//uchari;
ucharAlarmBuf[20];
//LED_GREEN=1;
//LED_RED=0;
sprintf(AlarmBuf,"智能调速:
%2.0f%%",radio);
W_1byte(0,0,0x98);
LCDString(AlarmBuf);
Beeper=0;
}
//********************T0定时,T1计数*******************************************
voidTime_Init()
{
TMOD=0x51;//工作方式2
EA=1;//使能
ET0=1;//开发中断,可到中断程序执行
//ET1=1;
TL0=timeH;TH0=timeL;//时间=(2^16-TH*2^8-TL)*1us
TR0=1;//开TO定时
flag0=1;
//TH1=0xff;TL1=0xff;//1ms中断
//TR1=1;
}
//主函数
main()
{
unsignedinti;
//LED_GREEN=0;
Time_Init();//定时器计数器初始化
init_LCD();
//****************输出作品信息******************************
/*sprintf(biaoti1,"厦门大学自动化系");
W_1byte(0,0,0x80);
LCDString(biaoti1);
sprintf(biaoti2,"陈福feng");
W_1byte(0,0,0x90);
LCDString(biaoti2);
sprintf(biaoti3,"23220131153339");
W_1byte(0,0,0x88);
LCDString(biaoti3);
sprintf(biaoti4,"2013-12-30");
W_1byte(0,0,0x98);
LCDString(biaoti4);
delay(0xef);
delay(0xef);
*/
//***************************************************************
DisplayLcd();//显示前两行
while
(1)
{
if(flag1==0)//没有警报
{
switch(~P0)
{
case0x01:
{timeH=0xe0;timeL=0xe0;radio=12.5;break;}
case0x03:
{timeH=0xc0;timeL=0xc0;radio=25.0;break;}
case0x07:
{timeH=0xa0;timeL=0xa0;radio=37.5;break;}
case0x0f:
{timeH=0x80;timeL=0x80;radio=50.0;break;}
case0x1f:
{timeH=0x60;timeL=0x60;radio=62.5;break;}
case0x3f:
{timeH=0x40;timeL=0x40;radio=75.0;break;}
case0x7f:
{timeH=0x20;timeL=0x20;radio=87.5;break;}
case0xff:
{timeH=0x00;timeL=0x00;radio=100;break;}
default:
{timeH=0xff;timeL=0xff;radio=00;break;}
}
P2=P0;//P2指示灯,表示档数
}
else
{
i=T-TEMPERATURE_ALARM;//智能降速
switch(i)
{
case1:
{timeH=0x20;timeL=0x20;radio=87.5;break;}
case2:
{timeH=0x60;timeL=0x60;radio=62.5;break;}
case3:
{timeH=0xa0;timeL=0xa0;radio=37.5;break;}
case4:
{timeH=0xe0;timeL=0xe0;radio=12.5;break;}
default:
{timeH=0xff;timeL=0xff;radio=0.0;break;}
}
P2=0x00;
delay(0xff);//指示灯闪烁
delay(0xff);
delay(0xff);
delay(0xff);
P2=0xff;
delay(0xff);
delay(0xff);
delay(0xff);
delay(0xff);
}
if(flag0==1)//置高
Dianji=1;//PWM输出
if(flag0==0)//置低
Dianji=0;
ShowTemperature();
delay(200);
}
}
voidtimer0(void)interrupt1using1
{
if(flag0==0)
{
TR0=0;
TL0=timeL;//高电平时间
TH0=timeH;
flag0=1;
TR0=1;
}
else
{
TR0=0;
TL0=~timeL;//低电平时间
TH0=~timeH;
flag0=0;
TR0=1;
}
}