历史上的今天
今天是:2024年09月02日(星期一)
2020年09月02日 | 实用的温度计(ds18b20)+Proteus仿真+C源程序
2020-09-02 来源:51hei




#include #include #include #include unsigned char code dispcode0[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f}; unsigned char dispcode1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed, 0xfd,0x87,0xff,0xef}; unsigned char TL; //储存暂存器的温度低位 unsigned char TH; //储存暂存器的温度高位 unsigned char TN; //储存温度的整数部分 unsigned int TD; //储存温度的小数部分 void delay1ms() { unsigned char i,j; for(i=0;i<10;i++) for(j=0;j<33;j++) ; } void delaynms(int n) { unsigned char i; for(i=0;i } sbit DQ=P1^0; unsigned char time_DS18B20; //设置全局变量,专门用于严格延时 bit Init_DS18B20(void) { bit flag_DS18B20; //储存DS18B20是否存在的标志,flag=0,表示存在;flag=1,表示不存在 DQ = 1; //先将数据线拉高 for(time_DS18B20=0;time_DS18B20<2;time_DS18B20++) //略微延时约6微秒 ; DQ = 0; //再将数据线从高拉低,要求保持480~960us for(time_DS18B20=0;time_DS18B20<200;time_DS18B20++) //略微延时约600微秒 ; //以向DS18B20发出一持续480~960us的低电平复位脉冲 DQ = 1; //释放数据线(将数据线拉高) for(time_DS18B20=0;time_DS18B20<10;time_DS18B20++) ; //延时约30us(释放总线后需等待15~60us让DS18B20输出存在脉冲) flag_DS18B20=DQ; //让单片机检测是否输出了存在脉冲(DQ=0表示存在) for(time_DS18B20=0;time_DS18B20<200;time_DS18B20++) //延时足够长时间,等待存在脉冲输出完毕 ; return (flag_DS18B20); //返回检测成功标志 } unsigned char ReadOneChar( ) { unsigned char i=0; unsigned char dat; //储存读出的一个字节数据 for (i=0;i<8;i++) { DQ =1; // 先将数据线拉高 _nop_(); //等待一个机器周期 DQ = 0; //单片机从DS18B20读书据时,将数据线从高拉低即启动读时序 dat>>=1; _nop_(); //等待一个机器周期 DQ = 1; //将数据线"人为"拉高,为单片机检测DS18B20的输出电平作准备 for(time_DS18B20=0;time_DS18B20<3;time_DS18B20++); //延时约6us,使主机在15us内采样 if(DQ==1) dat|=0x80; //如果读到的数据是1,则将1存入dat else dat|=0x00;//如果读到的数据是0,则将0存入dat //将单片机检测到的电平信号DQ存入r[i] for(time_DS18B20=0;time_DS18B20<8;time_DS18B20++) ; //延时3us,两个读时序之间必须有大于1us的恢复期 } return(dat); //返回读出的十进制数据 } WriteOneChar(unsigned char dat) { unsigned char i=0; for (i=0; i<8; i++) { DQ =1; // 先将数据线拉高 _nop_(); //等待一个机器周期 DQ=0; //将数据线从高拉低时即启动写时序 DQ=dat&0x01; //利用与运算取出要写的某位二进制数据, //并将其送到数据线上等待DS18B20采样 for(time_DS18B20=0;time_DS18B20<10;time_DS18B20++) ;//延时约30us,DS18B20在拉低后的约15~60us期间从数据线上采样 DQ=1; //释放数据线 for(time_DS18B20=0;time_DS18B20<1;time_DS18B20++) ;//延时3us,两个写时序间至少需要1us的恢复期 dat>>=1; //将dat中的各二进制位数据右移1位 } for(time_DS18B20=0;time_DS18B20<4;time_DS18B20++) ; //稍作延时,给硬件一点反应时间 } void display(unsigned char x,y) { unsigned char j,k,l,m,n,o; //j,k,l分别储存温度的百位、十位和个位 j=x/100; //取百位 k=(x%100)/10; //取十位 l=x%10; //取个位 m=y/100; n=(y%100)/10; o=y/10; if(x>=100) { P0=dispcode0[j]; P2=dispcode0[k]; if(o>=5) n+=1; else ; if(n>=5) m+=1; else ; if(m>=5) l+=1; else ; P3=dispcode0[l]; } else if((x>=10)&&(x<100)) { P0=dispcode0[k]; P2=dispcode1[l]; if(o>=5) n+=1; else ; if(n>=5) m+=1; else ; P3=dispcode0[m]; } else if((x>=0)&&(x<10)) { P0=dispcode1[l]; P2=dispcode0[m]; if(o>=5) n+=1; else ; P3=dispcode0[n]; } } void displayfu(unsigned char x,y) { unsigned char k,l,m,n,o; //j,k,l分别储存温度的百位、十位和个位 P0=0x40; k=(x%100)/10; //取十位 l=x%10; //取个位 m=y/100; n=(y%100)/10; o=y/10; if(x>=10) { P2=dispcode0[k]; if(o>=5) n+=1; else ; if(n>=5) m+=1; else ; if(m>=5) l+=1; else ; P3=dispcode0[l]; } else if(x<10) { P2=dispcode1[l]; if(o>=5) n+=1; else ; if(n>=5) m+=1; else ; P3=dispcode0[m]; } } void ReadyReadTemp(void) { Init_DS18B20(); //将DS18B20初始化 WriteOneChar(0xCC); // 跳过读序号列号的操作 WriteOneChar(0x44); // 启动温度转换
史海拾趣
|
最近在看别人写的驱动时总是遇到一些C语言用法,句子符号能看懂,但实际的意思不明白,如下语句: // LCD_PWREN(GPG4) s2440IOP->GPGCON &= ~(3 GPGCON |= (1 GPGDAT |= (1 GPBCON = (s2440IOP->GPBCON & ~(3… 查看全部问答> |
|
在CE下电源管理 MDD层代码中: 电池驱动对外接口函数没有“BAT_”前缀,因为HKEY_LOCAL_MACHINE\\Drivers\\BuiltIn\\Battery\\Flags注册表项设置了DEVFLAGS_NAKEDENTRIES属性,表示“Init”代替“BAT_Init”,这样修改注册表“Prefix ...… 查看全部问答> |
|
转载时请注明出处和作者联系方式 文章出处:http://www.limodev.cn/blog 作者联系方式:李先静 习惯了automake之后,再用Android的编译系统,就是感觉不爽。编译一个小模块也等上几分钟,有次实在受不了,看了一下它的实现,发现它对任何一次编 ...… 查看全部问答> |




