设计中有很多不完善的地方,欢迎各位大佬指正。 演示视频:https://www.bilibili.com/video/BV1CS4y1u7s6?share_source=copy_web
利用单片机、DS18B20温度传感器、数码管、按键、蜂鸣器设计。编程时考虑数码需要一直扫描,按键也需要一直扫描,DS18B20实时读取温度也需要实时扫描,这三个都放到主函数的while循环中,由于温度读取转换时间比较长,数码管就会一直闪烁。另外数码管和按键都再主函数中扫描,按键按下时数码管会熄灭。 最后,在一个定时器中断中扫描数码管,另一个定时器中断读取温,主函数主要扫描按键和判断温度值是否超过上下限。 经过不断调试终于实现了所有的功能。 功能说明: 1.数码管默认显示当前温度。默认上限30℃,下限22℃ 2.当温度高于上限,蜂鸣器报警,红色LED点亮;低于下限,蜂 鸣器报警,蓝色LED点亮。 3.第一次点击'设置'按键,数码管第一位显示H,此时点击'加' '减'按键,调节温度上限值。 第二次点击'设置'按键,数码管第一位显示L,此时点击'加' '减'按键,调节温度下限值。 注意:在调节温度上下限过程中,温度报警关闭。 第三次点击'设置'按键,退出设置状态,打开温度报警。 4.温度传感器测温范围:-55—128℃。 温度上下限调节范围:-55—128℃。
主函数 单片机代码如下: - /******************************************************************************
- * 单片机温度报警系统
- *******************************************************************************/
- #include <reg52.h>
- #include "delay.h"
- #include "key.h"
- #include "DS18B20.h"
- #define uchar unsigned char //对数据类型定义
- #define uint unsigned int
- /****************************端口定义******************************************/
- sbit D1=P2^4;
- sbit D2=P2^6;
- sbit D3=P2^5;
- sbit D4=P2^7;
-
- sbit Beep=P1^6; //蜂鸣器
- sbit LED_G=P1^2; //绿色LED端口
- sbit LED_B=P1^0; //蓝色LED端口
- sbit LED_R=P1^1; //红色LED端口
- /****************************定义变量******************************************/
- uchar KeyValve=0; //按键值
- float Temp=20.0; //温度变量
- float TH=30.0; //温度上限
- float TL=22.0; //温度下限
- uint Time_Count=1; //定时器0中断次数
- uchar Temp_Str[4]; //数组变量存放温度数据
- uchar Set_Mode=0; //设置模式
- uchar SMG_Data[4]={0,0,0,0}; //存放数码管的各个位的值
- uchar code smgduan[]={ //共阳极数码管段码
- 0xc0, //0,0
- 0xf9, //1,1
- 0xa4, //2,2
- 0xb0, //3,3
- 0x99, //4,4
- 0x92, //5,5
- 0x82, //6,6
- 0xf8, //7,7
- 0x80, //8,8
- 0x90, //9,9
- 0x88, //10,A
- 0x83, //11,b
- 0xc6, //12,C
- 0xa1, //13,d
- 0x86, //14,E
- 0x8e, //15,F
- 0xff, //16,
- 0xbf, //17,
- 0x89, //18,H
- 0xc7 //19,L
- };
- /*****************************************************************************/
- /***************************函数声明******************************************/
- void Timer_Init(); //定时器初始化
- void Temp_T(float t); //温度转换函数
- /******************************************************************************
- * 函 数 名 : 主函数
- * 函数功能 :
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void main()
- {
- DS18B20_Init(); //温度传感器初始化
- Timer_Init(); //定时器初始化
- Delay_Ms(100);
- while(1)
- {
- /***********按键扫描程序**************/
- KeyValve=Key_Check(); //扫描按键
- if(KeyValve!=0) //判断按键是否按下
- {
- switch(KeyValve) //判断按键值,并处理
- {
- case 1: //温度上限/下限设置
- {
- if(Set_Mode<2)
- Set_Mode++;
- else
- Set_Mode=0;
- Delay_Ms(200);
- }
- break;
- case 2: //按键加
- {
- if((Set_Mode==1)&&(TH<128.0)) //限制温度上限小于128℃
- TH=TH+1.0; //温度上限加一
- if((Set_Mode==2)&&(TL<TH)) //限制温度下限小于温度上限
- TL=TL+1.0; //温度下限加一
- Delay_Ms(200);
- }
- break;
- case 3: //按键减
- {
- if((Set_Mode==1)&&(TH>TL)) //限制温度上限大于温度下限
- TH=TH-1.0; //温度上限减一
- if((Set_Mode==2)&&(TL>-55.0)) //限制温度下限大于-55℃
- TL=TL-1.0; //温度下限减一
- Delay_Ms(200);
- }
- break;
- }
- }
- /***********温度上下限判断报警程序**************/
- if(Set_Mode==0)
- {
- if(Temp>TH)
- {
- LED_R=0; //红灯点亮
- LED_B=1; //蓝灯熄灭
- LED_G=1;
- Beep=0; //蜂鸣器报警
- }
- else if(Temp<TL)
- {
- LED_R=1; //红灯熄灭
- LED_B=0; //蓝灯点亮
- LED_G=1;
- Beep=0; //蜂鸣器报警
- }
- else
- {
- LED_R=1; //红灯熄灭
- LED_B=1; //蓝灯熄灭
- LED_G=0;
- Beep=1;
- }
- }
- else
- Beep=1;
- }
- }
- /*******************************************************************************
- * 函 数 名 : Temp_T(float t)
- * 函数功能 : 温度转换函数:将温度值放到数组中,便于显示
- * 输 入 : t
- * 输 出 : 无
- *******************************************************************************/
- void Temp_T(float t)
- {
- if(Set_Mode==0)
- {
- t=t*10.0; //放大十倍
- if(t>=0) //正温度
- {
- if(((int)t/1000)==0)
- SMG_Data[0]=16;
- else
- SMG_Data[0]=(int)t/1000; //提取温度百、十、个位
- SMG_Data[1]=((int)t%1000)/100;
- SMG_Data[2]=((int)t%100)/10;
- SMG_Data[3]=(int)t%10;
- }
- else //负温度
- {
- t=-t; //将负数转换为正数
- SMG_Data[0]=17; //显示“—”号
- SMG_Data[1]=(int)t/100; //提取温度个、十位
- SMG_Data[2]=((int)t%100)/10;
- SMG_Data[3]=(int)t%10;
- }
- }
- else
- {
- if(Set_Mode==1)
- SMG_Data[0]=18; //数码管第一位显示H
- if(Set_Mode==2)
- SMG_Data[0]=19; //数码管第一位显示L
- if(t>=0) //正温度
- {
- SMG_Data[1]=(int)t/100; //提取温度百、十、个位
- SMG_Data[2]=((int)t%100)/10;
- SMG_Data[3]=(int)t%10;
- }
- else //负温度
- {
- t=-t; //将负数转换为正数
- SMG_Data[1]=17; //显示“—”号
- SMG_Data[2]=((int)t%100)/10; //提取温度个、十位
- SMG_Data[3]=(int)t%10;
- t=-t; //将温度恢复
- }
- }
- }
- /*****************************************************************************
- * 函 数 名 : Timer_Init
- * 函数功能 : 定时器初始化
- * 输 入 : 无
- * 输 出 : 无
- *****************************************************************************/
- void Timer_Init()
- {
- TMOD=0x11; //打开定时器0,工作方式1。
- TH0=0xff; //给定时器0赋初值,定时200us (65536-200)/256 (65536-200)%256
- TL0=0x38;
- TH1=0xc5; //定时60ms
- TL1=0x68;
- ET0=1; //打开定时器0中断允许
- ET1=1; //打开定时器1中断允许
- TR0=1; //打开定时器0
- TR1=1; //打开定时器1
- PT1=1; //高优先级
- EA=1; //打开总中断
- }
- /*******************************************************************************
- * 函 数 名 : void Timer0() interrupt 1
- * 函数功能 : 定时器0中断函数
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void Timer0() interrupt 1
- {
- TH0=0xff; //给定时器赋初值,定时
- TL0=0x38;
- if(Time_Count%2==0)
- {
- switch(Time_Count%8) //位选,选择点亮的数码管,
- {
- case(0):
- D1=0;
- D2=1;
- D3=1;
- D4=1;
- break;//显示第0位
- case(2):
- D1=1;
- D2=0;
- D3=1;
- D4=1;
- break;//显示第1位
- case(4):
- D1=1;
- D2=1;
- D3=0;
- D4=1;
- break;//显示第2位
- case(6):
- D1=1;
- D2=1;
- D3=1;
- D4=0;
- break;//显示第3位
- }
- if((Set_Mode==0)&&(Time_Count%8==4))
- P0=smgduan[SMG_Data[(Time_Count%8)/2]]-0x80;//显示小数点
- P0=smgduan[SMG_Data[(Time_Count%8)/2]];//发送段码
- }
- if(Time_Count%2==1)
- {
- P0=0xff;//消隐
- }
- Time_Count++;
- }
- /*******************************************************************************
- * 函 数 名 : void Timer1() interrupt 3
- * 函数功能 : 定时器1中断函数
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void Timer1() interrupt 3
- {
- TH1=0xBB; //定时15ms
- TL1=0xa4;
- if(Set_Mode==0) //模式0:显示当前为温度
- {
- Temp=DS18B20_ReadTemp(); //读取温度值
- Temp_T(Temp); //温度转换
- }
- if(Set_Mode==1) //模式1:显示温度上限
- Temp_T(TH);
- if(Set_Mode==2) //模式2:显示温度下限
- Temp_T(TL);
- Time_Count=0;
- }
复制代码 DS18B20.c
KEY.C
- /******************************************************************************
- *文件描述:按键驱动文件
- *******************************************************************************/
- #include<reg52.h>
- #include "key.h"
- #include "delay.h"
- /*******************************************************************************
- * 函 数 名 : Key_Check()
- * 函数功能 : 检测有独立按键按下并读取键值
- * 输 入 : 无
- * 输 出 : KeyValue:按键值,无按键按下返回0
- *******************************************************************************/
- uchar Key_Check(void)
- {
- uchar KeyValue=0; //按键值初始化为0
- if((GPIO_KEY&0x0f)!=0x0f) //读取高4位,判断按键是否按下
- {
- Delay_Ms(10); //延时10ms进行消抖
- if((GPIO_KEY&0x0f)!=0x0f) //再次检测键盘是否按下
- {
- switch(GPIO_KEY&0x0f)
- {
- case(0x0e): KeyValue=1; break;
- case(0x0d): KeyValue=2; break;
- case(0x0b): KeyValue=3; break;
- case(0x07): KeyValue=4; break;
- }
- }
- }
- return KeyValue;
- }
复制代码 主要代码都在上面,拒绝白嫖,就不上传附件了,欢迎各位大佬留言。
|