文档详情

【51单片机】温度传感器DS18B20程序LCD1602显示[共11页]

1528****253
实名认证
店铺
DOC
572KB
约11页
文档ID:152958705
【51单片机】温度传感器DS18B20程序LCD1602显示[共11页]_第1页
1/11

#define uchar unsigned char#define uint unsigned intsbit P00 = P0^0;sbit P01 = P0^1;sbit P02 = P0^2;sbit P03 = P0^3;sbit P04 = P0^4;sbit P05 = P0^5;sbit P06 = P0^6;sbit P07 = P0^7;sbit P10 = P1^0;sbit P11 = P1^1;sbit P12 = P1^2;sbit P13 = P1^3;sbit P14 = P1^4; .sbit P15 = P1^5;sbit P16 = P1^6;sbit P17 = P1^7;sbit P20 = P2^0;sbit P21 = P2^1;sbit P22 = P2^2;sbit P23 = P2^3;sbit P24 = P2^4;sbit P25 = P2^5;sbit P26 = P2^6;sbit P27 = P2^7;sbit P30 = P3^0;sbit P31 = P3^1;sbit P32 = P3^2;sbit P33 = P3^3;sbit P34 = P3^4;sbit P35 = P3^5;sbit P36 = P3^6;sbit P37 = P3^7;//****** DS18B20 ******#define DQ P17/************* 精确延时函数 *****************/void delay10us(void)//误差 0us//误差 0us//误差 0us{unsigned char a,b;for(b=1;b>0;b--)for(a=2;a>0;a--);}void delay20us(void){unsigned char a,b;for(b=1;b>0;b--)for(a=7;a>0;a--);}void delay30us(){unsigned char a,b;for(b=3;b>0;b--)for(a=3;a>0;a--);}’. .void delay100us(){//误差 0us//误差 0us//误差 0usunsigned char a,b;for(b=1;b>0;b--)for(a=47;a>0;a--);}void delay200us(void){unsigned char a,b;for(b=1;b>0;b--)for(a=97;a>0;a--);}void delay500us(){unsigned char a,b;for(b=71;b>0;b--)for(a=2;a>0;a--);}void DS18B20_init(){//DS18B20 初始化 复位DQ = 1;_nop_();_nop_();_nop_();_nop_();//延时几个时钟周期 保证 DQ 引脚稳定在高电平//最短为 480us 的低电平信号 复位//拉高总线 15-60usDQ = 0;delay500us();DQ = 1;delay30us();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;//延时几个时钟周期 保证 DQ 引脚稳定在高电平byte >>= 1;delay20us();DQ = 1;//给脉冲 产生读时间间隙delay10us();if(DQ)//延时一定时间后,读 DQ 的值{byte |= 0x80;} // 读得 DQ 为 1 将 1 写到 dat 最高位 ;读得 DQ 为 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 命令 单个传感器所以不必读取Write_One_Byte(0x44); // 开始转换ROM 里的序列号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/LSBt = tep*10 + 0.5;// 保留 1 位小数并四舍五入 **** 后面除 10 还原正确温度值)return(t);}/*********** LCD************/#define RS P22#define RW P21#define LCDEN P20#define LCD_DATA P0#define LCD_BUSY P07//P0 口接 LCD 数据口//lcd1602 忙碌标志位uchar idata lcd_code[10];// 用来标记 lcd1602 什么时候清显示 每个页面都设一个 code,code不想同时清显示//*****************************************延时函数***************************************//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--);}}/*//********** 字符串复制函数 **********void string_copy(uchar *target,uchar *source)// 字符串复制 target:目标 source:源{uchar i = 0;for(i = 0;source[i] != '\0';i++)// 注意 target 的长度 无保护措施!{target[i] = source[i];}target[i] = '\0';}//********** 字符串比较函数 **********uchar string_cmp(uchar *target,uchar *source)// 字符串比较 target:目标 source:源’. .{uchar revalue;uchar i = 0;for(i = 0;target[i] != '\0' && source[i] != '\0';i++)//两个都不等于 '\0'才执行 出现一个等于'\0'就跳出{if(target[i] == source[i]){revalue = 1;}else{revalue = 0;break;}}if(revalue == 1){if(target[i] == '\0' && source[i] == '\0')revalue = 1;elserevalue = 0;}return(revalue);}*///****************LCD********************//LCD 基本函数:void busy_check() //忙碌检测{/*RW = 1; //读RS = 0; //指令寄存器LCD_DATA = 0xFF;// 实验证明读数时要将 I/O 口要置 1LCDEN = 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;elselocation = 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] != '\0';i++){address(x,y + i);lcdwrdata(word[i]);}}/*void printuint(uchar x,uchar y,uchar num_ws_max,uint num)//显示无符号整形 0~65535 x:行y:列 num_ws_max 变量的最大位数{uchar i = 0;uchar str[5] = {0x20,0x20,0x20,0x20,0x20};’. .if(num >= 10000){str[0] = num/10000 + '0';str[1] = num%10000/1000 + '0';str[2] = num%1000/100 + '0';str[3] = num%100/10 + '0';str[4] = num%10 + '0';//}str[5] = '\0';//手动加字符串结束标志else if(num >= 1000){str[0] = num/1000 + '0';str[1] = num%1000/100 + '0';str[2] = num%100/10 + '0';str[3] = num%10 + '0';str[4] ='\0';}else if(num >= 100){str[0] = num/100 + '0';str[1] = num%100/10 + '0';str[2] = num%10 + '0';str[3] = '\0';}else if(num >=10){str[0] = num/10 + '0';str[1] = num%10 + '0';str[2] = '\0';}else if(num >= 0){str[0] = num + '0';str[1] = '\0';}for(i = 0;i <= 5;i++){//uint 类型 最大值 65535 为 5 位数if(str[i] != '\0' && i < num_ws_max){address(x,y + i);lcdwrdata(str[i]);}else if(str[i] == '\0' && i < num_ws_max)’. .{address(x,y+i);lcdwrdata(' ');// 空格// 实现效用:在此变量的位数范围内,把没数字的位存0x20(空格)//例如:最大有 3 位 :999 当变为 99 时,存为 9+'0' 9+'0' 0x20}}}*/void printtemp(uchar x,uchar y ,uint temp)//显示温度 显示一位小数 【显示效果相当于将一个数除以 10 并保存一位小数】{if(temp < 100){address(x,y);lcdwrdata(temp/10 + '0');address(x,y + 1);lcdwrdata('.');address(x,y + 2);lcdwrdata(temp%10 + '0');address(x,y + 3);lcdwrdata(' ');address(x,y + 4);lcdwrdata(' ');}else if(temp < 1000){address(x,y);lcdwrdata(temp/100 + '0');address(x,y + 1);lcdwrdata(temp%100/10 + '0');address(x,y + 2);lcdwrdata('.');address(x,y + 3);lcdwrdata(temp%10 + '0');address(x,y + 4);lcdwrdata(' ');}else if(temp < 10000){address(x,y);lcdwrdata(temp/1000 + '0');address(x,y + 1);’. .lcdwrdata(temp%1000/100 + '0');address(x,y + 2);lcdwrdata(temp%100/10 + '0');address(x,y + 3);lcdwrdata('.');address(x,y + 4);lcdwrdata(temp%10 + '0');}}void main(){int temp; //温度值lcd_init();printword(0,0,"temp:");while(1){temp = Read_Temp();if(temp > 0 ){printchar(0,5,'+');printtemp(0,6,temp);}else if(temp == 0)科教兴国11。

下载提示
相关文档
正为您匹配相似的精品文档