要想成功读取DS18B20的温度,那么时序很重要,因为STC12C5A60是1T的单片机,跟STC89C52的延时是不一样的,所以在程序处理时,一定要特别注意延时是否正确,我在DS18B20身上研究了很久,一开始还以为是接线的问题或者是元件坏了,温度一直显示-0.006,后面查了很多资料才发现是时序不对,导致初始化不成功,如果看到我的帖子,希望对大家有所帮助- /*-----------------------------------------------
- 名称:18B20温度传感器
- ------------------------------------------------*/
- #include"delay.h"
- #include"18b20.h"
- #include"LCD1602.h"
- uchar fu;
- /*------------------------------------------------
- 端口定义
- ------------------------------------------------*/
- sbit DQ=P1^3;//ds18b20 端口
- sbit beep=P2^3;
- /*------------------------------------------------
- 18b20初始化
- ------------------------------------------------*/
- unsigned char ds18b20_init(void)
- {
- unsigned char presence;
- DQ = 1;
- delay_us(2);
- DQ = 0;
- delay_us(500);
- DQ = 1;
- delay_us(70);
- presence = DQ;
- delay_us(500);
- return presence;
- }
- /*------------------------------------------------
- 读一位
- ------------------------------------------------*/
- bit tmpreadbit(void)
- {
- unsigned char a;
- DQ = 0;
- delay_us(5);
- DQ = 1;
- delay_us(5);
- a = DQ;
- delay_us(50);
- return a;
- }
- /*------------------------------------------------
- 读一个字节
- ------------------------------------------------*/
- unsigned char ReadOneChar(void) //read a byte date
- {
- uchar i,j,dat;
- dat=0;
- for(i=1;i<=8;i++)
- {
- j=tmpreadbit();
- dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里
- }
- return(dat);
- }
- /*------------------------------------------------
- 写入一位
- ------------------------------------------------*/
- void ds18b20_writebit(unsigned char a)
- {
- DQ = 0;
- delay_us(10);
- DQ = a;
- delay_us(50);
- DQ = 1;
- }
- /*------------------------------------------------
- 写入一个字节
- ------------------------------------------------*/
- void WriteOneChar(unsigned char dat)
- {
- unsigned char j;
- bit testb;
- for(j=1;j<=8;j++)
- {
- testb=dat&0x01;
- dat=dat>>1;
- ds18b20_writebit(testb);
- }
- }
- void tmpchange(void) //DS18B20开始获取温度并转换
- {
- ds18b20_init();
- DelayMs(1);
- WriteOneChar(0xcc); // address all drivers on bus
- WriteOneChar(0x44); // initiates a single temperature conversion
- }
- /*------------------------------------------------
- 读取温度
- ------------------------------------------------*/
- unsigned int ReadTemperature(void)
- {
- unsigned char a,b;
- unsigned int g,c,d,e;
- ds18b20_init();
- DelayMs(1);
- WriteOneChar(0xCC); //跳过读序号列号的操作
- WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
- a=ReadOneChar(); //先读低位
- b=ReadOneChar(); //再读高位
- if(!(b&0x08))
- {
- fu=1;
- g=b;
- c=((g<<8)|a)*6.25;
- }
- else
- {
- fu=0;
- d=((b<<8)|a);
- e=((~d)+1);
- c=e*6.25;
- }
- return(c);
- }
- void warn(uint s,uchar led)//蜂鸣器报警和灯闪烁 s控制音调,led控制灯
- {
- uchar i;
- i=s;
- beep=0; //蜂鸣器响
- P1=~(led); //控制相应的灯亮
- while(i--)
- {
- distemperature();//用温度显示函数起到延时的作用
- }
- beep=1; //蜂鸣器不响
- P1=0xff; //控制相应的灯灭
- i=s;
- while(i--)
- {
- distemperature();//用温度显示函数起到延时的作用
- }
- }
- void deal(uint t) //温度区间报警
- {
- uchar i;
- if((t>2700)&&(t<=2500)) //大于25度小于27度
- {
- warn(40,0x01); //第一个灯亮,蜂鸣器发出"滴"声
- }
- else if(t<=2500) //小于25度
- {
- warn(10,0x03);//第一个和第二灯亮,蜂鸣器发出"滴"声
- }
- else if((t<3200)&&(t>=3000)) //小于32度大于30度
- {
- warn(40,0x04);//第三个灯亮,蜂鸣器发出"滴"声
- }
- else if(t>=3200)//大于32度
- {
- warn(10,0x0C);//第三个和第四个灯亮,蜂鸣器发出"滴"声
- }
- else //在27度和30度之间时只是调用显示函数延时
- {
- i=40;
- while(i--)
- {
- distemperature(); //用温度显示函数起到延时的作用
- }
- }
- }
- void distemperature(void)
- {
- unsigned int m1,m2,m3,m4,m5,temperature;
- tmpchange();
- temperature=ReadTemperature();//读取温度
- if(fu==0)
- {
- LCD_Write_Char(5,1,'-');//写入负号的位置,如果是负温度就显示
- }
- else
- {
- LCD_Write_Char(5,1,0x20);//是正温度就显示空格,0x20在ASCII字符表里表示空格
- }
- m1=temperature/10000+48; //1602字符显示ASCII的地址位0X30,0~9,对应的地址是48~57,所以计算出来的数要加48,48=0x30 /号是求整 %是求余
- m2=temperature%10000/1000+48;//为什么要除于10000呢,因为一开始温度换算的时就已经乘以100倍了,如果温度是110度,此时得出来的数就是11000,所以要除于10000
- m3=temperature%1000/100+48;
- m4=temperature%100/10+48;
- m5=temperature%10+48;
- LCD_Write_Char(6,1,m1);
- LCD_Write_Char(7,1,m2);
- LCD_Write_Char(8,1,m3);
- LCD_Write_Char(9,1,'.');
- LCD_Write_Char(10,1,m4);
- LCD_Write_Char(11,1,m5);
- }
复制代码 原理图: 无
仿真: 无
代码:
1602 18b20.zip
(58.15 KB, 下载次数: 50)
|