1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 基于51单片机的温度控制系统数码管显示蜂鸣器报警proteus仿真原理图PCB

基于51单片机的温度控制系统数码管显示蜂鸣器报警proteus仿真原理图PCB

时间:2022-02-15 23:41:07

相关推荐

基于51单片机的温度控制系统数码管显示蜂鸣器报警proteus仿真原理图PCB

功能:

0.本系统采用STC89C52作为单片机

1.系统实时监测并显示当前温度,并通过四位数码管显示

2.超过设定阈值,蜂鸣器将报警,同时控制相应继电器实现降温或者加热

3.系统具备三个功能按键,可更改温度上限和下限

4.采用DC002作为电源接口可直接输入5V给整个系统供电

原理图:

PCB :

主程序:

#include <reg52.h>// 包含头文件#include <intrins.h>#define uchar unsigned char// 以后unsigned char就可以用uchar代替#define uint unsigned int// 以后unsigned int 就可以用uint 代替sbit DQ = P1^1;// DS18B20传感器的引脚定义sbit w1 = P2^4; // 数码管第1位的控制引脚sbit w2 = P2^5;// 数码管第2位的控制引脚sbit w3 = P2^6;// 数码管第3位的控制引脚sbit w4 = P2^7; // 数码管第4位的控制引脚sbit Buzzer = P1^0;// 蜂鸣器引脚sbit JdqLow = P2^0;// 温度过低继电器控制(加热)sbit JdqHig = P2^1;// 温度过高继电器控制(降温)sbit LedLow = P2^2;// 温度低指示灯sbit LedHig = P2^3;// 温度高指示灯sbit KeySet = P3^2;// 设置按键sbit KeyDown = P3^3;// 减按键sbit KeyUp = P3^4;// 加按键/* 数码管的显示值: 0 1 2 3 4 56 7 8 9 - */uchar code Array1[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40 };/* 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. */uchar code Array2[]={0xBf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef };uchar Buff[4];// 显示缓冲区uchar ShowID=1;// 当前显示的是哪一个数码管int AlarmLow=150;// 默认报警的温度下限值是15度int AlarmHig=300;// 默认报警的温度上限值是30度/*********************************************************/// 毫秒级的延时函数,time是要延时的毫秒数/*********************************************************/void DelayMs(uint time){uint i,j;for(i=0;i<time;i++)for(j=0;j<112;j++);}/*********************************************************/// 延时15微秒/*********************************************************/void Delay15us(void){_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}/*********************************************************/// 复位DS18B20(初始化)/*********************************************************/void DS18B20_ReSet(void){uchar i;DQ=0;i=240;while(--i);DQ=1;i=30;while(--i);while(~DQ);i=4;while(--i);}/*********************************************************/// 向DS18B20写入一个字节/*********************************************************/void DS18B20_WriteByte(uchar dat){uchar j;uchar btmp;for(j=0;j<8;j++){btmp=0x01;btmp=btmp<<j;btmp=btmp&dat;if(btmp>0)// 写1{DQ=0;Delay15us();DQ=1;Delay15us();Delay15us();Delay15us();Delay15us();}else// 写0{DQ=0;Delay15us();Delay15us();Delay15us();Delay15us();DQ=1;Delay15us();}}}/*********************************************************/// 读取温度值/*********************************************************/int DS18B20_ReadTemp(void){uchar j;int b,temp=0;DS18B20_ReSet();// 产生复位脉DS18B20_WriteByte(0xcc);// 忽略ROM指令DS18B20_WriteByte(0x44);// 启动温度转换指令DS18B20_ReSet();// 产生复位脉DS18B20_WriteByte(0xcc);// 忽略ROM指令DS18B20_WriteByte(0xbe);// 读取温度指令for(j=0;j<16;j++)// 读取温度数量{DQ=0;_nop_();_nop_();DQ=1;Delay15us();b=DQ;Delay15us();Delay15us();Delay15us();b=b<<j;temp=temp|b;}temp=temp*0.0625*10;// 合成温度值并放大10倍return (temp);// 返回检测到的温度值}/*********************************************************/// 定时器初始化/*********************************************************/void TimerInit(){TMOD = 0x01;// 使用定时器0,工作方式1 TH0 = 248;// 给定时器0的TH0装初值TL0 = 48;// 给定时器0的TL0装初值ET0 = 1;// 定时器0中断使能EA = 1;// 打开总中断TR0 = 1;// 启动定时器0}/*********************************************************/// 显示温度值/*********************************************************/void ShowTemp(int dat){if(dat<0)// 负号{Buff[0]=Array1[10];dat=0-dat;}else// 百位{Buff[0]=Array1[dat/1000];}Buff[1]=Array1[dat%1000/100];// 十位Buff[2]=Array2[dat%100/10];// 个位Buff[3]=Array1[dat%10];// 小数后一位}/*********************************************************/// 报警判断/*********************************************************/void AlarmJudge(int dat){if(dat<AlarmLow)// 判断温度是否过低{LedLow=0;// 温度低指示灯亮LedHig=1;// 温度高指示灯灭JdqLow=0;// 温度过低的继电器闭合(开始加热)JdqHig=1;// 温度过高的继电器断开(停止降温)Buzzer=0;// 蜂鸣器报警}else if(dat>AlarmHig)// 判断温度是否过高{LedLow=1;// 温度低指示灯灭LedHig=0;// 温度高指示灯亮JdqLow=1;// 温度过低的继电器断开(停止加热)JdqHig=0;// 温度过高的继电器闭合(开始降温)Buzzer=0;// 蜂鸣器报警}else// 温度正常{LedLow=1;// 温度低指示灯灭LedHig=1;// 温度高指示灯灭JdqLow=1;// 温度过低的继电器断开(停止加热)JdqHig=1;// 温度过高的继电器断开(停止降温)Buzzer=1;// 蜂鸣器停止报警}}/*********************************************************/// 按键扫描/*********************************************************/void KeyScanf(){if(KeySet==0)// 如果设置按键被按下{/* 设置温度下限 */LedLow=0;// 点亮绿色灯(代表当前正在设置温度下限)LedHig=1;// 熄灭红色灯Buzzer=1;// 关闭蜂鸣器ShowTemp(AlarmLow);// 显示温度下限值DelayMs(10);// 延时去抖while(!KeySet);// 等待按键释放DelayMs(10);// 延时去抖while(1){if(KeyDown==0)// 如果“减”按键被按下{if(AlarmLow>-550)// 判断当前温度下限是否大于-55度{AlarmLow--;// 温度下限值减去0.1度ShowTemp(AlarmLow);// 刷新显示改变后的温度下限值DelayMs(200);// 延时}}if(KeyUp==0)// 如果“加”按键被按下{if(AlarmLow<1250)// 判断当前温度下限是否小于125度{AlarmLow++;// 温度下限值加上0.1度ShowTemp(AlarmLow);// 刷新显示改变后的温度下限值DelayMs(200);// 延时}}if(KeySet==0)// 如果“设置”按键被按下{break;// 退出温度下限值的设置,准备进入上限值的设置}}/* 设置温度上限 */LedLow=1;// 熄灭绿色灯LedHig=0;// 点亮红色灯(代表当前正在设置温度上限)ShowTemp(AlarmHig);// 显示温度上限值DelayMs(10);// 延时去抖while(!KeySet);// 等待按键释放DelayMs(10);// 延时去抖while(1){if(KeyDown==0)// 如果“减”按键被按下{if(AlarmHig>-550)// 判断当前温度上限是否大于-55度{AlarmHig--;// 温度上限值减去0.1度ShowTemp(AlarmHig);// 刷新显示改变后的温度上限值DelayMs(200);// 延时}}if(KeyUp==0)// 如果“加”按键被按下{if(AlarmHig<1250)// 判断当前温度上限是否小于125度{AlarmHig++;// 温度上限值加上0.1度ShowTemp(AlarmHig);// 刷新显示改变后的温度上限值DelayMs(200);}}if(KeySet==0)// 如果“设置”按键被按下{break;// 准备退出设置模式}}/* 退出设置模式 */LedLow=1;// 熄灭绿灯LedHig=1;// 熄灭红灯DelayMs(10);// 延时去抖while(!KeySet);// 等待按键释放DelayMs(10);// 延时去抖}}/*********************************************************/// 主函数/*********************************************************/void main(){int temp;uchar i;TimerInit();// 定时器0的初始化(数码管的动态扫描)Buff[0]=Array1[0];// 刚上电显示4个0Buff[1]=Array1[0];Buff[2]=Array1[0];Buff[3]=Array1[0];for(i=0;i<8;i++)// 由于传感器刚上电读出的温度不稳定,因此先进行几次温度的读取并丢弃{DS18B20_ReadTemp();DelayMs(120);}while(1){EA=0;// 屏蔽中断temp=DS18B20_ReadTemp();// 读取温度值EA=1;// 恢复中断ShowTemp(temp);// 显示温度值AlarmJudge(temp);// 判断是否需要报警for(i=0;i<100;i++)// 延时并进行按键扫描{KeyScanf();DelayMs(5);}}}/*********************************************************/// 定时器0服务程序/*********************************************************/void Timer0(void) interrupt 1{TH0 = 248;// 给定时器0的TH0装初值TL0 = 48;// 给定时器0的TL0装初值P0=0x00;// 先关闭所有显示w1=1;w2=1;w3=1;w4=1;if(ShowID==1) // 判断是否显示第1位数码管{w1=0; // 打开第1位数码管的控制开关P0=Buff[0]; // 第1位数码管显示内容}if(ShowID==2) // 判断是否显示第2位数码管{w2=0; // 打开第2位数码管的控制开关P0=Buff[1]; // 第2位数码管显示内容}if(ShowID==3) // 判断是否显示第3位数码管{w3=0; // 打开第3位数码管的控制开关P0=Buff[2]; // 第3位数码管显示内容}if(ShowID==4) // 判断是否显示第4位数码管{w4=0; // 打开第4位数码管的控制开关P0=Buff[3]; // 第4位数码管显示内容}ShowID++; // 切换到下一个数码管的显示if(ShowID==5)ShowID=1;}

仿真演示视频:

/video/BV1MG4y1p74C/

实物演示视频:

/video/BV1Cd4y1i7Ja/

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。