欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136
標題:
單片機數字溫度控制器Proteus仿真設計帶源碼
[打印本頁]
作者:
我不是我
時間:
2017-7-17 21:37
標題:
單片機數字溫度控制器Proteus仿真設計帶源碼
用DS18B20進行溫度轉換,用AT89C51單片機讀取溫度,并根據溫度值,控制1602顯示和直流電機轉動,采用占空比調速,帶有ISIS仿真文件,可直接使用。
proteus仿真原理圖如下:
0.png
(19.5 KB, 下載次數: 117)
下載附件
2017-7-18 01:42 上傳
0.png
(56.08 KB, 下載次數: 79)
下載附件
2017-7-18 01:42 上傳
單片機源程序如下:
/******************************/
/* 數字溫度控制器 */
/******************************/
#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;//直流電機控制端
sbit Moto2=P2^4;//直流電機控制端
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 //正轉
#define CCWD Moto1=0;Moto2=1 //反轉
#define Stop Moto1=1; Moto2=1 //停止
//全局變量定義
uchar HPulseNum;//高電平數(PWM波高電平持續長度)
uchar LPulseNum;//低電平數(PWM波低電平持續長度)
uint NumChange; //周期
bit TempFlag;//正負溫度標志:溫度為正Temp_Flag=0,否則為1
uint Temp;//溫度值
//直流電機轉向狀態 0為CWD(順時針方向) 1為CCWD(逆時針方向)
uchar MotoStatus; //電機狀態
bit PulseStatus;//PWM波狀態,0高電平 1低電平
//函數申明(共11個函數)
/*****************************************************/
void Delayms(uint xms);//ms級延時函數
void WriteLcd(uchar Dat,bit x);//寫1602LCD指令、數據函數
void InitLcd(void);//初始化1602LCD函數
void StatusLCD(void);//1602LCD顯示狀態函數
void InitT0(void);//初始化定時器T0函數
void Delayus(uchar xus);//us級延時函數
bit Init_DS18B20(void);//初始化DS18B20函數
uchar Read_DS18B20(void);//讀DS18B20函數
void Write_DS18B20(uchar Dat);//寫DS18B20函數
void GetTemp();//取溫度函數
void MotoControl();
/*****************************************************/
uchar FirstLine[16]={" C STOP"}; //用于1602LCD第一行顯示的數組
uchar SecondLine[16]={"TG! H/L: 0%"}; //用于1602LCD第二行顯示的數組
//ms級延時函數
void Delayms(uint xms)//1ms左右延時
{
uint i,j;
for(i=xms; i>0; i--)
for(j=110; j>0; j--);
}
//寫1602LCD指令、數據函數
void WriteLcd(uchar Dat,bit x)
{
E=0;
LcdData=Dat;
RS=x;//寫指令時x=0,寫數據時x=1
RW=0;
E=1;
Delayms(1);
E=0;
}
//初始化1602LCD函數
void InitLcd(void)
{
WriteLcd(0x38,0);//功能設定(38H)
WriteLcd(0x0C,0);//顯示開、關設定(0CH)
WriteLcd(0x06,0);//輸入模式設定(06H)
WriteLcd(0x01,0);//清除顯示(01H)
}
//1602LCD顯示狀態函數
void StatusLCD(void)
{
if(TempFlag) FirstLine[0]='-';//如果溫度值為負,顯示負符號
else FirstLine[0]=' ';//否則不顯示溫度符號
if(Temp<1000) FirstLine[1]=' ';//如果溫度值小于100,百位顯示空白(不顯示0)
else FirstLine[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<250))//如果溫度為負或小于25度,溫度過低
SecondLine[1]='L';//改寫1602LCD第二行顯示內容
if((!TempFlag)&(Temp>=250)&(Temp<=300))//如果溫度為正且在25℃~30℃之間,溫度正常
SecondLine[1]='G';//改寫1602LCD第二行顯示內容
if((!TempFlag)&(Temp>300))//如果溫度為正且大于30度,溫度過高
SecondLine[1]='H';//改寫1602LCD第二行顯示內容
//占空比小于100%時,不顯示百位
if(NumChange<100)
SecondLine[8]=' ';
else
//取占空比百位并轉換成ASCII碼
SecondLine[8]=NumChange/100+0x30;
//占空比小于10%時,不顯示十位
if(NumChange<10)
SecondLine[9]=' ';
else
//取占空比十位并轉換成ASCII碼
SecondLine[9]=NumChange%100/10+0x30;
//取占空比個位并轉換成ASCII碼
SecondLine[10]=NumChange%10+0x30;
}
//us級延時函數
void Delayus(uchar xus)//晶振為12MHz,延時時間為2i+5 us
{
while(--xus);
}
//初始化DS18B20函數
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函數
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函數
void Write_DS18B20(uchar Dat)
{
uchar i=0;
for(i=0;i<8;i++)//循環8次,寫入一個字節
{
DQ=1;//未發送前的狀態
Dat >>= 1;//將要傳送的最低位放入CY
DQ=0;//將總線拉低,產生寫時序
DQ=CY;//將要傳送的位狀態送到總線上
Delayus(30);//延時50us,即保持總線狀態,待DS18B20采樣
DQ=1;//恢復期,總線置1
}
}
//取溫度函數
void GetTemp(void)//獲取溫度函數
{
uchar a=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;
}
//初始化外部中斷INT0和定時器T0
void InitT0(void)
{
EA=1;
ET0=1;
TMOD=0x02;//T0工作于定時、方式2
TH0=256-250;//250us定時
TL0=256-250;
TR0=1;//啟動定時器
}
//T0定時器中斷服務函數
void T0Serv() interrupt 1
{
if(!PulseStatus)//如果當前處于PWM波高電平段 PulseStatus:PWM波狀態,0高電平 1低電平
{
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波低電平段
{
//如果低電平段延時計數不為0
if(LPulseNum--!=0)
{
Stop;//停止驅動直流電機
}
//低電平段延時計數為0
else
{
PulseStatus=!PulseStatus; //取反PWM波電平狀態
HPulseNum=NumChange; //裝載高電平段延時計數,為高電平段延時做準備
}
}
}
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))
{
……………………
…………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
任務5 數字溫度控制器.rar
(71.55 KB, 下載次數: 66)
2017-7-17 21:34 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
作者:
LIuwEI.
時間:
2018-10-30 16:35
為什么仿真不對 有錯誤?
歡迎光臨 (http://www.raoushi.com/bbs/)
Powered by Discuz! X3.1