数字温度控制器的设计.docx

上传人:b****7 文档编号:8983013 上传时间:2023-02-02 格式:DOCX 页数:16 大小:119.83KB
下载 相关 举报
数字温度控制器的设计.docx_第1页
第1页 / 共16页
数字温度控制器的设计.docx_第2页
第2页 / 共16页
数字温度控制器的设计.docx_第3页
第3页 / 共16页
数字温度控制器的设计.docx_第4页
第4页 / 共16页
数字温度控制器的设计.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

数字温度控制器的设计.docx

《数字温度控制器的设计.docx》由会员分享,可在线阅读,更多相关《数字温度控制器的设计.docx(16页珍藏版)》请在冰豆网上搜索。

数字温度控制器的设计.docx

数字温度控制器的设计

数字温度控制器的设计

王宁

1001应用电子

1、实验项目

数字温度控制器的设计

2、实验要求

用AT89C51单片机作为控制器,检测数字温度传感器DS18B20,并将检测到的温度信息和当前电机转动方向显示在1602LCD液晶显示模块上。

温度控制范围在20+学号尾数℃——35℃,占空比调整,每变化0.1℃时占空比调整学号尾数。

当温度在28℃-35℃之间时,第一行显示“XXX.X℃STOP”,第二行显示“TG!

H/L:

0%”,驱动直流电机的PWM波占空比为0,直流电机不转动;

当温度在高于35℃时,第一行显示“XXX.X℃CWD”,第二行显示“TH!

H/L:

XXX%”,直流电机顺时针转动,温度每上升0.1℃,驱动直流电机的PWM波占空比增加8%;

当温度在低于28℃时,第一行显示“XXX.X℃CCWD”,第二行显示“TL!

H/L:

XXX%”,直流电机逆时针转动,温度每下降0.1℃,驱动直流电机的PWM波占空比增加8%;

另:

显示增加班级、姓名、学号等信息

完成程序,生成hex文件,运行仿真

3、实验原理图

图1显示为:

第一行显示“温度STOP(电机工作状态)姓名首字母”

第二行显示“TG!

(温度状态)H/L:

0%(占空比)学号”

图1

图2温度传感器的连接方式,显示温度值;

图2

图3为电机接线图

图3

图4为电路原理总图

图4

4、程序设计

#include

//引脚定义

sbitRS=P2^0;//1602LCDRS

sbitRW=P2^1;//1602LCDRW

sbitE=P2^2;//1602LCDE

sbitMoto1=P2^3;//直流电机控制端

sbitMoto2=P2^4;//直流电机控制端

sbitDQ=P2^5;//DS18B20DQ

//宏定义

#defineucharunsignedchar

#defineuintunsignedint

#defineLcdDataP0

#defineCWDMoto1=1;Moto2=0

#defineCCWDMoto1=0;Moto2=1

#defineStopMoto1=1;Moto2=1

//全局变量定义

ucharHPulseNum;//高电平数(PWM波高电平持续长度)

ucharLPulseNum;//低电平数(PWM波低电平持续长度)

uintNumChange;

bitTempFlag;//正负温度标志:

温度为正Temp_Flag=0,否则为1

uintTemp;//温度值

ucharMotoStatus;//直流电机转向状态0CWD(顺时针方向)1CCWD(逆时针方向)

bitPulseStatus;//PWM波状态,0高电平1低电平

//函数申明

voidDelayms(uintxms);//ms级延时函数

voidWriteLcd(ucharDat,bitx);//写1602LCD指令、数据函数

voidInitLCD(void);//初始化1602LCD函数

voidStatusLCD(void);//1602LCD显示状态函数

voidInitT0(void);//初始化定时器T0函数

voidDelayus(ucharxus);//us级延时函数

bitInit_DS18B20(void);//初始化DS18B20函数

ucharRead_DS18B20(void);//读DS18B20函数

voidWrite_DS18B20(ucharDat);//写DS18B20函数

voidGetTemp();//取温度函数

voidMotoControl();

ucharFirstLine[16]={"CSTOPwn"};//用于1602LCD第一行显示的数组

