DS18B20溫度讀取練習(xí)

課程/原代碼來(lái)自u(píng)p主:江科大自化協(xié)
代碼為課后練習(xí)

延時(shí)模塊

#ifndef __DELAY_H__
#define __DELAY_H__

void Delay(unsigned int xms);

#endif
#include <REGX52.H>
void Delay(unsigned int xms)
{
    unsigned char i, j;
    while(xms--)
    {
        i = 2;
        j = 239;
        do
        {
            while (--j);
        } while (--i);
    }
}

LCD1602模塊

#ifndef __LCD1602_H__
#define __LCD1602_H__

//用戶調(diào)用函數(shù):
void LCD_Init();
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char);
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String);
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length);
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);

#endif

#include <REGX52.H>

//引腳配置:
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0

//函數(shù)定義:
/**
  * @brief  LCD1602延時(shí)函數(shù),12MHz調(diào)用可延時(shí)1ms
  * @param  無(wú)
  * @retval 無(wú)
  */
void LCD_Delay()
{
    unsigned char i, j;

    i = 2;
    j = 239;
    do
    {
        while (--j);
    } while (--i);
}

/**
  * @brief  LCD1602寫(xiě)命令
  * @param  Command 要寫(xiě)入的命令
  * @retval 無(wú)
  */
void LCD_WriteCommand(unsigned char Command)
{
    LCD_RS=0;
    LCD_RW=0;
    LCD_DataPort=Command;
    LCD_EN=1;
    LCD_Delay();
    LCD_EN=0;
    LCD_Delay();
}

/**
  * @brief  LCD1602寫(xiě)數(shù)據(jù)
  * @param  Data 要寫(xiě)入的數(shù)據(jù)
  * @retval 無(wú)
  */
void LCD_WriteData(unsigned char Data)
{
    LCD_RS=1;
    LCD_RW=0;
    LCD_DataPort=Data;
    LCD_EN=1;
    LCD_Delay();
    LCD_EN=0;
    LCD_Delay();
}

/**
  * @brief  LCD1602設(shè)置光標(biāo)位置
  * @param  Line 行位置,范圍:1~2
  * @param  Column 列位置,范圍:1~16
  * @retval 無(wú)
  */
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
    if(Line==1)
    {
        LCD_WriteCommand(0x80|(Column-1));
    }
    else if(Line==2)
    {
        LCD_WriteCommand(0x80|(Column-1+0x40));
    }
}

/**
  * @brief  LCD1602初始化函數(shù)
  * @param  無(wú)
  * @retval 無(wú)
  */
void LCD_Init()
{
    LCD_WriteCommand(0x38);//八位數(shù)據(jù)接口,兩行顯示,5*7點(diǎn)陣
    LCD_WriteCommand(0x0c);//顯示開(kāi),光標(biāo)關(guān),閃爍關(guān)
    LCD_WriteCommand(0x06);//數(shù)據(jù)讀寫(xiě)操作后,光標(biāo)自動(dòng)加一,畫(huà)面不動(dòng)
    LCD_WriteCommand(0x01);//光標(biāo)復(fù)位,清屏
}

/**
  * @brief  在LCD1602指定位置上顯示一個(gè)字符
  * @param  Line 行位置,范圍:1~2
  * @param  Column 列位置,范圍:1~16
  * @param  Char 要顯示的字符
  * @retval 無(wú)
  */
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{
    LCD_SetCursor(Line,Column);
    LCD_WriteData(Char);
}

/**
  * @brief  在LCD1602指定位置開(kāi)始顯示所給字符串
  * @param  Line 起始行位置,范圍:1~2
  * @param  Column 起始列位置,范圍:1~16
  * @param  String 要顯示的字符串
  * @retval 無(wú)
  */
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{
    unsigned char i;
    LCD_SetCursor(Line,Column);
    for(i=0;String[i]!='\0';i++)
    {
        LCD_WriteData(String[i]);
    }
}

/**
  * @brief  返回值=X的Y次方
  */
int LCD_Pow(int X,int Y)
{
    unsigned char i;
    int Result=1;
    for(i=0;i<Y;i++)
    {
        Result*=X;
    }
    return Result;
}

/**
  * @brief  在LCD1602指定位置開(kāi)始顯示所給數(shù)字
  * @param  Line 起始行位置,范圍:1~2
  * @param  Column 起始列位置,范圍:1~16
  * @param  Number 要顯示的數(shù)字,范圍:0~65535
  * @param  Length 要顯示數(shù)字的長(zhǎng)度,范圍:1~5
  * @retval 無(wú)
  */
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
    unsigned char i;
    LCD_SetCursor(Line,Column);
    for(i=Length;i>0;i--)
    {
        LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
    }
}

/**
  * @brief  在LCD1602指定位置開(kāi)始以有符號(hào)十進(jìn)制顯示所給數(shù)字
  * @param  Line 起始行位置,范圍:1~2
  * @param  Column 起始列位置,范圍:1~16
  * @param  Number 要顯示的數(shù)字,范圍:-32768~32767
  * @param  Length 要顯示數(shù)字的長(zhǎng)度,范圍:1~5
  * @retval 無(wú)
  */
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{
    unsigned char i;
    unsigned int Number1;
    LCD_SetCursor(Line,Column);
    if(Number>=0)
    {
        LCD_WriteData('+');
        Number1=Number;
    }
    else
    {
        LCD_WriteData('-');
        Number1=-Number;
    }
    for(i=Length;i>0;i--)
    {
        LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');
    }
}

