DS18B20设计程序.docx
- 文档编号:10873903
- 上传时间:2023-02-23
- 格式:DOCX
- 页数:24
- 大小:19.16KB
DS18B20设计程序.docx
《DS18B20设计程序.docx》由会员分享,可在线阅读,更多相关《DS18B20设计程序.docx(24页珍藏版)》请在冰豆网上搜索。
DS18B20设计程序
include
#include
#defineucharunsignedchar
#defineuintunsignedint
uchartplsb,tpmsb;
uinttemp,tempx;
sbitDQ=P2^0;
ucharcodetable[1]=".";
ucharcodetable1[10]="0123456789";
voiddelay(uintt);
bitlcd1602_busy(void);
voidlcd1602_wrcmd(unsignedcharlcdcmd);
voidlcd1602_wrdata(ucharlcddata);
voidlcd1602_clear(void);
voidlcd1602_init(void);
ucharkeyscan(void);
voidchuli(ucharkey);
ucharzhuan(ucharkey);
//数据口定义
#definelcd1602_busP3
//引脚定义
sbitrs_1602=P2^5;
sbitrw_1602=P2^6;
sbite_1602=P2^7;
/*延时t毫秒*/
voiddelay(uintt)
{
uinti;
while(t--)
{
/*对于11.0592M时钟,约延时1ms*/
for(i=0;i<125;i++)
{}
}
}
/***********忙判断标志,返回一个位BF********************/
bitlcd1602_busy(void)
{
ucharbusy_flag;
rs_1602=0;
rw_1602=1;
_nop_();
e_1602=1;
_nop_();
lcd1602_bus=0xff;
busy_flag=lcd1602_bus;//e在高电平时读
e_1602=0;
return(bit)(busy_flag&0x80);//BF=1;BUSY返回一个位
}
/********写命令,有两个参数,一个是要写的命令控制字,
第二个是用来控制是否进行忙标志的判断。
busyflag=1;
判断:
为0
***************/
voidlcd1602_wrcmd(unsignedcharlcdcmd)
{
while(lcd1602_busy());//等待空闲
lcd1602_bus=lcdcmd;
rs_1602=0;
rw_1602=0;
_nop_();
e_1602=1;
_nop_();
_nop_();
e_1602=0;//产生一个下沿
}
/***************向液晶写数据******************/
voidlcd1602_wrdata(ucharlcddata)
{
while(lcd1602_busy());//等待空闲
lcd1602_bus=lcddata;//在下沿的时候写数据
rs_1602=1;
rw_1602=0;
_nop_();
e_1602=1;
_nop_();
_nop_();
e_1602=0;
//lcd_bus=0xff;
}
/************液晶的清屏************/
voidlcd1602_clear(void)
{
lcd1602_wrcmd(0x01);//液晶清屏控制字并延时>40us
delay(100);
}
/***********1602液晶的初始化***************/
voidlcd1602_init(void)
{
lcd1602_wrcmd(0x38);//功能设置-----8位数据接口,两行显示,5*7点阵字符显示
delay(100);
lcd1602_wrcmd(0x0e);//显示开关控制----显示开关开,光标开关关,闪烁开关关
delay(100);
lcd1602_wrcmd(0x06);//输入方式设置,AC自增1,S=0;
delay(100);
lcd1602_wrcmd(0x01);//清屏
delay(100);
}
/*产生复位脉冲初始化DS18B20*/
voidTxReset(void)
{
uinti;
DQ=0;
/*拉低约900us*/
i=100;
while(i>0)i--;
DQ=1;//产生上升沿
i=4;
while(i>0)i--;
}
/*等待应答脉冲*/
voidRxWait(void)
{
uinti;
while(DQ);
while(~DQ);//检测到应答脉冲
i=4;
while(i>0)i--;
}
/*读取数据的一位,满足读时隙要求*/
bitRdBit(void)
{
uinti;
bitb;
DQ=0;
i++;
DQ=1;
i++;i++;//延时15us以上,读时隙下降沿后15us,DS18B20输出数据才有效
b=DQ;
i=8;
while(i>0)i--;
return(b);
}
/*读取数据的一个字节*/
ucharRdByte(void)
{
uchari,j,b;
b=0;
for(i=1;i<=8;i++)
{
j=RdBit();
b=(j<<7)|(b>>1);
}
return(b);
}
/*写数据的一个字节,满足写1和写0的时隙要求*/
voidWrByte(ucharb)
{
uinti;
ucharj;
bitbtmp;
for(j=1;j<=8;j++)
{
btmp=b&0x01;
b=b>>1;//取下一位(由低位向高位)
if(btmp)
{
/*写1*/
DQ=0;
i++;i++;//延时,使得15us以内拉高
DQ=1;
i=8;
while(i>0)i--;//整个写1时隙不低于60us
}
else
{
/*写0*/
DQ=0;
i=8;
while(i>0)i--;//保持低在60us到120us之间
DQ=1;
i++;
i++;
}
}
}
/*启动温度转换*/
voidconvert(void)
{
TxReset();//产生复位脉冲,初始化DS18B20
RxWait();//等待DS18B20给出应答脉冲
delay
(1);//延时
WrByte(0xcc);//skiprom命令
WrByte(0x44);//convertT命令
}
/*读取温度值*/
voidRdTemp(void)
{
TxReset();//产生复位脉冲,初始化DS18B20
RxWait();//等待DS18B20给出应答脉冲
delay
(1);//延时
WrByte(0xcc);//skiprom命令
WrByte(0xbe);//readscratchpad命令
tplsb=RdByte();//温度值低位字节(其中低4位为二进制的“小数”部分)
tpmsb=RdByte();//高位值高位字节(其中高5位为符号位)
}
/************键盘扫描*************/
ucharkeyscan(void)
{
ucharscancode,tmpcode;
P1=0xf0;
if((P1&0xf0)!
=0xf0)
{
delay(125);
if((P1&0xf0)!
=0xf0)
{
scancode=0xfe;
while((scancode&0x10)!
=0)
{
P1=scancode;
if((P1&0xf0)!
=0xf0)
{
tmpcode=(P1&0xf0)|0x0f;
return((~scancode)+(~tmpcode));
}
elsescancode=(scancode<<1)|0x01;
}
}
}
return(0);
}
voidgettemp()
{
delay
(1);//延时1ms
convert();//启动温度转换,需要750ms
delay(1000);//延时1s
RdTemp();
temp=(tpmsb&0x07)*16+((tplsb&0xf0)>>4);
tempx=tplsb&0x0f;
}
/*主程序,读取的温度值最终存放在tplsb和tpmsb变量中。
tplsb其中低4位为二进制的“小数”部分;tpmsb其中高
5位为符号位。
真正通过数码管输出时,需要进行到十进
制有符号实数(包括小数部分)的转换。
*/
voidmain(void)
{
ucharkey,a[2],b[4];
chari;
uintd;
delay
(2);
lcd1602_bus=0xff;
lcd1602_init();
lcd1602_clear();
while
(1)
{
gettemp();
a[1]=temp/10;
temp=temp%10;
a[0]=temp;
d=tempx*625;
b[0]=d/1000;
d=d%1000;
b[1]=d/100;
d=d%100;
b[2]=d/10;
d=d%10;
b[3]=d;
lcd1602_wrcmd(0x80);
for(i=1;i>=0;i--)
lcd1602_wrdata(table1[a[i]]);
lcd1602_wrdata(table[0]);
for(i=0;i<4;i++)
lcd1602_wrdata(table1[b[i]]);
}
}
新程序:
#include
#include
#defineuintunsignedint
#defineucharunsignedchar
#definelcd1602_busP1
Unsignedchardatanum[16]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x2b,0x2d,0x2a,0x2f,0x3e,0x20};
unsignedchardatahang[4][16];
unsignedchardataerror[16]="ERROR";
unsignedcharcodesm[16]={18,4,11,4,2,19,27,27,12,14,3,4,27,27,27,27};
unsignedcharcodema[16]={12,14,3,4,27,00,27,27,27,27,27,27,27,27,27,27};
unsignedcharcodekong[16]={27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27};
unsignedchardatat;
unsignedintdatajie;
unsignedcharcodeeng[27]={0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x20};
sbitrs_1602=P2^0;
sbitrw_1602=P2^1;
sbite_1602=P2^2;
/**********************************lcd1602******************************************/
/*********延时子程序**********/
voiddelay(uchardy)
{
while(--dy);
}
/***********忙判断标志,返回一个位BF********************/
bitlcd1602_busy(void)
{
ucharbusy_flag;
rs_1602=0;
rw_1602=1;
_nop_();
e_1602=1;
_nop_();
lcd1602_bus=0xff;
busy_flag=lcd1602_bus;//e在高电平时读
e_1602=0;
return(bit)(busy_flag&0x80);//BF=1;BUSY返回一个位
}
/********写命令,有两个参数,一个是要写的命令控制字,
第二个是用来控制是否进行忙标志的判断。
busyflag=1;
判断:
为0
***************/
voidlcd1602_wrcmd(unsignedcharlcdcmd)
{
while(lcd1602_busy());//等待空闲
lcd1602_bus=lcdcmd;
rs_1602=0;
rw_1602=0;
_nop_();
e_1602=1;
_nop_();
_nop_();
e_1602=0;//产生一个下沿
}
/***************向液晶写数据******************/
voidlcd1602_wrdata(ucharlcddata)
{
while(lcd1602_busy());//等待空闲
lcd1602_bus=lcddata;//在下沿的时候写数据
rs_1602=1;
rw_1602=0;
_nop_();
e_1602=1;
_nop_();
_nop_();
e_1602=0;
//lcd_bus=0xff;
}
/***********1602液晶的初始化***************/
voidlcd1602_init(void)
{
lcd1602_wrcmd(0x38);//功能设置-----8位数据接口,两行显示,5*7点阵字符显示
delay(100);
lcd1602_wrcmd(0x0c);//显示开关控制----显示开关开,光标开关关,闪烁开关关
delay(100);
lcd1602_wrcmd(0x06);//输入方式设置,AC自增1,S=0;
delay(100);
lcd1602_wrcmd(0x01);//清屏
delay(100);
}
/************矩阵键盘读键程序*******************/
//输入参数:
void
//输出参数:
unsignedchar键值
//程序设计思路:
扫描法读取键值(具体见书)
//
/**********4*4矩阵键盘****************/
/************
矩阵键盘按键值的分布,键值=行号x4+列号
列入3210
P1.0-----P1.1-----P1.2-----P1.3
行出3----P1.4C(F)1(E)4(d)7(c)功能(键值)
2----P1.50(b)2(A)5(9)8(8)
1----P1.6=(7)3(6)6(5)9(4)
0----P1.7+(3)_
(2)*
(1)/(0)
利用已有的按键程序
*************/
voidlcd1602_clear(void)
{
lcd1602_wrcmd(0x01);//液晶清屏控制字并延时>40us
delay(100);
}
unsignedcharkeytrans(unsignedchari)
{switch(i)
{
case4:
return9;break;
case5:
return6;break;
case6:
return3;break;
case8:
return8;break;
case9:
return5;break;
case10:
return2;break;
case11:
return0;break;
case12:
return7;break;
case13:
return4;break;
case14:
return1;break;
default:
t=1;
returni;
break;
}
}
unsignedchargetkey()
{
unsignedcharkeycode=0xff,temp,i;
P0=0x0f;
temp=P0&0x0f;
if(temp!
=0x0f)//判是否有键按下
{
//beep=0;
P0=0x7f;//自第0行开始扫描输出,自列读入键值
for(i=0;i<4;i++)
{
temp=P0&0x0f;
if(temp==0x07)//判断第0列是否有键按下
{
keycode=i*4;
break;
}
elseif(temp==0x0b)//判断第1列是否有键按下
{
keycode=i*4+1;
break;
}
elseif(temp==0x0d)//判断第2列是否有键按下
{
keycode=i*4+2;
break;
}
elseif(temp==0x0e)//判断第3列是否有键按下
{
keycode=i*4+3;
break;
}
P0=(P0>>1)|0x80;
}
while((P0&0x0f)!
=0x0f)//等待释放
{
P0=0x0f;
}
//beep=1;
}
returnkeycode;
}
/********程序执行结果***************/
//按键程序测试代码,数码管一开始没有显示,
//当有按键按下时,则数码管显示按键值
//
main()
{
unsignedcharkey;//定义按键返回参数的变量
unsignedchari,u,v,y,keypress=0;
unsignedcharoffset=0x80;
keypress=0;
delay
(2);
lcd1602_init();
t=0;
delay
(2);
lcd1602_wrcmd(offset+0x00);
for(i=0;i<16;i++)
{
lcd1602_wrdata(eng[sm[i]]);
}
key=getkey();
while(key==0xff)
{key=keytrans(getkey());}
if(key>=0&key<=15)
{if(key==0)
{
lcd1602_clear();
lcd1602_wrcmd(offset+0x00);
for(i=0;i<16;i++)
{
lcd1602_wrdata(eng[ma[i]]);
}
lcd1602_wrcmd(offset+0x40);
for(i=0;i<16;i++)
{
lcd1602_wrdata(eng[kong[i]]);
}
u=0;
while(key==0xff)
{key=keytrans(getkey());}
while(t!
=1){
keypress=keypress+1;
if(key>=0&key<=15)
{u=u*10+key;
for(i=1;i<=keypress;i++)
{hang[2][15-keypress-i+1]=hang[2][15-keypress-i+2];
}
}
lcd1602_wrcmd(offset+0x40);
for(i=0;i<16;i++)
{
lcd1602_wrdata(num[hang[2][i]]);
}
while(key==0xff)
{key=keytrans(getkey());}
}
for(i=1;i<=keypress;i++)
{hang[2][15-keypress-i+1]=hang[2][15-keypress-i+2];
}
switch(key)
{
case0:
hang[2][15]=13;break;
case1:
hang[2][15]=12;break;
case2:
hang[2][15]=11;break;
case3:
hang[2][15]=10;break;
}
keypress=keypress+1;
t=0;
y=key;
lcd1602_wrcmd(offset+0x40);
for(i=0;i<16;i++)
{
lcd1602_wrdata(num[hang[2][i]]);
}
while(key==0xff)
{key=keytrans(getkey());}
v=0;
while(t!
=1){
keypress=keypress+1;
if(key>=0&key<=15)
{v=v*10+key;
for(i=1;i<=keypress;i++)
{hang[2][15-keypress-i+1]=hang[2][15-keypress-i+2];
}
hang[2][15]=key;
}
lcd1602_wrcmd(offset+0x40);
for(i=0;i<16;i++)
{
lcd1602_wrdata(num[hang[2][i]]);
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- DS18B20 设计 程序