51单片机温度传感器DS18B20程序LCD1602显示.docx
- 文档编号:17155351
- 上传时间:2023-07-22
- 格式:DOCX
- 页数:18
- 大小:115.56KB
51单片机温度传感器DS18B20程序LCD1602显示.docx
《51单片机温度传感器DS18B20程序LCD1602显示.docx》由会员分享,可在线阅读,更多相关《51单片机温度传感器DS18B20程序LCD1602显示.docx(18页珍藏版)》请在冰点文库上搜索。
51单片机温度传感器DS18B20程序LCD1602显示
仿真截图:
//仿真文件网盘地址:
:
//pan.baidu/s/1qW8sGQK
//程序:
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitP00=P0^0;
sbitP01=P0^1;
sbitP02=P0^2;
sbitP03=P0^3;
sbitP04=P0^4;
sbitP05=P0^5;
sbitP06=P0^6;
sbitP07=P0^7;
sbitP10=P1^0;
sbitP11=P1^1;
sbitP12=P1^2;
sbitP13=P1^3;
sbitP14=P1^4;
sbitP15=P1^5;
sbitP16=P1^6;
sbitP17=P1^7;
sbitP20=P2^0;
sbitP21=P2^1;
sbitP22=P2^2;
sbitP23=P2^3;
sbitP24=P2^4;
sbitP25=P2^5;
sbitP26=P2^6;
sbitP27=P2^7;
sbitP30=P3^0;
sbitP31=P3^1;
sbitP32=P3^2;
sbitP33=P3^3;
sbitP34=P3^4;
sbitP35=P3^5;
sbitP36=P3^6;
sbitP37=P3^7;
//******DS18B20******
#defineDQP17
/*************精确延时函数*****************/
voiddelay10us(void)//误差0us
{
unsignedchara,b;
for(b=1;b>0;b--)
for(a=2;a>0;a--);
}
voiddelay20us(void)//误差0us
{
unsignedchara,b;
for(b=1;b>0;b--)
for(a=7;a>0;a--);
}
voiddelay30us()//误差0us
{
unsignedchara,b;
for(b=3;b>0;b--)
for(a=3;a>0;a--);
}
voiddelay100us()//误差0us
{
unsignedchara,b;
for(b=1;b>0;b--)
for(a=47;a>0;a--);
}
voiddelay200us(void)//误差0us
{
unsignedchara,b;
for(b=1;b>0;b--)
for(a=97;a>0;a--);
}
voiddelay500us()//误差0us
{
unsignedchara,b;
for(b=71;b>0;b--)
for(a=2;a>0;a--);
}
voidDS18B20_init()//DS18B20初始化复位
{
DQ=1;
_nop_();
_nop_();
_nop_();
_nop_();//延时几个时钟周期保证DQ引脚稳定在高电平
DQ=0;
delay500us();//最短为480us的低电平信号复位
DQ=1;//拉高总线15-60us
delay30us();
delay200us();//延时足够时间复位基本上都会成功因此不必再判断是否复位成功
DQ=1;//释放总线
}
ucharRead_One_Byte()
{
uchari;
ucharbyte=0;
for(i=0;i<8;i++)
{
DQ=1;
_nop_();
_nop_();
_nop_();
_nop_();//延时几个时钟周期保证DQ引脚稳定在高电平
DQ=0;
byte>>=1;
delay20us();
DQ=1;//给脉冲产生读时间间隙
delay10us();//延时一定时间后,读DQ的值
if(DQ)
{byte|=0x80;}//读得DQ为1将1写到dat最高位;读得DQ为0不必处理
delay100us();
DQ=1;
}
return(byte);
}
voidWrite_One_Byte(ucharbyte)
{
uchari=0;
for(i=0;i<8;i++)
{
DQ=1;
_nop_();
_nop_();
_nop_();
_nop_();//延时几个时钟周期保证DQ引脚稳定在高电平
DQ=0;
DQ=byte&0x01;//写所给数据最低位
delay30us();
byte>>=1;
}
}
intRead_Temp()////////***读取温度值***********/////每次读写均要先复位
{
intt;
floattep;
uchara,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);
}
/***********LCD************/
#defineRSP22
#defineRWP21
#defineLCDENP20
#defineLCD_DATAP0//P0口接LCD数据口
#defineLCD_BUSYP07//lcd1602忙碌标志位
ucharidatalcd_code[10];//用来标记lcd1602什么时候清显示每个页面都设一个code,code不想同时清显示
//*****************************************延时函数***************************************//
voiddelayms(uintms)//延时?
个ms
{
uchara,b,c;
while(ms--)
{
for(c=1;c>0;c--)
for(b=142;b>0;b--)
for(a=2;a>0;a--);
}
}
/*
//**********字符串复制函数**********
voidstring_copy(uchar*target,uchar*source)//字符串复制target:
目标source:
源
{
uchari=0;
for(i=0;source[i]!
='\0';i++)//注意target的长度无保护措施!
{
target[i]=source[i];
}
target[i]='\0';
}
//**********字符串比较函数**********
ucharstring_cmp(uchar*target,uchar*source)//字符串比较target:
目标source:
源
{
ucharrevalue;
uchari=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;
else
revalue=0;
}
return(revalue);
}
*/
//****************LCD********************
//LCD基本函数:
voidbusy_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);//仿真时用延时法下载到真实单片机上时,将这句注释掉,采用上面的语句。
}
voidlcdwrcom(ucharcommand)//写指令
{
busy_check();
RW=0;//写
RS=0;//指令寄存器
LCD_DATA=command;
LCDEN=1;//负跳变写入指令
_nop_();
_nop_();
_nop_();
_nop_();
LCDEN=0;
}
voidlcdwrdata(ucharlcd_data)//写数据数字、字母、标点符号都是数据
{
busy_check();
RW=0;//写
RS=1;//数据寄存器
LCD_DATA=lcd_data;
LCDEN=1;//负跳变写入指令
_nop_();
_nop_();
_nop_();
_nop_();
LCDEN=0;
}
voidlcd_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扩展函数:
voidaddress(ucharx,uchary)//定位下一步要写数的地址
{
ucharlocation;
if(x==0)
location=0x80|y;
else
location=0xC0|y;
lcdwrcom(location);
}
voidprintchar(ucharx,uchary,ucharletter)//显示字母、单个字符
{
address(x,y);
lcdwrdata(letter);
}
voidprintword(ucharx,uchary,uchar*word)//显示单词〔字符数组〕
{
uchari=0;
for(i=0;word[i]!
='\0';i++)
{
address(x,y+i);
lcdwrdata(word[i]);
}
}
/*
voidprintuint(ucharx,uchary,ucharnum_ws_max,uintnum)//显示无符号整形0~65535x:
行y:
列num_ws_max变量的最大位数
{
uchari=0;
ucharstr[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';//手动加字符串结束标志
}
elseif(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';
}
elseif(num>=100)
{
str[0]=num/100+'0';
str[1]=num%100/10+'0';
str[2]=num%10+'0';
str[3]='\0';
}
elseif(num>=10)
{
str[0]=num/10+'0';
str[1]=num%10+'0';
str[2]='\0';
}
elseif(num>=0)
{
str[0]=num+'0';
str[1]='\0';
}
for(i=0;i<=5;i++)//uint类型最大值65535为5位数
{
if(str[i]!
='\0'&&i { address(x,y+i); lcdwrdata(str[i]); } elseif(str[i]=='\0'&&i { address(x,y+i); lcdwrdata('');//空格//实现功能: 在此变量的位数范围内,把没数字的位存0x20〔空格〕 //例如: 最大有3位: 999当变为99时,存为9+'0'9+'0'0x20 } } } */ voidprinttemp(ucharx,uchary,uinttemp)//显示温度显示一位小数【显示效果相当于将一个数除以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(''); } elseif(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(''); } elseif(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'); } } voidmain() { inttemp;//温度值 lcd_init(); printword(0,0,"temp: "); while (1) { temp=Read_Temp(); if(temp>0) { printchar(0,5,'+'); printtemp(0,6,temp); } elseif(temp==0) { printchar(0,5,''); printchar(0,6,'0'); } else { temp=-temp; printchar(0,5,'-'); printtemp(0,6,temp); } } }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 51 单片机 温度传感器 DS18B20 程序 LCD1602 显示