SHT10温湿度的值送往LCD显示,读取DS1302的时钟日期送往LCD显示, 接着开启按键扫描子程序等待着按键的输入读取对时间日期和闹钟的设置调整,将设置好的闹钟子程序与DS1302所读取的时间进行比较,如是一致则调用蜂鸣器子程序进行报警。
4.2.2 程序流程框图
开始 初始化 Y 是否按键k1 读写时间日期 N 读写温湿度 N 是否按键k2 Y Y N 进入时间日期调整 是否k2有效 进入闹钟设置
N
N N 是否按键k3 是否按键k4 Y
是否按键k3
Y Y 多个闹钟设置 相应位加1 相应位减1 N N 是否与时间 是否按键 相等 k4 Y Y 返回 LCD显示 蜂鸣器触发 相应位加1
返回
4.3 程序的实现
我们使用的是C语言编程并利用Keil软件编译连接生成Hex文件后(如图4.3.1)利用STC烧录软件(如图4.3.2)将Hex代码下载到单片机里面;
图4.3.1 Keil软件编译c程序
图4.3.2 烧录软件
以下为部分程序分析:
4.3.1 检查LCD1602忙位子函数
void LCD1602_busy() // 检查LCD1602忙位子函数 { uchar i=0; RS=0; RW=1; E=1; P0=0xff; i=0; while(((P0&0x80)==0x80)&&i<150) i++; E=0; }
4.3.2 LCD1602写指令子函数
void write_com(uchar com) // LCD1602写指令子函数 { LCD1602_busy(); RS=0; RW=0; P0=com; E=1; E=0; }
4.3.3 LCD1602写数据子函数
void write_date(uchar date) // LCD1602写数据子函数 { LCD1602_busy(); RS=1; RW=0; P0=date; E=1; E=0; }
4.3.4 LCD1602初始化子函数
void LCD1602_init() { uchar i; write_com(0x38); write_com(0x0c); write_com(0x06);
//LCD1602初始化设置
}
write_com(0x01); write_com(0x80); for(i=0;i<16;i++) { write_date(table1[i]); delay(500); }
write_com(0xc0); for(i=0;i<16;i++) { write_date(table2[i]); delay(500); } a=35; b=10; c=65; d=40;
4.3.5 SHT10写字节子函数
char s_write_byte(uchar value) { uchar i,error=0; for(i=0x80;i>0;i>>=1) //高位为1,循环右移 { if(i&value) DATA=1; //和要发送的数相与,结果为发送的位 else DATA=0; SCK=1; _nop_(); _nop_(); _nop_();//延时3us SCK=0; } DATA=1; //释放数据线 SCK=1; error=DATA; //检查应答信号,确认通讯正常 _nop_(); _nop_(); _nop_(); SCK=0; DATA=1; return error; //error=1 通讯错误 }
4.3.6 SHT10读字节子函数
char s_read_byte(uchar ack)
{ uchar i,val=0; DATA=1; //释放数据线 for(i=0x80;i>0;i>>=1) //高位为1,循环右移 { SCK=1; if(DATA) val=(val|i); //读一位数据线的值 SCK=0; } DATA=!ack; //如果是校验,读取完后结束通讯; SCK=1; _nop_(); _nop_(); _nop_();//延时3us SCK=0; _nop_(); _nop_(); _nop_(); DATA=1; //释放数据线 return val; }
4.3.7 SHT10温湿度检测子函数
char s_measure(uchar *p_value,uchar *p_checksum,uchar mode) { unsigned error=0; uint i; s_transstart(); //启动传输 switch(mode) //选择发送命令 { case TEMP: error+=s_write_byte(0x03); break; //测量温度 case HUMI: error+=s_write_byte(0x05); break; //测量湿度 default: break; } for(i=0;i<65535;i++) if(DATA==0) break; //等待测量结束 if(DATA) error+=1; // 如果长时间数据线没有拉低,说明测量错误 *(p_value)=s_read_byte(1); //读第一个字节,高字节 (MSB) *(p_value+1)=s_read_byte(1); //读第二个字节,低字节 (LSB) *p_checksum=s_read_byte(0); //read CRC校验码 return error; // error=1 通讯错误 }