锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

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

时间:2024-04-26 19:07:09

此程序是基于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

//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百科大全!

相关文章