微控制器小白學習之路(三十二)---DS18B20數字溫度計(三)

weixin_33806914發表於2018-10-09

目標:目標: DS18B20數字溫度計(三)


  • 18b20開始轉換溫度

DS18B20 的典型溫度讀取過程為:復位→發 SKIP ROM 命令(0XCC)→發開始轉換命令( 0X44)→延時→復位→傳送 SKIP ROM 命令(0XCC)→發讀儲存器命令( 0XBE)→連續讀出兩個位元組資料(即溫度)→結束。

  • 我們把上面的過程分成了兩部分,並分別用函式表示

(1)復位→發 SKIP ROM 命令(0XCC)→發開始轉換命令( 0X44)→延時

復位→發 SKIP ROM 命令(0XCC)→發開始轉換命令( 0X44)→延時
void Ds18b20ReadTemp()  //傳送讀取溫度命令--轉換
{
    Ds18b20Init();  //18b20初始化
    delay_1ms(1);
    Ds18b20WriteByte(0xcc); //跳過ROM操作命令
    DS18b20WriteByte(0x44); //傳送讀取溫度的轉換命令
    //Delay1ms(100);    //等待轉換成功,而如果你是一直刷著的話,就不用這個延時了
}

(2)復位→傳送 SKIP ROM 命令(0XCC)→發讀儲存器命令( 0XBE)

復位→傳送 SKIP ROM 命令(0XCC)→發讀儲存器命令( 0XBE)→連續讀出兩個位元組資料(即溫度)→結束
void Ds18b20ReadTempCom()  //傳送讀取溫度命令--傳送讀取溫度指令
{
    Ds18b20Init();
    delay_1ms();
    Ds18b20WriteByte(0xcc);  //跳過ROM操作命令
    Ds18b20WriteByte(0xbe);  //傳送讀取溫度的讀取儲存器命令
}

  • 讀取溫度
int Ds18b20ReadTemp()   //讀取溫度
{
    int temp = 0;    //int型別佔2個位元組,共16位
    uchar tmh,tml;
    Ds18b20ReadTemp();    //先寫入轉換命令
    Ds18b20ReadTempCom();  //然後等待轉換完成後傳送讀取溫度命令
    tml = Ds18b20ReadByte();//先讀出低位元組
    tmh = Ds18b20ReadByte();//再讀出高位元組
    temp = tmh;
    temp <<= 8;   //相當於在低8位的溫度高8位向左移8位到正確位置
    temp |= tml;   //再把tml放到低8位儲存
    return temp;

}


main檔案:

/*
實現現象:下載程式後,在DS18B20溫度感測器介面處,按照絲印方向插好溫度感測器,數碼管就會顯示
            檢測的溫度值,
注意事項:將LED點陣模組的J1短接片短接到VCC端          
*/

#include "reg52.h"
#include "ds18b20.h"

typedef unsigned int u16;
typedef unsigned char u8;

sbit LSA = P3^0;
sbit LSB = P3^1;
sbit LSC = P3^3;

char num = 0;
u8 DisplayData[8];
u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};


void delay(u16 i)
{
    while(i--);
}

void datapros(int temp)
{
    float tp;
    if(temp<0){
        DisplayData[0] = 0x40;  //數碼管顯示一個‘-’來表示負號
        temp = temp-1;  //因為讀取的溫度是實際溫度的補碼,而又是負數所以原碼是補碼減1然後取反
        temp = ~temp;  //得到實際溫度
        tp = temp;
        temp = tp*0.0625*100+0.5;  //由於temp是整形所以當小數賦給temp時會把小數點後面的數字去掉,
                                //為了不讓小數部分去掉我們乘100把小數變成整數
    }
    else{
        DisplayData[0] = 0x00;
        tp = temp;
        temp = tp*0.0625*100+0.5;   
    }
    DisplayData[1] = smgduan[temp/10000];  //取出5位數的最高位
    DisplayData[2] = smgduan[temp%10000/1000];   //取出次高位
    DisplayData[3] = smgduan[temp%1000/100] | 0x80; //取出一位並加上個小數點
    DisplayData[4] = smgduan[temp%100/10];
    DisplayData[5] = smgduan[temp%10];     //最低位
}

void DigDisplay()
{
    u8 i;
    for(i=0;i<6;i++){
        switch(i)    //位選,選擇點亮的數碼管,
        {
            case(0):
                LSA=0;LSB=0;LSC=0; break;//顯示第0位
            case(1):
                LSA=1;LSB=0;LSC=0; break;//顯示第1位
            case(2):
                LSA=0;LSB=1;LSC=0; break;//顯示第2位
            case(3):
                LSA=1;LSB=1;LSC=0; break;//顯示第3位
            case(4):
                LSA=0;LSB=0;LSC=1; break;//顯示第4位
            case(5):
                LSA=1;LSB=0;LSC=1; break;//顯示第5位    
        }
        P0 = DisplayData[i];  //向數碼管傳送資料
        delay(100);//間隔一段時間掃描
        P0 = 0x00;
    }
}

void main()
{
    while(1){
        datapros(Ds18b20ReadTemp()); //資料處理函式
        DigDisplay();    //數碼管顯示函式
    }
}




標頭檔案:

#ifndef _ds18b20_H_
#define _ds18b20_H_

#include<reg52.h>
#include<intrins.h>

#ifndef uchar
#define uchar unsigned char
#endif

#ifndef uint 
#define uint unsigned int
#endif


sbit DSPORT = P3^7;

void delay_1ms(uint );
void delay_10tus(uint );
uchar Ds18b20Init();
void Ds18b20WriteByte(uchar );
uchar Ds18b20ReadByte();
void Ds18b20ChangeTemp();
void Ds18b20ReadTempCom();
int Ds18b20ReadTemp();

#endif

相關文章