资讯详情

单片机开源项目之基于DS18B20的带记忆功能温度报警系统源码

此程序是基于51hei单片机上面做的,如需要移植到自己的电路上,修改相应的端口即可,开发板完整的电路图下载: 点这里(注意:只需要看相关部分即可如 温感 数码管 蜂鸣器的使用的端口的连线,其他部分可以忽略)

/** *********************************************************************************************************** * @file : main.c * @author : 徐冉 * @date : 2014年4月27日08:40:23 ~ 2014年5月1日23:03:58 * @version : V1.2.3 * @brief : 基于DS18B20的带记忆功能温度报警系统 单片机STC89C52RC 晶振 : 11.0592MHZ * @note : 温度报警值可由开发板和红外遥控器按键进行调整,调整后下次上电将保存上一次的调整值 * ------------ 温度报警系统有三种状态:当温度达到设定的高温预警值范围时将显示"火",同时蜂鸣器 * ------------ 以8000HZ的频率发声报警,且LED小灯全亮;当温度达到设定的低温预警值时LED点阵屏将显示“水”, * ------------ 蜂鸣器将以4000HZ的频率报警,且LED小灯全亮;当温度处于正常温度值时,LED点阵屏显示“心形”, * ------------ 蜂鸣器处于关闭状态,且LED小灯全部熄灭。 *********************************************************************************************************** */ #include <reg52.h>

