完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
//代码如下 #include #include #define uchar unsigned char #define uint unsigned int #define LCD_DATA P2 ***it Beep=P1^0; //蜂鸣器 ***it DQ=P0^1; //定义温度传感器的数据口 ***it Fire=P0^2; //火焰传感器 ***it RS=P0^7; //LCD1602相关 ***it RW=P0^6; ***it LCDEN=P0^5; ***it LCD_BUSY=P2^7; uchar idata lcd_code[10];//用来标记lcd1602 什么时候清显示 每个页面都设一个code,code不想同时清显示 /*************精确延时函数*****************/ void delay10us(void) //误差 0us { unsigned char a,b; for(b=1;b>0;b--) for(a=2;a>0;a--); } void delay20us(void) //误差 0us { unsigned char a,b; for(b=1;b>0;b--) for(a=7;a>0;a--); } void delay30us() //误差 0us { unsigned char a,b; for(b=3;b>0;b--) for(a=3;a>0;a--); } void delay100us() //误差 0us { unsigned char a,b; for(b=1;b>0;b--) for(a=47;a>0;a--); } void delay200us(void) //误差 0us { unsigned char a,b; for(b=1;b>0;b--) for(a=97;a>0;a--); } void delay500us() //误差 0us { unsigned char a,b; for(b=71;b>0;b--) for(a=2;a>0;a--); } //DS18B20初始化 void DS18B20_init() { DQ = 1; _nop_(); _nop_(); _nop_(); _nop_(); DQ = 0; delay500us(); DQ = 1; delay300us(); delay200us(); DQ = 1; } uchar Read_One_Byte() { uchar i; uchar byte = 0; for(i =0;i<8;i++) { DQ = 1; _nop_(); _nop_(); _nop_(); _nop_(); DQ = 0; byte >>= 1; delay20us(); DQ = 1; delay10us(); if(DQ) { byte |= 0x80; //读DQ为1,将数据写入最高位;为0,则不管 } delay100us(); DQ = 1; } return(byte); } void Write_One_Byte(uchar byte) { uchar i = 0; for(i = 0;i < 8;i++) { DQ = 1; _nop_(); _nop_(); _nop_(); _nop_(); //延时几个时钟周期 保证DQ引脚稳定在高电平 DQ = 0; DQ = byte & 0x01; //写所给数据最低位 delay30us(); byte >>= 1; } } /***读取温度值***/ int Read_Temp() { int t; float tep; uchar a,b; DS18B20_init(); Write_One_Byte(0xcc); //跳过ROM命令 单个传感器所以不必读取ROM里的序列号 Write_One_Byte(0x44); //开始转换 DS18B20_init(); Write_One_Byte(0xcc); //跳过ROM命令 Write_One_Byte(0xbe); //读寄存器,共九字节,前两字节为转换值 a = Read_One_Byte(); //a存低字节 b = Read_One_Byte(); //b存高字节 t = b; t <<= 8;//高字节转换为10进制 t = t|a; tep = t*0.0625;//转换精度为0.0625/LSB t = tep*10 + 0.5;//保留1位小数并四舍五入****后面除10还原正确温度值) return(t); } void delayms(uint ms)//延时?个 ms { uchar a,b,c; while(ms--) { for(c=1;c>0;c--) for(b=142;b>0;b--) for(a=2;a>0;a--); } } //LCD基本函数: //忙碌检测 void busy_check() { RW = 1; //读 RS = 0; //指令寄存器 LCD_DATA = 0xFF;//实验证明读数时要将I/O口要置1 LCDEN = 0; _nop_(); _nop_(); _nop_(); _nop_(); LCDEN = 1;// EN高电平读信息 负跳变执行指令 _nop_(); _nop_(); _nop_(); _nop_(); while(1) { if(LCD_BUSY == 0)//P07 == 0跳出循环 break; } //delayms(2);//仿真时用延时法 下载到真实单片机上时,将这句注释掉,采用上面的语句。 } //写指令 void lcdwrcom(uchar command) { busy_check(); RW = 0;//写 RS = 0;//指令寄存器 LCD_DATA = command; LCDEN = 1;//负跳变写入指令 _nop_(); _nop_(); _nop_(); _nop_(); LCDEN = 0; } //写数据 void lcdwrdata(uchar lcd_data) { busy_check(); RW = 0;//写 RS = 1;//数据寄存器 LCD_DATA = lcd_data; LCDEN = 1;//负跳变写入指令 _nop_(); _nop_(); _nop_(); _nop_(); LCDEN = 0; } //初始化 void lcd_init() { delayms(15);//必要 lcd1602上电到电压稳定需要时间 RW = 0;//写 RS = 0;//指令寄存器 LCD_DATA = 0x38;// 0x38设置显示模式为:16X2 显示,5X7 点阵,8 位数据接口' LCDEN = 1; _nop_(); _nop_(); _nop_(); _nop_(); LCDEN = 0; delayms(5); lcdwrcom(0x0c);//打开显示 无光标 不闪烁 lcdwrcom(0x06);//指令3 光标右移 屏幕所有文字移动无效 lcdwrcom(0x01);// 清显示,光标复位到地址00H位置。 } //LCD扩展函数: void address(uchar x,uchar y) //定位下一步要写数的地址 { uchar location; if(x == 0) location = 0x80|y; else location = 0xC0|y; lcdwrcom(location); } void printchar(uchar x,uchar y,uchar letter)//显示字母、单个字符 { address(x,y); lcdwrdata(letter); } void printword(uchar x,uchar y,uchar *word) //显示单词(字符数组) { uchar i = 0; for(i = 0;word[i] != ' |