ucharSecondLine[16]={"TG!

H/L:

0%28"};//用于1602LCD第二行显示的数组

voidDelayms(uintxms)//延时程序

{

uinti,j;

for(i=xms;i>0;i--)

for(j=110;j>0;j--);

}

voidWriteLcd(ucharDat,bitx)//写1602LCD指令、数据函数

{

E=0;

LcdData=Dat;

RS=x;//写指令时x=0,写数据时x=1

RW=0;

E=1;

Delayms

(1);

E=0;

}

voidInitLcd(void)//初始化1602LCD函数

{

WriteLcd(0x38,0);//功能设定(38H)

WriteLcd(0x0C,0);//显示开、关设定(0CH)

WriteLcd(0x06,0);//输入模式设定(06H)

WriteLcd(0x01,0);//清除显示(01H)

}

voidStatusLCD(void)//1602LCD显示状态函数

{

if(TempFlag)FirstLine[0]='-';//如果温度值为负,显示负符号

elseFirstLine[0]='';//否则不显示温度符号

if(Temp<1000)FirstLine[1]='';//如果温度值小于100,百位显示空白(不显示0)

elseFirstLine[1]=Temp/1000+0x30;//取温度百位并转换成ASCII码

if(Temp<100)FirstLine[2]='';//如果温度值小于10,十位显示空白(不显示0)

else

FirstLine[2]=Temp%1000/100+0x30;//取温度十位并转换成ASCII码

FirstLine[3]=Temp%100/10+0x30;//取温度个位并转换成ASCII码

FirstLine[4]='.';//显示小数点

FirstLine[5]=Temp%10+0x30;//取温度十分位并转换成ASCII码

FirstLine[6]=0xDF;//显示℃中C前面的小圆

if(NumChange!

=0)

{

if(MotoStatus==1)//顺时针时显示CWD

{

FirstLine[9]='';

FirstLine[10]='C';

FirstLine[11]='W';

FirstLine[12]='D';

}

if(MotoStatus==2)//逆时针时显示CCWD

{

FirstLine[9]='C';

FirstLine[10]='C';

FirstLine[11]='W';

FirstLine[12]='D';

}

}

else

{

FirstLine[9]='S';

FirstLine[10]='T';

FirstLine[11]='O';

FirstLine[12]='P';

}

if((TempFlag)|(Temp<280))//如果温度为负或小于25度,温度过低

SecondLine[1]='L';//改写1602LCD第二行显示内容

if((!

TempFlag)&(Temp>=280)&(Temp<=350))//如果温度为正且在25℃~30℃之间,温度正常

SecondLine[1]='G';//改写1602LCD第二行显示内容

if((!

TempFlag)&(Temp>350))//如果温度为正且大于30度,温度过高

SecondLine[1]='H';//改写1602LCD第二行显示内容

if(NumChange<100)//占空比小于100%时,不显示百位

SecondLine[8]='';

else

SecondLine[8]=NumChange/100+0x30;//取占空比百位并转换成ASCII码

if(NumChange<10)//占空比小于10%时,不显示十位

SecondLine[9]='';

else

SecondLine[9]=NumChange%100/10+0x30;//取占空比十位并转换成ASCII码

SecondLine[10]=NumChange%10+0x30;//取占空比个位并转换成ASCII码

}

voidDelayus(ucharxus)//晶振为12MHz,延时时间为2i+5us

{

while(--xus);

}

bitInit_DS18B20(void)//初始化DS18B20函数

{

bitx;

DQ=1;

DQ=0;

Delayus(250);

DQ=1;

Delayus(27);

if(!

DQ)x=0;

elsex=1;

Delayus(250);

DQ=1;

returnx;

}

ucharRead_DS18B20(void)//读DS18B20函数

{

uchari=0,Dat=0;

for(i=0;i<8;i++)

{

DQ=1;

DQ=0;

Dat>>=1;

DQ=1;

if(DQ)Dat|=0x80;

DQ=1;

Delayus(30);

}

returnDat;

}

voidWrite_DS18B20(ucharDat)//写DS18B20函数

{

uchari=0;

for(i=0;i<8;i++)//循环8次,写入一个字节

{

DQ=1;//未发送前的状态

Dat>>=1;//将要传送的最低位放入CY

DQ=0;//将总线拉低,产生写时序

DQ=CY;//将要传送的位状态送到总线上

Delayus(30);//延时50us,即保持总线状态,待DS18B20采样

DQ=1;//恢复期,总线置1

}

}

voidGetTemp(void)//获取温度函数

{

uchara=0,b=0;

TR0=0;

Init_DS18B20();

Write_DS18B20(0xcc);//跳过ROM

Write_DS18B20(0x44);//开启温度转换

Init_DS18B20();

Write_DS18B20(0xcc);//跳过ROM

Write_DS18B20(0xbe);//读暂存器

a=Read_DS18B20();//读取高速暂存字节0,温度低8位

b=Read_DS18B20();//读取高速暂存字节1,温度高8位

Temp=b;

Temp<<=8;

Temp=Temp|a;//将高、低位温度编码合在一起

if(b>=8)//判断温度值是否为负,如果温度高字节大于等于8说明温度值为负

{

Temp=~Temp+1;//将补码转换成原码

TempFlag=1;//温度标志为1,表示温度为负

}

else

{

TempFlag=0;//温度标志为0,表示温度为正

}

Temp=Temp*0.0625*10+0.5;//将温度编码转换成温度值放大10倍加0.5是为了四舍五入

TR0=1;

}

voidInitT0(void)//初始化外部中断INT0和定时器T0

{

EA=1;

ET0=1;

TMOD=0x02;//T0工作于定时、方式2

TH0=6;//250us定时

TL0=6;

TR0=1;//启动定时器

}

voidT0Serv()interrupt1//T0定时器中断服务函数

{

if(!

PulseStatus)//如果当前处于PWM波高电平段

{

if(HPulseNum--!

=0)//如果高电平段延时计数不为0

{

if(MotoStatus!

=0)//如果MotoStatus!

=0(为0是停止状态)

{

if(MotoStatus==1)

{

CWD;//顺时针驱动直流电机

}

else//MotoStatus=1

{

CCWD;//逆时针驱动直流电机

}

}

}

Else//高电平段延时计数为0

{

PulseStatus=!

PulseStatus;//取反PWM波电平状态

LPulseNum=100-NumChange;

}

}

Else//当前处于PWM波低电平段

{

if(LPulseNum--!

=0)

{

Stop;//停止驱动直流电机

}

else

{

PulseStatus=!

PulseStatus;//取反PWM波电平状态

HPulseNum=NumChange;

}

}

}

voidMotoControl()

{

if((!

TempFlag)&(Temp>350))

{

MotoStatus=1;

NumChange=(Temp-350)*8;

if(NumChange>=100)NumChange=100;//控制上限

}

if((!

TempFlag)&(Temp<=350)&(Temp>=280))

{

MotoStatus=0;

NumChange=0;

}

if((Temp<280)|(TempFlag))

{

MotoStatus=2;

NumChange=(280-Temp)*8;

if((NumChange>=100)|(TempFlag))NumChange=100;//控制上限

}

}

voidmain()

{

uchary;

InitLcd();//初始化1602LCD

HPulseNum=NumChange;//装载PWM波高电平段延时计数,为高电平段延时做准备

InitT0();//初始化外部中断INT0和定时器T0

while

(1)

{

GetTemp();

Delayms(500);//延时0.5s,降低温度读取频率

MotoControl();//根据当前工作状态改变1602LCD显示状态

StatusLCD();//指定送入的字符显示于1602LCD第一行第一个字符位置

WriteLcd(0x80,0);

for(y=0;y<16;y++)//循环送入

WriteLcd(FirstLine[y],1);//向1602LCD送第一行显示内容数组

WriteLcd(0xc0,0);

for(y=0;y<16;y++)//循环送入

WriteLcd(SecondLine[y],1);//向1602LCD送第二行显示内容数组

}

}

5、实验过程

利用keil软件编写程序,利用仿真软件绘制原理图,将生成的.hex文件装入原理图进行仿真运行

6、实验小结

注意占空比的调整,如何利用程序合理调整及分配电机运行的速度,2*16的LCD的显示及如何合理写入字符串与字符。

温度传感器的初始化和写、读的程序编写。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1