/**
  * @brief  在LCD1602指定位置開(kāi)始以十六進(jìn)制顯示所給數(shù)字
  * @param  Line 起始行位置,范圍:1~2
  * @param  Column 起始列位置,范圍:1~16
  * @param  Number 要顯示的數(shù)字,范圍:0~0xFFFF
  * @param  Length 要顯示數(shù)字的長(zhǎng)度,范圍:1~4
  * @retval 無(wú)
  */
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
    unsigned char i,SingleNumber;
    LCD_SetCursor(Line,Column);
    for(i=Length;i>0;i--)
    {
        SingleNumber=Number/LCD_Pow(16,i-1)%16;
        if(SingleNumber<10)
        {
            LCD_WriteData(SingleNumber+'0');
        }
        else
        {
            LCD_WriteData(SingleNumber-10+'A');
        }
    }
}

/**
  * @brief  在LCD1602指定位置開(kāi)始以二進(jìn)制顯示所給數(shù)字
  * @param  Line 起始行位置,范圍:1~2
  * @param  Column 起始列位置,范圍:1~16
  * @param  Number 要顯示的數(shù)字,范圍:0~1111 1111 1111 1111
  * @param  Length 要顯示數(shù)字的長(zhǎng)度,范圍:1~16
  * @retval 無(wú)
  */
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
    unsigned char i;
    LCD_SetCursor(Line,Column);
    for(i=Length;i>0;i--)
    {
        LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');
    }
}

單總線配置

#ifndef __OneWire_H__
#define __OneWire_H__

unsigned char OneWire_Init(void);
void OneWire_SendBit(unsigned char Bit);
unsigned char OneWire_ReceiveBit(void);
void OneWire_SendByte(unsigned char Byte);
unsigned char OneWire_ReceiveByte(void);

#endif

#include <REGX52.H>

sbit OneWire_DQ=P3^7;

unsigned char OneWire_Init(void)
{
    unsigned char i;
    unsigned char AckBit;
    OneWire_DQ=1;
    OneWire_DQ=0;
    i = 247;while (--i);  //延遲至少480us
    OneWire_DQ=1;
    i = 32;while (--i);   //延遲70us
    AckBit=OneWire_DQ;
    i = 247;while (--i);  //延遲至少480us
    return(AckBit);
}

void OneWire_SendBit(unsigned char Bit)
{
    unsigned char i;
    OneWire_DQ=0;
    i = 4;while (--i);  //延遲10us
    OneWire_DQ=Bit;
    i = 24;while (--i); //延遲50us
    OneWire_DQ=1;
}

unsigned char OneWire_ReceiveBit(void)
{
    unsigned char i;
    unsigned char Bit;
    OneWire_DQ=0;
    i = 2;while (--i);  //延遲5us
    OneWire_DQ=1;
    i = 2;while (--i);  //延遲5us
    Bit=OneWire_DQ;
    i = 24;while (--i); //延遲50us
    return Bit;
}

void OneWire_SendByte(unsigned char Byte)
{
    unsigned char i;
    for(i=0;i<8;i++)
    {
            OneWire_SendBit(Byte&(0x01<<i));
    }
}

unsigned char OneWire_ReceiveByte(void)
{
        unsigned char i;
        unsigned char Byte=0x00;
        for(i=0;i<8;i++)
    {
      if(OneWire_ReceiveBit()){Byte|=(0x01<<i);}
    }
        return Byte;
}

溫度傳感器模塊配置

#ifndef __DS18B20_H__
#define __DS18B20_H__

void DS18B20_ConvertT(void);
float DS18B20_ReadT(void);

#endif

#include <REGX52.H>
#include "OneWire.h"

#define DS18B20_SKIP_ROM                0xCC
#define DS18B20_CONVERT_T           0x44
#define DS18B20_READ_SCRATCHPAD 0xBE

void DS18B20_ConvertT(void)
{
        OneWire_Init();
        OneWire_SendByte(DS18B20_SKIP_ROM);
        OneWire_SendByte(DS18B20_CONVERT_T);
}

float DS18B20_ReadT(void)
{
        unsigned char TLSB,TMSB;
        int Temp;
        float T;
        OneWire_Init();
        OneWire_SendByte(DS18B20_SKIP_ROM);
        OneWire_SendByte(DS18B20_READ_SCRATCHPAD);
        TLSB=OneWire_ReceiveByte();
        TMSB=OneWire_ReceiveByte();
        Temp=(TMSB<<8)|TLSB;  //????ààDí×a??£?°?TMSBoíTLSBo?2¢
        T=Temp/16.0;
        return T;
}

主函數(shù)

#include <REGX52.H>
#include "LCD1602.h"
#include "DS18B20.h"
#include "Delay.h"


float T;

void main()
{
        LCD_Init(); 
        LCD_ShowString(1,1,"Temperature:");
        while (1)
        {
                DS18B20_ConvertT();     //?a??×a??
                Delay(1000);                    //μè′yò???ê±??
                T=DS18B20_ReadT();
                if(T<0)
                {
                        LCD_ShowChar(2,1,'-');
                        T=-T;
                }
                else
                {
                        LCD_ShowChar(2,1,'+');
                }
                LCD_ShowNum(2,2,T,3);
                LCD_ShowChar(2,5,'.');
                LCD_ShowNum(2,6,(unsigned long)(T*10000)%10000,4);
            }
}

實(shí)際效果:測(cè)試宿舍空調(diào)

宿舍空調(diào).jpg

可見(jiàn)宿舍空調(diào)還是很給力的w

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容