標(biāo)題:
單片機(jī)數(shù)字溫度控制器Proteus仿真設(shè)計(jì)帶源碼
[打印本頁(yè)]
作者:
我不是我
時(shí)間:
2017-7-17 21:37
標(biāo)題:
單片機(jī)數(shù)字溫度控制器Proteus仿真設(shè)計(jì)帶源碼
用DS18B20進(jìn)行溫度轉(zhuǎn)換,用AT89C51單片機(jī)讀取溫度,并根據(jù)溫度值,控制1602顯示和直流電機(jī)轉(zhuǎn)動(dòng),采用占空比調(diào)速,帶有ISIS仿真文件,可直接使用。
proteus仿真原理圖如下:
0.png
(19.5 KB, 下載次數(shù): 117)
下載附件
2017-7-18 01:42 上傳
0.png
(56.08 KB, 下載次數(shù): 79)
下載附件
2017-7-18 01:42 上傳
單片機(jī)源程序如下:
/******************************/
/* 數(shù)字溫度控制器 */
/******************************/
#include <reg51.h>
//引腳定義
sbit RS=P2^0;//1602LCD RS
sbit RW=P2^1;//1602LCD RW
sbit E=P2^2;//1602LCD E
sbit Moto1=P2^3;//直流電機(jī)控制端
sbit Moto2=P2^4;//直流電機(jī)控制端
sbit DQ=P2^5;//DS18B20 DQ
#define uchar unsigned char
#define uint unsigned int //宏定義
#define LcdData P0 //1602的D0~D7
#define CWD Moto1=1;Moto2=0 //正轉(zhuǎn)
#define CCWD Moto1=0;Moto2=1 //反轉(zhuǎn)
#define Stop Moto1=1; Moto2=1 //停止
//全局變量定義
uchar HPulseNum;//高電平數(shù)(PWM波高電平持續(xù)長(zhǎng)度)
uchar LPulseNum;//低電平數(shù)(PWM波低電平持續(xù)長(zhǎng)度)
uint NumChange; //周期
bit TempFlag;//正負(fù)溫度標(biāo)志:溫度為正Temp_Flag=0,否則為1
uint Temp;//溫度值
//直流電機(jī)轉(zhuǎn)向狀態(tài) 0為CWD(順時(shí)針?lè)较颍?1為CCWD(逆時(shí)針?lè)较颍?br />
uchar MotoStatus; //電機(jī)狀態(tài)
bit PulseStatus;//PWM波狀態(tài),0高電平 1低電平
//函數(shù)申明(共11個(gè)函數(shù))
/*****************************************************/
void Delayms(uint xms);//ms級(jí)延時(shí)函數(shù)
void WriteLcd(uchar Dat,bit x);//寫1602LCD指令、數(shù)據(jù)函數(shù)
void InitLcd(void);//初始化1602LCD函數(shù)
void StatusLCD(void);//1602LCD顯示狀態(tài)函數(shù)
void InitT0(void);//初始化定時(shí)器T0函數(shù)
void Delayus(uchar xus);//us級(jí)延時(shí)函數(shù)
bit Init_DS18B20(void);//初始化DS18B20函數(shù)
uchar Read_DS18B20(void);//讀DS18B20函數(shù)
void Write_DS18B20(uchar Dat);//寫DS18B20函數(shù)
void GetTemp();//取溫度函數(shù)
void MotoControl();
/*****************************************************/
uchar FirstLine[16]={" C STOP"}; //用于1602LCD第一行顯示的數(shù)組
uchar SecondLine[16]={"TG! H/L: 0%"}; //用于1602LCD第二行顯示的數(shù)組
//ms級(jí)延時(shí)函數(shù)
void Delayms(uint xms)//1ms左右延時(shí)
{
uint i,j;
for(i=xms; i>0; i--)
for(j=110; j>0; j--);
}
//寫1602LCD指令、數(shù)據(jù)函數(shù)
void WriteLcd(uchar Dat,bit x)
{
E=0;
LcdData=Dat;
RS=x;//寫指令時(shí)x=0,寫數(shù)據(jù)時(shí)x=1
RW=0;
E=1;
Delayms(1);
E=0;
}
//初始化1602LCD函數(shù)
void InitLcd(void)
{
WriteLcd(0x38,0);//功能設(shè)定(38H)
WriteLcd(0x0C,0);//顯示開(kāi)、關(guān)設(shè)定(0CH)
WriteLcd(0x06,0);//輸入模式設(shè)定(06H)
WriteLcd(0x01,0);//清除顯示(01H)
}
//1602LCD顯示狀態(tài)函數(shù)
void StatusLCD(void)
{
if(TempFlag) FirstLine[0]='-';//如果溫度值為負(fù),顯示負(fù)符號(hào)
else FirstLine[0]=' ';//否則不顯示溫度符號(hào)
if(Temp<1000) FirstLine[1]=' ';//如果溫度值小于100,百位顯示空白(不顯示0)
else FirstLine[1]=Temp/1000+0x30;//取溫度百位并轉(zhuǎn)換成ASCII碼
if(Temp<100) FirstLine[2]=' ';//如果溫度值小于10,十位顯示空白(不顯示0)
else FirstLine[2]=Temp%1000/100+0x30;//取溫度十位并轉(zhuǎn)換成ASCII碼
FirstLine[3]=Temp%100/10+0x30;//取溫度個(gè)位并轉(zhuǎn)換成ASCII碼
FirstLine[4]='.';//顯示小數(shù)點(diǎn)
FirstLine[5]=Temp%10+0x30;//取溫度十分位并轉(zhuǎn)換成ASCII碼
FirstLine[6]=0xDF;//顯示℃中C前面的小圓
if(NumChange!=0)
{
if(MotoStatus==1)//順時(shí)針時(shí)顯示CWD
{
FirstLine[9]=' ';
FirstLine[10]='C';
FirstLine[11]='W';
FirstLine[12]='D';
}
if(MotoStatus==2)//逆時(shí)針時(shí)顯示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<250))//如果溫度為負(fù)或小于25度,溫度過(guò)低
SecondLine[1]='L';//改寫1602LCD第二行顯示內(nèi)容
if((!TempFlag)&(Temp>=250)&(Temp<=300))//如果溫度為正且在25℃~30℃之間,溫度正常
SecondLine[1]='G';//改寫1602LCD第二行顯示內(nèi)容
if((!TempFlag)&(Temp>300))//如果溫度為正且大于30度,溫度過(guò)高
SecondLine[1]='H';//改寫1602LCD第二行顯示內(nèi)容
//占空比小于100%時(shí),不顯示百位
if(NumChange<100)
SecondLine[8]=' ';
else
//取占空比百位并轉(zhuǎn)換成ASCII碼
SecondLine[8]=NumChange/100+0x30;
//占空比小于10%時(shí),不顯示十位
if(NumChange<10)
SecondLine[9]=' ';
else
//取占空比十位并轉(zhuǎn)換成ASCII碼
SecondLine[9]=NumChange%100/10+0x30;
//取占空比個(gè)位并轉(zhuǎn)換成ASCII碼
SecondLine[10]=NumChange%10+0x30;
}
//us級(jí)延時(shí)函數(shù)
void Delayus(uchar xus)//晶振為12MHz,延時(shí)時(shí)間為2i+5 us
{
while(--xus);
}
//初始化DS18B20函數(shù)
bit Init_DS18B20(void)
{
bit x;
DQ=1;
DQ=0;
Delayus(250);
DQ=1;
Delayus(27);
if(!DQ) x=0;
else x=1;
Delayus(250);
DQ=1;
return x;
}
//讀DS18B20函數(shù)
uchar Read_DS18B20(void)
{
uchar i=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);
}
return Dat;
}
//寫DS18B20函數(shù)
void Write_DS18B20(uchar Dat)
{
uchar i=0;
for(i=0;i<8;i++)//循環(huán)8次,寫入一個(gè)字節(jié)
{
DQ=1;//未發(fā)送前的狀態(tài)
Dat >>= 1;//將要傳送的最低位放入CY
DQ=0;//將總線拉低,產(chǎn)生寫時(shí)序
DQ=CY;//將要傳送的位狀態(tài)送到總線上
Delayus(30);//延時(shí)50us,即保持總線狀態(tài),待DS18B20采樣
DQ=1;//恢復(fù)期,總線置1
}
}
//取溫度函數(shù)
void GetTemp(void)//獲取溫度函數(shù)
{
uchar a=0,b=0;
TR0=0;
Init_DS18B20();
Write_DS18B20(0xcc);//跳過(guò)ROM
Write_DS18B20(0x44);//開(kāi)啟溫度轉(zhuǎn)換
Init_DS18B20();
Write_DS18B20(0xcc);//跳過(guò)ROM
Write_DS18B20(0xbe);//讀暫存器
a=Read_DS18B20();//讀取高速暫存字節(jié)0,溫度低8位
b=Read_DS18B20();//讀取高速暫存字節(jié)1,溫度高8位
Temp=b;
Temp<<=8;
Temp=Temp|a;//將高、低位溫度編碼合在一起
if(b>=8)//判斷溫度值是否為負(fù),如果溫度高字節(jié)大于等于8說(shuō)明溫度值為負(fù)
{
Temp=~Temp+1;//將補(bǔ)碼轉(zhuǎn)換成原碼
TempFlag=1;//溫度標(biāo)志為1,表示溫度為負(fù)
}
else
{
TempFlag=0;//溫度標(biāo)志為0,表示溫度為正
}
Temp=Temp*0.0625*10+0.5;//將溫度編碼轉(zhuǎn)換成溫度值 放大10倍 加0.5是為了四舍五入
TR0=1;
}
//初始化外部中斷INT0和定時(shí)器T0
void InitT0(void)
{
EA=1;
ET0=1;
TMOD=0x02;//T0工作于定時(shí)、方式2
TH0=256-250;//250us定時(shí)
TL0=256-250;
TR0=1;//啟動(dòng)定時(shí)器
}
//T0定時(shí)器中斷服務(wù)函數(shù)
void T0Serv() interrupt 1
{
if(!PulseStatus)//如果當(dāng)前處于PWM波高電平段 PulseStatus:PWM波狀態(tài),0高電平 1低電平
{
if(HPulseNum--!=0)//如果高電平段延時(shí)計(jì)數(shù)不為0
{
if(MotoStatus!=0)//如果MotoStatus!=0(為0是停止?fàn)顟B(tài))
{
if(MotoStatus==1)
{
CWD;//順時(shí)針驅(qū)動(dòng)直流電機(jī)
}
else//MotoStatus=1(逆時(shí)針)
{
CCWD;//逆時(shí)針驅(qū)動(dòng)直流電機(jī)
}
}
}
else//高電平段延時(shí)計(jì)數(shù)為0
{
PulseStatus=!PulseStatus;//取反PWM波電平狀態(tài)
LPulseNum=100-NumChange; //裝載低電平段延時(shí)計(jì)數(shù),為低電平段延時(shí)做準(zhǔn)備
}
}
else//當(dāng)前處于PWM波低電平段
{
//如果低電平段延時(shí)計(jì)數(shù)不為0
if(LPulseNum--!=0)
{
Stop;//停止驅(qū)動(dòng)直流電機(jī)
}
//低電平段延時(shí)計(jì)數(shù)為0
else
{
PulseStatus=!PulseStatus; //取反PWM波電平狀態(tài)
HPulseNum=NumChange; //裝載高電平段延時(shí)計(jì)數(shù),為高電平段延時(shí)做準(zhǔn)備
}
}
}
void MotoControl()
{
if((!TempFlag)&(Temp>300)) //正的溫度且大于30℃
{
MotoStatus=1;
NumChange=Temp-300;
if(NumChange>=100) NumChange=100;//控制上限
}
if((!TempFlag)&(Temp<=300)&(Temp>=250))
{
MotoStatus=0;
NumChange=0;
}
if((Temp<250)|(TempFlag))
{
……………………
…………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
任務(wù)5 數(shù)字溫度控制器.rar
(71.55 KB, 下載次數(shù): 66)
2017-7-17 21:34 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
作者:
LIuwEI.
時(shí)間:
2018-10-30 16:35
為什么仿真不對(duì) 有錯(cuò)誤?
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1