標(biāo)題:
51單片機(jī)溫度控制報(bào)警和時(shí)間顯示程序+Proteus仿真
[打印本頁(yè)]
作者:
a1357787200
時(shí)間:
2019-4-9 19:03
標(biāo)題:
51單片機(jī)溫度控制報(bào)警和時(shí)間顯示程序+Proteus仿真
本系統(tǒng)由AT89C51單片機(jī)、DS18B20溫度檢測(cè)部分、DS1302日期時(shí)間記錄部分、數(shù)碼管顯示部分、按鍵輸入部分和蜂鳴器報(bào)警部分組成。該系統(tǒng)通過(guò)按鍵一來(lái)調(diào)整模式,共五個(gè)模式。模式一是DS18B20采集環(huán)境溫度并保存在存儲(chǔ)器中通過(guò)單片機(jī)將溫度顯示在數(shù)碼管上,當(dāng)溫度低于下限或高于上限時(shí)蜂鳴器報(bào)警;模式二是利用按鍵二和按鍵三調(diào)整報(bào)警的最高溫度加減;模式三是利用按鍵二和按鍵三調(diào)整報(bào)警的最低溫度加減;模式四是DS1302記錄的日期通過(guò)單片機(jī)顯示在數(shù)碼管上;模式五是DS1302記錄的時(shí)間通過(guò)單片機(jī)顯示在數(shù)碼管上。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
WIM2E$E6{`DF5)EBBJUR~2U.png
(96.44 KB, 下載次數(shù): 94)
下載附件
2019-4-9 19:01 上傳
單片機(jī)源程序如下:
#include <reg52.h>
#include"intrins.h"
#define uchar unsigned char
#define uint unsigned int
sbit dula = P2^0; //數(shù)碼管引腳定義
sbit wela = P2^1;
sbit DQ = P2^2; //
sbit key1 = P2^5;
sbit key2 = P2^6;
sbit key3 = P2^7;
sbit buzz = P2^3;
sbit led = P3^7;
sbit RST=P1^0;
sbit DSIO=P1^1;
sbit SCLK=P1^2; //定義ds1302使用的IO口
int bai,shi,ge;
uchar fuhao,flag;
uint ff,Hff=50,Lff=10;
uchar count=0,t100ms=0,t500ms,t1s,t2s;
uchar cishu=0;
uchar jiange=0;
uchar biaozhi1=0; //由低于下限到高于下限標(biāo)志
uchar biaozhi2=0; //有高于上限到低于上限標(biāo)志
uchar biaozhi3=0; //2s長(zhǎng)鳴標(biāo)志
uchar biaozhi4=0;
uchar TIMEBCD[7] = {0x00, 0x00, 0x12, 0x1, 0x01, 0x01, 0x18};
//存儲(chǔ)順序是秒分時(shí)日月周年,存儲(chǔ)格式是用BCD碼
uchar TIME[7] = {0}; //十進(jìn)制時(shí)間
//DS1302時(shí)鐘初始化2018年1月1日星期一12點(diǎn)00分00秒。
uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
//DS1302寫(xiě)入和讀取時(shí)分秒的地址命令(最低位控制讀寫(xiě))
unsigned char code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f, 0x6f};
unsigned char code table1[]={
0xbf,0x86,0xdb,0xcf,
0xe6,0xed,0xfd,0x87,
0xff, 0xef};
unsigned char code tablefu[]={
0x40, 0x76 , 0x38 , 0x39
}; //數(shù)碼管符號(hào) - H L C
/*延時(shí)函數(shù)*/
void delayms(uint xms)
{
uint i,j;
for(i=xms;i>0;i--)
for(j=114;j>0;j--);
}
/*****溫度延時(shí)*****/
void Delaywendu(int num)
{
while(num--) ;
}
/*****初始化DS18B20*****/
void Init_DS18B20()
{
DQ = 1; //DQ復(fù)位
Delaywendu(8); //稍做延時(shí)
DQ = 0; //單片機(jī)將DQ拉低
Delaywendu(80); //精確延時(shí),大于480us
DQ = 1; //拉高總線(xiàn)
Delaywendu(40);
}
/*****讀一個(gè)字節(jié)*****/
uchar ReadOneChar()
{
uchar i=0;
uchar dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 給脈沖信號(hào)
dat>>=1;
DQ = 1; // 給脈沖信號(hào)
if(DQ)
dat|=0x80;
Delaywendu(4);
}
return(dat);
}
/*****寫(xiě)一個(gè)字節(jié)*****/
void WriteOneChar(uchar dat)
{
uchar i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
Delaywendu(5);
DQ = 1;
dat>>=1;
}
}
/*****讀取溫度*****/
uint ReadTemperature()
{
uint a=0,b=0;
int temp=0;
float tt=0;
Init_DS18B20();
WriteOneChar(0xCC); //跳過(guò)讀序號(hào)列號(hào)的操作 1100 1100
WriteOneChar(0x44); //啟動(dòng)溫度轉(zhuǎn)換 0100 0100
Init_DS18B20();
WriteOneChar(0xCC); //跳過(guò)讀序號(hào)列號(hào)的操作
WriteOneChar(0xBE); //讀取溫度寄存器 1011 1110
a=ReadOneChar(); //讀低8位
b=ReadOneChar(); //讀高8位
temp=b;
temp<<=8;
temp=temp|a;
if(temp&0xf800)
{
temp=~temp+1;
fuhao=1;
}
else
fuhao=0;
tt=temp*0.0625;
temp=tt*10+0.5; //放大10倍輸出并四舍五入
return(temp);
}
/*****讀取溫度*****/
void check_wendu()
{
uint f;
f=ReadTemperature(); //獲取溫度值并減去DS18B20的溫漂誤差
ff=f;
bai=f/100;
shi=f %100/10;
ge= f%10;
}
/****讀設(shè)定值*****/
void check_v_set(int v_set)
{
int bb;
bb=v_set*10;
bai=bb/100;
shi=bb %100/10;
ge= bb %10;
}
/*****顯示溫度子程序*****/
void display()
{
P0=0xff;
wela=1;
P0=0xfb;
wela=0;
dula=1;
P0=table[bai];
dula=0;
delayms(5);
P0=0xff;
wela=1;
P0=0xf7;
wela=0;
dula=1;
P0=table1[shi];
dula=0;
delayms(5);
P0=0xff;
wela=1;
P0=0xef;
wela=0;
dula=1;
P0=table[ge];
dula=0;
delayms(5);
P0=0xff;
wela=1;
P0=0xdf;
wela=0;
dula=1;
P0=tablefu[3];
dula=0;
delayms(5);
}
void keyscan()
{
if(key1==0)
{
delayms(5);
if(key1==0)
{
flag++;
if(flag==5)
flag=0;
while(!key1);
}
}
}
int keyad(int num)
{
if(flag!=0)
{
if(key2==0)
{
delayms(5);
if(key2==0)
{
num++;
while(!key2);
}
}
if(key3==0)
{
delayms(5);
if(key3==0)
{
num--;
while(!key3);
}
}
}
return num;
}
/**************************************************************/
/**************************日歷計(jì)時(shí)部分************************/
void Ds1302Write(uchar addr, uchar dat) //向DS1302發(fā)送命令(地址+數(shù)據(jù))
{
uchar n;
RST = 0;
_nop_();
SCLK = 0;//先將SCLK置低電平。
_nop_();
RST = 1; //然后將RST(CE)置高電平。
_nop_();
for (n=0; n<8; n++)//開(kāi)始傳送八位地址命令
{
DSIO = addr & 0x01;//數(shù)據(jù)從低位開(kāi)始傳送
addr >>= 1;
SCLK = 1;//數(shù)據(jù)在上升沿時(shí),DS1302讀取數(shù)據(jù)
_nop_();
SCLK = 0;
_nop_();
}
for (n=0; n<8; n++)//寫(xiě)入8位數(shù)據(jù)
{
DSIO = dat & 0x01;
dat >>= 1;
SCLK = 1;//數(shù)據(jù)在上升沿時(shí),DS1302讀取數(shù)據(jù)
_nop_();
SCLK = 0;
_nop_();
}
RST = 0;//傳送數(shù)據(jù)結(jié)束
_nop_();
}
uchar Ds1302Read(uchar addr) //讀取一個(gè)地址的數(shù)據(jù)
{
uchar n,dat,dat1;
RST = 0;
_nop_();
SCLK = 0;//先將SCLK置低電平。
_nop_();
RST = 1;//然后將RST(CE)置高電平。
_nop_();
for(n=0; n<8; n++)//開(kāi)始傳送八位地址命令
{
DSIO = addr & 0x01;//數(shù)據(jù)從低位開(kāi)始傳送
addr >>= 1;
SCLK = 1;//數(shù)據(jù)在上升沿時(shí),DS1302讀取數(shù)據(jù)
_nop_();
SCLK = 0;//DS1302下降沿時(shí),放置數(shù)據(jù)
_nop_();
}
_nop_();
for(n=0; n<8; n++)//讀取8位數(shù)據(jù)
{
dat1 = DSIO;//從最低位開(kāi)始接收
dat = (dat>>1) | (dat1<<7);
SCLK = 1;
_nop_();
SCLK = 0;//DS1302下降沿時(shí),放置數(shù)據(jù)
_nop_();
}
RST = 0;
_nop_(); //以下為DS1302復(fù)位的穩(wěn)定時(shí)間
SCLK = 1;
_nop_();
DSIO = 0;
_nop_();
DSIO = 1;
_nop_();
return dat;
}
void Ds1302ReadTime() //讀取時(shí)鐘信息
{
uchar n;
for (n=0; n<7; n++)//讀取7個(gè)字節(jié)的時(shí)鐘信號(hào):分秒時(shí)日月周年
{
TIMEBCD[n] = Ds1302Read(READ_RTC_ADDR[n]);
TIME[n] = TIMEBCD[n]/16*10+TIMEBCD[n]%16;
}
}
void Ds1302Init() // 初始化DS1302
{
uchar n;
Ds1302ReadTime(); //首次讀取時(shí)間
if(TIME[5]==0) //判斷時(shí)間值是否有效
{
Ds1302Write(0x8E,0X00); //禁止寫(xiě)保護(hù),就是關(guān)閉寫(xiě)保護(hù)功能
for (n=0; n<7; n++)//寫(xiě)入7個(gè)字節(jié)的時(shí)鐘信號(hào):分秒時(shí)日月周年
{
Ds1302Write(WRITE_RTC_ADDR[n],TIMEBCD[n]);
}
Ds1302Write(0x8E,0x80); //打開(kāi)寫(xiě)保護(hù)功能
}
}
void displaytime()
{
P0=0xff;
wela=1;
P0=0xfe;
wela=0;
dula=1;
P0=table[TIME[2]/10];
dula=0;
delayms(5);
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
dula=1;
P0=table1[TIME[2]%10];
dula=0;
delayms(5);
P0=0xff;
wela=1;
P0=0xfb;
wela=0;
dula=1;
P0=table[TIME[1]/10];
dula=0;
delayms(5);
P0=0xff;
wela=1;
P0=0xf7;
wela=0;
dula=1;
P0=table1[TIME[1]%10];
dula=0;
delayms(5);
P0=0xff;
wela=1;
P0=0xef;
wela=0;
dula=1;
P0=table[TIME[0]/10];
dula=0;
delayms(5);
P0=0xff;
wela=1;
P0=0xdf;
wela=0;
dula=1;
P0=table1[TIME[0]%10];
dula=0;
delayms(5);
}
void displaydate()
{
P0=0xff;
wela=1;
P0=0xfe;
wela=0;
dula=1;
P0=table[TIME[6]/10];
dula=0;
delayms(5);
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
dula=1;
P0=table1[TIME[6]%10];
dula=0;
delayms(5);
P0=0xff;
wela=1;
P0=0xfb;
wela=0;
dula=1;
P0=table[TIME[4]/10];
dula=0;
delayms(5);
P0=0xff;
wela=1;
P0=0xf7;
wela=0;
dula=1;
P0=table1[TIME[4]%10];
dula=0;
delayms(5);
P0=0xff;
wela=1;
P0=0xef;
wela=0;
dula=1;
P0=table[TIME[3]/10];
dula=0;
delayms(5);
P0=0xff;
wela=1;
P0=0xdf;
wela=0;
dula=1;
P0=table1[TIME[3]%10];
dula=0;
delayms(5);
}
/*主函數(shù)*/
void main()
{
int z;
buzz=1; //低電平響,
led=0;
TMOD=0x01;//設(shè)置定時(shí)器0工作模式1
TH0=(65536-50000)/256;//定時(shí)器裝初值
TL0=(65536-50000)%256;
EA=1; //開(kāi)總中斷
ET0=1; //開(kāi)定時(shí)器0中斷
Ds1302Init( );
for(z=0;z<100;z++)
{
check_wendu();
}
TR0=1;
while(1)
{
keyscan();
if(flag==0)
{
check_wendu();
if(fuhao==1) //當(dāng)溫度值為負(fù)數(shù)
{
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
dula=1;
P0=tablefu[0];
dula=0;
delayms(5); //顯示負(fù)
}
else
{
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
dula=1;
P0=0x00;
dula=0;
delayms(5); //顯示正
}
display();
}
else if(flag==1)
{
Hff=keyad(Hff);
check_v_set(Hff);
P0=0xff;
wela=1;
P0=0xfe;
wela=0;
dula=1;
P0=tablefu[1];
dula=0;
delayms(5); //顯示H
display();
}
else if(flag==2)
{
Lff=keyad(Lff);
check_v_set(Lff);
P0=0xff;
wela=1;
P0=0xfe;
wela=0;
dula=1;
P0=tablefu[2];
dula=0;
delayms(5); //顯示L
display();
}
else if(flag==3)
{
Ds1302ReadTime();
delayms(10);
displaydate();
}
else if(flag==4)
{
Ds1302ReadTime();
delayms(10);
displaytime();
}
}
}
/*中斷函數(shù)*/
void timer0() interrupt 1//定時(shí)器0中斷服務(wù)程序
{
TH0=(65536-50000)/256;//再次裝定時(shí)器初值
TL0=(65536-50000)%256;
count++; //中斷次數(shù)累加 //50毫秒
// ff=ReadTemperature();
if(count%2==0)
{
t100ms = 1;
}
if(count%10==0)
{
t500ms = 1;
}
if(count%20==0)
{
……………………
…………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
test1.zip
(156.81 KB, 下載次數(shù): 173)
2019-4-9 18:59 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
作者:
風(fēng)凌天下
時(shí)間:
2019-11-7 15:41
感謝
作者:
天夜ss
時(shí)間:
2019-11-26 09:04
感謝!
作者:
13332078528
時(shí)間:
2019-12-3 15:21
。。。。我怎么打不開(kāi) 仿真圖片???
作者:
Crush.
時(shí)間:
2019-12-4 12:33
為啥程序?qū)нM(jìn)去后 仿真數(shù)碼管會(huì)不亮 端口也是灰色 連著數(shù)碼管的兩個(gè) 端口也是灰色的
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1