智能防火防盗系统
类似方法第二、第三列、第四列。 ??
SetComLCD1602(0x0c);
//显示开,关光标
此处用到效果就是在密码那块地方光标才会闪速,其他的地方不显示,效果见仿真。
4.8 定时中断
本设计中定时中断只用于声音报警。 void timer0() interrupt 1 using 1 {
if(3 == EroTimes || 1 == WarnSign)
{ ??
在main中定义打开中断
TMOD = 0x01; 选择T0的方式1中断。 frq = 0x00; TH0 = 0xfe; TL0 = 0xff;
方式1下TH0 TL0的计算方法如下
X=错误!未找到引用源。 //X的高位即为TH0,地8位为TL0;TR0 = 1;
允许T0计数,本程序中表示写到这里熟悉一下。 IE = 0x82;
当然,开始时设置EA=1是必须的。它是所以中断允许的总开关。 ET0溢出允许中断
TH0 = 0xfe;
TL0 = frq;
SPK = ~SPK;
第 26 页 (共 77 页)
系统软件的设计与实现
4.9 温度模块
图8 温度模块电路图
实物电路图如图8,写时间隙分为写“0”和写“1”。在写数据时间隙的前15uS总线需要是被控制器拉置低电平,而后则将是芯片对总线数据的采样时间,采样时间在15~60uS,采样时间内如果控制器将总线拉高则表示写“1”,如果控制器将总线拉低则表示写“0”。每一位的发送都应该有一个至少15uS的低电平起始位,随后的数据“0”或“1”应该在45uS内完成。整个位的发送时间应该保持在60~120uS,否则不能保证通信的正常。
读时间隙时控制时的采样时间应该更加的精确才行,读时间隙时也是必须先由主机产生至少1uS的低电平,表示读时间的起始。随后在总线被释放后的15uS中DS18B20会发送内部数据位,这时控制如果发现总线为高电平表示读出“1”,如果总线为低电平则表示读出数据“0”。每一位的读取之前都由控制器加一个起始信号。注意:必须在读间隙开始的15uS内读取数据位才可以保证通信的正确。
DQ = 1; //DQ复位
第 27 页 (共 77 页)
智能防火防盗系统
Delay_UMs(8); //稍做延时
DQ = 0; //单片机将DQ拉低 Delay_UMs(80); //精确延时 大于 480us DQ = 1; //拉高总线 Delay_UMs(20);
//注意延迟,不然会出错 Delay_Fut(10);出错!
复位:首先我们必须对DS18B20芯片进行复位,复位就是由控制器(单片机)给DS18B20单总线至少480uS的低电平信号。当18B20接到此复位信号后则会在15~60uS后回发一个芯片的存在脉冲。
DS18B20芯片与单片机的接口: ??
for (i=8;i>0;i--) 循环取出8位
DQ = 0; // 给脉冲信号 sChar>>=1; //数据右移一位 DQ = 1; // 给脉冲信号 if(DQ)
sChar|=0x80; //按位或,取最高位 Delay_UMs(4);
return(sChar);
ds18b20读一个字节:存在脉冲,在复位电平结束之后,控制器应该将数据单总线拉高,以便于在15~60uS后接收存在脉冲,存在脉冲为一个60~240uS的低电平信号。至此,通信双方已经达成了基本的协议,接下来将会是控制器与18B20间的数据通信。如果复位低电平的时间不足或是单总线的电路断路都不会接到存在脉冲,在设计时要注意意外情况的处理。
若要读出当前的温度数据我们需要执行两次工作周期,第一个周期为复位、跳过ROM指令、执行温度转换存储器操作指令、等待500uS温度转换时间。紧接着执行第二个周期为复位、跳过ROM指令、执行读RAM的存储器操作指令、读数据(最多为9个字节,中途可停止,只读简单温度值则读前2个字节即可)。其它的操作流程也大同小异。
void WriteOneChar(uchar WDat)写法
第 28 页 (共 77 页)
系统软件的设计与实现
for (i=8; i>0; i--)
{ ??
执行或数据读写:一个存储器操作指令结束后则将进行指令执行或数据的读写,这个操作要视存储器操作指令而定。如执行温度转换指令则控制器(单片机)必须等待18B20执行其指令,一般转换时间为500uS。如执行数据读写指令则需要严格遵循18B20的读写时序来操作。
unsigned char a=0,b=0,x=0; Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
0xCC 为跳过ROM,命令发出后系统将对所有DS18B20进行操作,通常用于启动所有DS18B20转换之前,或系统中仅有一个DS18B20时。
WriteOneChar(0x44); // 启动温度转换
0x44 为温度转换寄存器,用于启动DS18B20进行温度测量,温度转换命令被执行后DS18B20保持等待状态。DS18B20将在总线上输出‘0’,若温度转换完成,则输出‘1’。
Delay_UMs(50); // this message is wery important Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作 WriteOneChar(0xBE);
//读取温度寄存器等(共可读9个寄存器) 前两个就是温度 字节的读或写是从高位开始的; Delay_UMs(50);
a=ReadOneChar(); //读取温度值低位 b=ReadOneChar();
//读取温度值高位
DQ = 0;
DQ = WDat&0x01; //取最低位 Delay_UMs(5);
DQ = 1; //上升沿将数据送入 WDat>>=1;
Int_Tempt=(a>>4)|(b<<4)&0X3f; //温度整数部分
第 29 页 (共 77 页)
智能防火防盗系统
Flot_Tempt=(a<<4)&0xf0; //温度小数部分
LSB的高4表示十位和个位,后4为表示小数位。本设计只保存一位小数。 MSB的高4为S 为符号为,正负温度。后4位为百位,在这里不考虑负温度,所以将0x3F将高位过滤掉,防火只检测高温着火点检测。
对于高于某温度的值返回报警。
下面的代码是将取出来的数据转化为字符串,因为在LCD1602中只能读取
字符,只有这样才好显示出来。显示代码见下面函数。
if(b & 0x80) FloatTempt[0]='-';
//负数 因为是防火,不需要算出负数
else
FloatTempt[0]=' ';
if(Int_Tempt>100) { } else { }
FloatTempt[3]='.'; if(Flot_Tempt & 0x80)
x=x+5000;
FloatTempt[1]=Int_Tempt/10+'0';
//整数十位
FloatTempt[1]='9'; //整数十位 FloatTempt[2]='9'; //整数个位
FloatTempt[2]=Int_Tempt+'0'; //整数个位
if(Flot_Tempt & 0x40)
x=x+2500;
??
PS:LSB的第0~4位为小数部分 xxxx1111 10000/16 = 625,就是说1就代表625,xxxx1000
第 30 页 (共 77 页)