测温打铃附代码和电路图
前言
一、测温打铃是什么?
测温打铃是在单片机的基础上实现的一种温度报警装置。它可以通过自己设定报警温度,当温度传感器的温度达到报警温度发出报警声。(本项目添加生日快乐的报警音乐)有想法的可以自己动手实践,做一个真正的单片机实体项目。
二、具体实现
1.电路图
电路图首先要了解需要哪些元件,我在本项目中添加了微调电容、外部晶振、温度传感器、LCD显示屏、排阻、三极管、蜂鸣器、AT89C52。下面是具体电路图。
2.代码
代码注释很清晰,具体代码如下:
#include <reg52.h> //头文件 #include <intrins.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #define uchar unsigned char #define uint unsigned int sbit DQ=P3^0; //数据传输线接单片机的相应的引脚 sbit beepIO=P3^1; //接PNP型三极管 sbit RS = P3^2;//液晶接口,rs0命令,1数据;外部中断0 sbit RW = P3^3;//外部中断1 sbit E = P3^4;//液晶使能端E,控制信号输入端,下降沿使能 sbit k3 = P3^5;//k3开关,播放音量 sbit k2 = P3^6;//k2开关,温度上限减 sbit k1 = P3^7;//k1开关,温度上限加 float Temp;//温度 uint Temp_H = 60;//温度上限 unsigned char tempL=0; //设全局变量//用于温度进制转化 unsigned char tempH=0; uchar bz1;//k3按下 uchar m,n; uchar code T[49][2]={{0,0},//各个音调的初始值 {0xF8,0x8B},{0xF8,0xF2},{0xF9,0x5B},{0xF9,0xB7},{0xFA,0x14},{0xFA,0x66},{0xFA,0xB9},{0xFB,0x03},{0xFB,0x4A},{0xFB,0x8F},{0xFB,0xCF},{0xFC,0x0B}, {0xFC,0x43},{0xFC,0x78},{0xFC,0xAB},{0xFC,0xDB},{0xFD,0x08},{0xFD,0x33},{0xFD,0x5B},{0xFD,0x81},{0xFD,0xA5},{0xFD,0xC7},{0xFD,0xE7},{0xFE,0x05}, {0xFE,0x21},{0xFE,0x3C},{0xFE,0x55},{0xFE,0x6D},{0xFE,0x84},{0xFE,0x99},{0xFE,0xAD},{0xFE,0xC0},{0xFE,0x02},{0xFE,0xE3},{0xFE,0xF3},{0xFF,0x02}, {0xFF,0x10},{0xFF,0x1D},{0xFF,0x2A},{0xFF,0x36},{0xFF,0x42},{0xFF,0x4C},{0xFF,0x56},{0xFF,0x60},{0xFF,0x69},{0xFF,0x71},{0xFF,0x79},{0xFF,0x81} }; uchar code music[][2]={{0,4}, {17,6},{17,2},{19,8},{17,8},{22,8},{21,16}, {17,6},{17,2},{19,8},{17,8},{24,8},{22,16},{17,6},{17,2},{29,8},{26,8},{22,8},{21,8},{19,8},{27,6},{27,2},{26,8},{22,8},{24,8},{22,16}, {0xFF,0xFF}}; /***********************************************************延时函数**********************************************************/ void delayms(uint x) { uchar i; while(x--)for(i = 0; i < 120; i++); } void delay(unsigned char i) { for(i;i>0;i--); } /***********************************************************************液晶显示*******************************************/ //写指令 void Write_Order(uchar x) { delayms(1); RS = 0;//低电平选择指令寄存器 RW = 0;//低电平写数据 P0 = x;//P0端口设为x E = 1;//使能端高电平(下降沿,赋给传感器) _nop_();//指令延时1us,延时一个机器周期 E = 0;//使能端低电平 /*让EN引脚从低电平到高电平变化,然后EN引脚再从高电平到低电平出现下降沿, 检测到下降沿后,就会读取D0~D7的数据*/ RW = 1;//高电平进行读操作 } //写数据 void Write_Data(uchar x) { delayms(1); RS = 1;//高电平选择数据寄存器 RW = 0;//低电平写数据 P0 = x;//P0端口设为x E = 1;//使能端高电平 _nop_();//指令延时1us,延时一个机器周期 E = 0;//使能端低电平 RW = 1;//高电平进行读操作 } //初始化LCD(液晶显示器) void Init_1602(void) { Write_Order(0x38);//显示设置:8位数据接口,2行,16×2显示,5×7点阵 Write_Order(0x08);//显示关闭 Write_Order(0x01);//清屏(包含数据指针清零,所有显示清零) Write_Order(0x06);//输入方式:光标右移,屏幕不动 Write_Order(0x0c);//整体显示,有光标,不闪烁 } //显示一个字节 void Write_Byte(uchar x,uchar y,uchar dod) { if(x) y |= 0x40;//逻辑"或"1000000(0x40),X=X|0x40, 即将X的第6位赋值为1。 y |= 0x80;//10000000(0x80),即将X的第7位,也就是最高位赋值为1。 Write_Order(y);//写y指令 Write_Data(dod);//写数据 } //显示一个字符串 void Write_String(uchar x,uchar y,uchar *p) { uchar i = 0; if(x == 0)y|=0x80;//将X的第7位,也就是最高位赋值为1。 if(x == 1)y|=0xc0; if(x == 2)y|=0x94; if(x == 3)y|=0xd4; Write_Order(y);//写字符串指令y while(p[i] != 0) { Write_Data(p[i++]);//写字符串数据p[i++] } } //LCD显示字符 void Display(void) { uchar Buff[20]; sprintf(Buff,"Temp:%3.1f H%d ",Temp,Temp_H);//显示测试温度和报警上限温度 Write_String(0,0,Buff);//LCD显示字符串 } /*************************************************************温度检测******************************************************/ //*******************************************************初始化程序 **********************************************************// void Init_DS18B20(void) { unsigned char x=0; DQ=1; //DQ先置高 delay(8); //稍延时 DQ=0; //发送复位脉冲 delay(80); //延时(>480us) DQ=1; //拉高数据线 delay(5); //等待(15~60us) x=DQ; //用X的值来判断初始化有没有成功,18B20存在的话X=0,否则X=1 delay(20); } //**********读一个字节************// ReadOneChar(void) //主机数据线先从高拉至低电平1us以上,再使数据线升为高电平,从而产生读信号 { unsigned char i=0; //每个读周期最短的持续时间为60us,各个读周期之间必须有1us以上的高电平恢复期 unsigned char dat=0; for (i=8;i>0;i--) //一个字节有8位 { DQ=1; //DQ先置高 delay(1); DQ=0;//发送复位脉冲 dat>>=1; DQ=1; //拉高数据线 if(DQ) dat|=0x80; delay(4); } return(dat); } //*********************** **写一个字节**************************// void WriteOneChar(unsigned char dat) { unsigned char i=0; //数据线从高电平拉至低电平,产生写起始信号。15us之内将所需写的位送到数据线上, for(i=8;i>0;i--) //在15~60us之间对数据线进行采样,如果是高电平就写1,低写0发生。 { DQ=0; //在开始另一个写周期前必须有1us以上的高电平恢复期。 DQ=dat&0x01; delay(5); DQ=1; //继续至高电平 dat>>=1; } delay(4); } //读温度值(低位放tempL;高位放tempH;) void ReadTemperature(void) { int TempINT; Init_DS18B20(); //初始化 WriteOneChar(0xcc); //跳过读序列号的操作 WriteOneChar(0x44); //启动温度转换 delay(125); //转换需要一点时间,延时 Init_DS18B20(); //初始化 WriteOneChar(0xcc); //跳过读序列号的操作 WriteOneChar(0xbe); //读温度寄存器(头两个值分别为温度的低位和高位) tempL=ReadOneChar(); //读出温度的低位LSB tempH=ReadOneChar(); //读出温度的高位MSB TempINT = tempH<<8|tempL; Temp = TempINT*0.0625; } void CL(void) { ReadTemperature();//读温度值 } /*********************************************************按键扫描********************************************************/ void keyscand() { if(k1==0)//k1开关按下,温度上限加 { delayms(100);//延时 if(k1==0)//k1依然处于低电平状态 { Temp_H++;//温度上限加1 bz1=0; EA=0; } } if(Temp_H==100)//如果温度上限等于100 { Temp_H=50; //超过元件最大温度,至为50 } if(k2==0)//k2开关按下,温度上限减 { delayms(100); if(k2==0)//k2依然处于低电平状态 { Temp_H--;//温度上限减1 bz1=0; EA=0; } } if(Temp_H==0)//k3开关,播放音量 { Temp_H=50; } } /**********************************************BAOJING************************************************************/ void bj()//报警 { if(Temp>Temp_H)//温度大于温度上限 { beepIO=0;//蜂鸣器鸣叫 delayms(200);//超过上限报警 } if(Temp<Temp_H)//温度小于温度上限 { beepIO=1;//蜂鸣器关闭 } } //k3按键(播放音调) void k3scand() { if(k3==0)//如果k3被按下 { delayms(100);//延时 if(k3==0) { bz1++; } } if(bz1==2) { bz1=0; }//k3按下标志取值01 } /********************************************************主函数***********************************************************/ //中断T0 void T0_int() interrupt 1 { beepIO=!beepIO; TH0=T[m][0]; TL0=T[m][1]; } //主函数 void main() { uchar i=0; TMOD=0x01; //开启定时器0,0x10时使用定时器,0x11时启动两个 EA=1;//开放所有中断 ET0=1; //允许T0中断 Init_1602();//初始化LCD(液晶显示器) while(1) { k3scand();//k3按键 if(bz1==0)//k3未按下 { EA=0;//关闭所有中断 CL();//读温度值 Display();//LCD显示温度 delayms(50);//延时 keyscand();//按键扫描 bj();//报警 } if(bz1==1)//k3按下 { EA=1;//开放所有中断 m=music[i][0]; n=music[i][1]; if(m==0x00) { TR0=0;//关闭定时器计数器0 delayms(n*100); i++; } else if(m==0xFF) { TR0=0;//关闭定时器计数器0 delayms(30*100); i=0; } else if(m==music[i+1][0]) { TR0=1;//打开定时器计数器0 delayms(n*100); TR0=0; delayms(100); i++; } else { TR0=1;//开放定时器计数器0 delayms(n*100); i++; } } } }
程序效果图
链接: https://pan.baidu.com/s/1CFJgNWwhgXQfjJPz5pfX_w
提取码:64kl