//74HC138 sbit A 3 = P1^3; sbit ENLED = P1^4; // sbit BUZZ = P1^6; // 编码表 unsigned char code LedTable[] = { 0xC0, //"0" 0xF9, //"1" 0xA4, //"2" 0xB0, //"3" 0x99, //"4" 0x92, //"5" 0x82, //"6" 0xF8, //"7" 0x80, //"8" 0x90, //"9" 0x9C, // '小0' 0xC6, //'C' 0xBF //"-" }; //数码管显示缓冲区+LED独立小灯 unsigned char idata LedBuff[] = {0xC6, 0x9C, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F}; //点阵取模 unsigned char pdata LedCode[3][8] = { {0xFF,0x99,0x00,0x00,0x00,0x81,0xC3,0xE7}, //heart {0xF7,0xD5,0xD5,0xE6,0xF7,0xEB,0xDD,0xBE}, //fire {0xF7,0x77,0xA0,0xC3,0xE5,0xD6,0xB7,0x71} //water }; /**************************local values definition***********************************/ //温度状态 unsigned char idata tempSta = 0;//0表示正常温度,1表示高温,2表示低温 bit flag2s = 0; unsigned char setTempIndex = 0;//0-正常运行状态 1-8报警温度设定索引 unsigned char thr0, tlr0;//T0定时器重载值 unsigned int counter = 0;// unsigned char idata thr1, tlr1;//00H-70H内存不够,使用70H-FFH内存 signed int temp;//存储温度值 bit buzzflag = 0;//蜂鸣器启动标志 //定义报警温度的上限值和下限值范围(以下温度值是*10之后的温度值)温度值分正负且都是int型 signed int shangxianHigh = 300, shangxianLow = 280;//温度上限值高温度值和低温度值 signed int xiaxianHigh = 200, xiaxianLow = 180; //温度下限值的高温度值和低温度值 signed char num[8] = {0, 0, 0, 0, 0, 0, 0, 0};//保存报警温度值十位数和个位数 extern bit flagIrd; //红外解码完成标志 extern unsigned char IrdCode[4];//装载红外解码值 /**************************local function definition***********************************/ void ConfigTimer0(unsigned int xms); void TempToLedBuf(signed int temp); void TempertureWarning(signed int temp); void ConfigBuzzFr(unsigned int fr); void ReadE2PROMToNumArrary(); /**************************extern function definition***********************************/ extern void KeyDrive(); extern void KeyScan(); extern void 1602RefreshCoursor(); extern void InitLCD1602(); extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char * str); extern bit StartConvertTemp(); extern bit ReadDS18B20Temperture(signed int * temperture); extern void Write Byte(unsigned char addr, unsigned char dat); extern unsigned char ReadEEPROMByte(unsigned char addr); extern void LEDRefreshPause(); extern void ContinueRefreshLED(); extern void ConfigInfrared(); extern void IrdKeyDrive(); /*主函数main()*/ void main(void) { ADDR3 = 1; ENLED = 0;//选择LED InitLCD1602(); ConfigTimer0(1);//T0定时1ms ConfigInfrared(); //ConfigBuzzFr(1000);//默认设定蜂鸣器频率为1000 StartConvertTemp();//启动一次温度转换 LcdShowStr(0, 0, "high T: XX-XX 'C"); LcdShowStr(0, 1, "low T: XX-XX 'C");//LCD初始化显示 ReadE2PROMToNumArrary(); EA = 1; //打开总中断 while (1) { KeyDrive(); //检测按键动作 if (flagIrd) { flagIrd = 0; IrdKeyDrive();//红外按键检测 } if (flag2s) { flag2s = 0; if (ReadDS18B20Temperture(&temp)) { TempToLedBuf(temp); //将温度值转换成数码管数字并检测温度是否超限,超限启动声光报警! StartConvertTemp();//再次启动温度转换 } } } } /*将eeprom的存储的报警温度值的各个位数字读取到num[8]数组中*/ void ReadE2PROMToNumArrary() { unsigned char str[4]; //数码管初始化显示0.00 LedBuff[2] = LedTable[0]; LedBuff[3] = LedTable[0]; LedBuff[4] = LedTable[0]; LedBuff[3] &= 0x7F;//add point /*读取eeprom中的数据*/ num[0] = ReadEEPROMByte(0x00); num[1] = ReadEEPROMByte(0x01); num[2] = ReadEEPROMByte(0x02); num[3] = ReadEEPROMByte(0x03); num[4] = ReadEEPROMByte(0x04); num[5] = ReadEEPROMByte(0x05); num[6] = ReadEEPROMByte(0x06); num[7] = ReadEEPROMByte(0x07); LedBuff[6] = 0x7F;//读取成功指示 /*初始化更新设定的报警温度值*/ shangxianLow = (num[0] * 100 + num[1] * 10); shangxianHigh = (num[2] * 100 + num[3] * 10); xiaxianLow = (num[4] * 100 + num[5] * 10); xiaxianHigh = (num[6] * 100 + num[7] * 10); /*将报警温度值显示到LCD1602上*/ str[0] = num[0] + '0'; str[1] = num[1] + '0'; str[2] = '\0'; LcdShowStr(8, 0, str); str[0] = num[2] + '0'; str[1] = num[3] + '0'; str[2] = '\0'; LcdShowStr(11, 0, str); str[0] = num[4] + '0'; str[1] = num[5] + '0'; str[2] = '\0'; LcdShowStr(8, 1, str); str[0] = num[6] + '0'; str[1] = num[7] + '0'; str[3] = '\0'; LcdShowStr(11, 1, str); } /*将温度值转换为有效数字存储到LedBuff中*/ void TempToLedBuf(signed int temp) { unsigned char buf[6];//缓冲区 signed char i = 0; //i必须是有符号型数据 if (temp < 0) //负温度值 { buf[5] = LedTable[12];//添加负号 //保留一位小数 temp = (~temp + 1) * 0.0625 * 10;//负值,读取到的16位二进制数值取反+1再*分辨率0.0625 for (i = 0; i < 4; i++) //温度值最高3位数值+小数位 { buf[i] = temp % 10; temp /= 10; } //去掉无效位数字 for (i = 3; i > 1; i--) { if (buf[i] == 0) { buf[i] = 0xFF;//去掉高位0不显示 } else { break;//遇到第一个有效数字就退出 } } //转换为实际的有效数字 for (; i >= 0; i--) { buf[i] = LedTable[buf[i]]; } //将实际数字拷贝到数码管缓冲区中 for (i = 0; i < 4; i++) { LedBuff[i+2] = buf[i]; } } else { //温度值大于等于0,保留一位小数位 temp = (temp * 0.0625 * 10);//直接用读取到的16位二进制数值*分辨率即是实际的温度值 TempertureWarning(temp); //温度报警检测必须函数必须放在前面 for (i = 0; i < 4; i++) { buf[i] = temp % 10; temp /= 10; } //去掉高位的0 for (i = 3; i > 1; i--) { if (buf[i] == 0) { buf[i] = 0xFF; } else { break;//遇到第一个有效数字就退出 } } //转换为实际的有效数字 for (; i >= 0; i--) { buf[i] = LedTable[buf[i]]; } //拷贝到缓冲区 for (i = 0; i < 4; i++) { LedBuff[i+2] = buf[i]; //最低两位显示温度标示符 } } //在相应的位置点上小数点 LedBuff[3] &= 0x7F;//0 111 1111 } /*刷新LCD设置位置上的数字显示*/ void RefreshLCDDisplay() { unsigned char str[3];//字符串缓冲区 switch (setTempIndex) { case 1: str[0] = num[0] + '0'; str[1] = '\0'; LcdShowStr(8, 0, str); break; case 2: str[0] = num[1] + '0'; str[1] = '\0'; LcdShowStr(9, 0, str); break;//shangxianLow的十位和个位数字显示刷新 case 3: str[0] = num[2] + '0'; str[1] = '\0'; LcdShowStr(11, 0, str); break; case 4: str[0] = num[3] + '0'; str[1] = '\0'; LcdShowStr(12, 0, str); break; case 5: str[0] = num[4] + '0'; str[1] = '\0'; LcdShowStr(8, 1, str); break; case 6: str[0] = num[5] + '0'; str[1] = '\0'; LcdShowStr(9, 1, str); break; case 7: str[0] = num[6] + '0'; str[1] = '\0'; LcdShowStr(11, 1, str); break; case 8: str[0] = num[7] + '0'; str[
锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台