要想成功讀取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)
2023-9-13 14:40 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|