该温度检测器,使用了10米线长的DS18b20温度传感器和51开发板,传感器由于使用长距离的接线,所以需增加上拉电阻。使用Lcd1602显示温度和所设置的上限报警值,可使用矩阵键盘设置上限报警的温度值,报警系统包括:LED灯由黄变红,同时电机转动散热。
制作出来的实物图如下:
单片机源程序如下:
- #include "reg52.h"
- #include "temp.h" //包含ds18b20的相关函数
- #include "lcd.h" //包含Lcd的相关函数
- #define GPIO_KEY P1 //薄膜按键接口
- typedef unsigned int u16; //对数据类型进行声明定义
- typedef unsigned char u8;
- void LcdWriteCom(uchar com); //选择Lcd屏写入位置的函数
- void LcdWriteData(uchar dat); //在Lcd屏进行写入数据操作的函数
- void LcdInit(); //Lcd初始化函数
- sbit LED_yello=P3^5; //LED黄色正极
- sbit LED_red=P3^6; //LED红色正极
- sbit K3=P3^2; //设置按键
- int Ceiling=27; //初始上限值
- u8 LcdplayData[16]={'T','e','m','p',':',' ',' ',0,0,0,0,'.',0,0,'`','C'};
- u8 sz[16]="Please input: ";
- u8 shezhi[16]={'C','e','i','l','i','n','g',':',' ','2','7','`','C',' ',' ',' '};
- void Delay_ms(unsigned int ms)//延时函数,延时1ms
- {
- int j;
- for(;ms>0;ms--)
- for(j=140;j>0;j--);
- }
- /*******************************************************************************
- * 函 数 名 : datapros()
- * 函数功能 : 温度读取处理转换函数
- * 输 入 : temp
- * 输 出 : 无
- *******************************************************************************/
- int datapros(int temp)
- {
- float tp;
- int t;
- if(temp< 0) //当温度值为负数
- {
- LcdplayData[7] ='-'; //正负位为-
- //因为读取的温度是实际温度的补码,所以减1,再取反求出原码
- temp=temp-1;
- temp=~temp;
- tp=temp;
- temp=tp*0.0625*100+0.5;
- //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
- //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
- //算加上0.5,还是在小数点后面。
-
- }
- else
- {
- LcdplayData[7] ='+';
- tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
- //如果温度是正的那么,那么正数的原码就是补码它本身
- temp=tp*0.0625*100+0.5;
- //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
- //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
- //算加上0.5,还是在小数点后面。
- }
- t=temp;
- LcdplayData[8] = temp / 10000+48; //提取各位
- LcdplayData[9] = temp % 10000 / 1000+48;
- LcdplayData[10] = temp % 1000 / 100+48;
- LcdplayData[12] = temp % 100 / 10+48;
- LcdplayData[13] = temp % 10+48;
- return t;
- }
- /*******************************************************************************
- * 函数名 :LcdDisplay()
- * 函数功能 :Lcd1602显示函数
- * 输入 : 无
- * 输出 : 无
- *******************************************************************************/
- void LcdDisplay()
- {
- LcdWriteCom(0x87);
- LcdWriteData(LcdplayData[7]); //写入+-号
- LcdWriteData(LcdplayData[8]=='0' ? ' ':LcdplayData[8]); //输出整数部分
- LcdWriteData(LcdplayData[9]=='0' ? ' ':LcdplayData[9]); //若是0,不输出
- LcdWriteData(LcdplayData[10]);
- LcdWriteCom(0x8c);
- LcdWriteData(LcdplayData[12]); //输出小数部分
- LcdWriteData(LcdplayData[13]);
- // Delay_ms(100);
- /*
- SBUF = '0'+m; //将接收到的数据放入到发送寄存器
- while (!TI); //等待发送数据完成
- TI = 0; //发送完成标志位清零
- */
- }
- void xinxi()//输出两行中的固定信息
- {
- u8 i;
- LcdWriteCom(0x01);//清屏
- LcdWriteCom(0x80);//输出第一行的
- for (i=0;i<7;i++)
- {
- LcdWriteData(LcdplayData[i]);
- }
- LcdWriteCom(0x8b);
- LcdWriteData(LcdplayData[11]);
- LcdWriteCom(0x8e);
- LcdWriteData(LcdplayData[14]);
- LcdWriteData(LcdplayData[15]);
- LcdWriteCom(0xc0);//输出第二行的
- for (i=0;i<16;i++)
- {
- if (i==8&&shezhi[8]=='0') shezhi[8]=' ';
- LcdWriteData(shezhi[i]);
- }
- }
- void zdkg() // 中断开关
- {
- EA=1;
- IT0=1;
- EX0=1;
- }
- void Int0() interrupt 0 //外部中断0的中断函数
- {
- u8 i,j,KeyValue;
- u16 key=0;
- if(K3==0)
- {
- Delay_ms(10);//消抖
- if(K3==0)
- {
- LcdWriteCom(0x80);
- for (i=0;i<16;i++)//输出提示信息
- {
- LcdWriteData(sz[i]);
- }
- while (K3==0) ;//等待松手,必须确保第一次按下后已松手
- while (1)
- {
- j=0;
- GPIO_KEY=0x0f;
- while (GPIO_KEY==0x0f) //等待按下键盘
- {
- if (K3==0)
- {
- Delay_ms(10);
- if (K3==0)
- {
- while (K3==0) ;//等待松手,必须确保第2次按下后已松手
- goto over; //若再次按下K3按键,则设置完毕,可以跳出中断
- }
- }
- }
- if (GPIO_KEY!=0x0f)//读取按键是否按下
- {
- Delay_ms(10);//延时消抖
- if(GPIO_KEY!=0x0f)//再次检测键盘是否按下
- {
- //测试列
- GPIO_KEY=0X0f;
- switch(GPIO_KEY)
- {
- case(0X07): KeyValue=0;break;
- case(0X0b): KeyValue=1;break;
- case(0X0d): KeyValue=2;break;
- case(0X0e): KeyValue=3;break;
- }
- //测试行
- GPIO_KEY=0Xf0;
- switch(GPIO_KEY)
- {
- case(0X70): KeyValue=KeyValue+0;break;
- case(0Xb0): KeyValue=KeyValue+4;break;
- case(0Xd0): KeyValue=KeyValue+8;break;
- case(0Xe0): KeyValue=KeyValue+12;break;
- }
- while((j<40)&&(GPIO_KEY!=0xf0)) //松手检测
- {
- Delay_ms(10);
- j++;
- }
- switch (KeyValue)
- {
- //key计算最新键入的值,Ceiling存放最新键入的值
- case 0:key=key*10+1;Ceiling=key;break;//键入1
- case 1:key=key*10+2;Ceiling=key;break;//键入2
- case 2:key=key*10+3;Ceiling=key;break;//键入3
- case 3:Ceiling++;key=0;break; //按“A”,则加1,同时变量key要清零
- case 4:key=key*10+4;Ceiling=key;break;//键入4
- case 5:key=key*10+5;Ceiling=key;break;//键入5
- case 6:key=key*10+6;Ceiling=key;break;//键入6
- case 7:Ceiling--;key=0;break; //按“B”,则减1,同时变量key要清零
- case 8:key=key*10+7;Ceiling=key;break;//键入7
- case 9:key=key*10+8;Ceiling=key;break;//键入8
- case 10:key=key*10+9;Ceiling=key;break;//键入9
- case 11:break;
- case 12:key=Ceiling=0;break; //按“*”,则所有清零
- case 13:key=key*10+0;Ceiling=key;break;//键入0
- case 14:break;
- case 15:break; //“C”“D”“#”无操作
- }
- shezhi[8] = Ceiling % 1000 / 100+48;
- shezhi[9] = Ceiling % 100 / 10+48;
- shezhi[10] = Ceiling % 10+48;
- LcdWriteCom(0xc8);
- LcdWriteData(shezhi[8]=='0' ? ' ':shezhi[8]); //显示设置的上限值
- LcdWriteData(shezhi[9]=='0' ? ' ':shezhi[9]);
- LcdWriteData(shezhi[10]);
- }
- }
- }
- }
- }
- over: xinxi(); //跳出中断前重新输出屏幕固定信息
- }
- /*******************************************************************************
- * 函 数 名 : main
- * 函数功能 : 主函数
- * 输 入 : 无
- * 输 出 : 无
- *******************************************************************************/
- void main()
- {
- u16 temp;
- LED_red=0;
- LED_yello=1;
- LcdInit();//初始化Lcd
- zdkg(); //打开中断
- xinxi(); //输出屏幕固定信息
- while(1)
- {
- temp=datapros(Ds18b20ReadTemp()); //数据处理函数
- LcdDisplay(); //Lcd显示函数
- if (temp>=Ceiling*100) LED_red=1,LED_yello=0; //超限报警(LED灯变红)
- else LED_red=0,LED_yello=1;
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
Ds18B20温度检测器(Lcd显示、矩阵键盘设置上限报警、报警系统(LED灯亮、电机转动散热).rar
(2.04 MB, 下载次数: 52)
|