STC15系列讀取DS18B20溫度傳感器串口顯示代碼

STC15系列讀取DS18B20溫度傳感器串口顯示代碼
調試通過,複製粘貼即編譯可使用,無需調試,晶振:22.1184M,串口輸出,波特率:115200
爲方便大家調試,特附該程序的項目文件,下載打開即可調試,下載地址:
http://download.csdn.net/detail/liyu3519/9873187
stc15系列都可以直接用

//**************************
//程序說明:stc15系列採集ds18b20溫度數據,並從串口輸出
//採用的是22.1184M晶振,用傳感器中間那個腳連接單片機的P2.0口
//**************************

#include<stc15fxxxx.h>  //調用stc15f系列頭文件,下載地址:  http://pan.baidu.com/s/1eRUbjLS

//IO口聲明

#define ds18b20_io P20   //P2.0口作爲數據讀取接口

//常量聲明
#define MAIN_Fosc       22118400L       //主時鐘
#define baud_rate       115200L         //波特率
#define Timer1_Reload   (65536UL -(MAIN_Fosc / 4 / baud_rate))      //Timer1重裝值

//變量定義

u16 datas=0;//測試用


//函數聲明

void  Delay3us();                                   //22.1184M晶振精確延時30微秒
void  Delay6us();                                   //22.1184M晶振精確延時30微秒
void  Delay24us();                              //22.1184M晶振精確延時40微秒
void  Delay30us();                              //22.1184M晶振精確延時40微秒
void  Delay300us();                             //22.1184M晶振精確延時40微秒
void  Delay600us();                             //22.1184M晶振精確延時30毫秒
void    Delay1000ms();                          //22.1184M晶振精確延時1000毫秒

bit  ds18b20_init();                                //初始化ds18b20
u8   ds18b20_read_one_char();               //從ds18b20讀取一個字節
void ds18b20_write_one_char(u8 dat);//向ds18b20寫入一個字節
void ds18b20_ready_read_temp();         //準備讀取數據
u16  ds18b20_read_temp_val();               //讀取數據,返回溫度值,返回實際值的100倍,且萬位爲符號位,例:12556爲-25.56度,2556爲25.56度

void    serial_init();                          //串口初始化
void    serial_send_byte(u8 dat);       //串口發送一個字節的數據
void    serial_send_string(u8 *dat);//串口發送字符串

//主函數
void main()
{
    Delay1000ms();
    serial_init();//串口初始化
    ds18b20_io = 1;
    while(1)
    {
        datas=ds18b20_read_temp_val();
        serial_send_string("溫度: ");
        if(datas/10000 == 1)                                            //如果萬位爲1,則表示溫度爲負
            serial_send_byte('-');                                  //輸出負號
        serial_send_byte(datas%10000/1000+'0');     //十位
        serial_send_byte(datas%1000/100+'0');         //個位
        serial_send_byte('.');
        serial_send_byte(datas%100/10+'0');         //小數點後第一位
        serial_send_byte(datas%10+'0');                 //小數點後第二位
        serial_send_string("℃\r\n");
        Delay1000ms();
    }
}

//串口初始化
void serial_init()
{
    S1_8bit();              //8位數據
    S1_USE_P30P31();        //UART1 使用P30 P31口  默認
    TR1 = 0;
    AUXR &= ~0x01;     //S1 BRT Use Timer1;
    TMOD &= ~(1<<6);   //Timer1 set As Timer
    TMOD &= ~0x30;     //Timer1_16bitAutoReload;2
    AUXR |=  (1<<6);    //Timer1 set as 1T mode
    TH1 = (u8)(Timer1_Reload >> 8);
    TL1 = (u8)Timer1_Reload;
    TR1  = 1;
    PS = 1; //高優先級中斷
    REN = 1;    //允許接收
    ES  = 1;    //允許中斷

    EA = 1;     //允許全局中斷
}


//ds18b20初始化
bit ds18b20_init()
{
    u8 init_success_tag=0;
    ds18b20_io=1;//拉高
    Delay6us();//6us
    ds18b20_io=0;//拉低
    Delay600us();//600us
    ds18b20_io=1;//拉高
    Delay30us();//30us
    init_success_tag=ds18b20_io;
    Delay600us();//600us
    return init_success_tag;
}

//讀取一個字節
u8 ds18b20_read_one_char()
{
    u8 i=0;
    u8 dat=0;
    for(i=0;i<8;i++)
    {
        ds18b20_io=1;//拉高
        NOP1();
        ds18b20_io=0;//拉低
        dat>>=1;
        NOP1();
        ds18b20_io=1;//拉高
        Delay6us();//6us
        if(ds18b20_io==1)
            dat|=0x80;
        else
            dat|=0x00;
        Delay24us();//24us
    }
    return (dat);
}

//向傳感器寫入一個字節
void ds18b20_write_one_char(u8 dat)
{
    u8 i=0;
    for(i=0;i<8;i++)
    {
        ds18b20_io=1;//拉高
        NOP1();
        ds18b20_io=0;//拉低
        ds18b20_io=dat&0x01;
        Delay30us();//30us
        ds18b20_io=1;//拉高
        Delay3us();//3us
        dat>>=1;
    }
    Delay6us();
    Delay6us();//12us
}

//準備讀取一個溫度值
void ds18b20_ready_read_temp()
{
    ds18b20_init();                          //初始化
    ds18b20_write_one_char(0xcc);//忽略讀序列號
    ds18b20_write_one_char(0x44);//啓動溫度轉換
    Delay300us();                                   //300us,等待轉換完畢
    ds18b20_init();                          //初始化
    ds18b20_write_one_char(0xcc);//忽略讀序列號
    ds18b20_write_one_char(0xbe);//讀取溫度寄存器
}

//讀取數據,返回溫度值,返回實際值的100倍,且萬位爲符號位,例:12556
u16 ds18b20_read_temp_val()
{
    u16 temp_16_bit=0;
    u8  temp_L=0;
    u8  temp_H=0;
    ds18b20_ready_read_temp();
    temp_L=ds18b20_read_one_char();//讀取溫度低八位
    temp_H=ds18b20_read_one_char();//讀取溫度高八位
    if(temp_H>0x7f)
    {
        temp_L=~temp_L;                    //補碼轉換,取反加一
        temp_H=~temp_H+1;  
        temp_16_bit=100;
    }
    temp_16_bit=temp_16_bit+temp_H*16+temp_L/16;
    temp_16_bit=temp_16_bit*100;
    temp_16_bit=temp_16_bit+((temp_L&0x0f)*10/16)*10;
    temp_16_bit=temp_16_bit+(temp_L&0x0f)*100/16%10;
    return (u16)(temp_16_bit);
}

//串口發送一個字節數據
void serial_send_byte(u8 dat)
{
    SBUF=dat;
    while(!TI);
    TI=0;
}

//串口發送一串字符串
void serial_send_string(u8 *dat)
{
    while(*dat)
    {
        serial_send_byte(*dat++);
    }
}

/********************* 串口1中斷函數************************/
void UART1_int (void) interrupt UART1_VECTOR
{
    if(RI)
    {
        RI = 0;
    }

    if(TI)
    {
    }
}

void Delay3us()     //@22.1184MHz
{
    unsigned char i;

    i = 14;
    while (--i);
}

void Delay6us()     //@22.1184MHz
{
    unsigned char i;

    _nop_();
    _nop_();
    _nop_();
    i = 30;
    while (--i);
}

void Delay24us()        //@22.1184MHz
{
    unsigned char i, j;

    _nop_();
    _nop_();
    _nop_();
    i = 1;
    j = 128;
    do
    {
        while (--j);
    } while (--i);
}

void Delay30us()        //@22.1184MHz
{
    unsigned char i, j;

    i = 1;
    j = 162;
    do
    {
        while (--j);
    } while (--i);
}

void Delay300us()       //@22.1184MHz
{
    unsigned char i, j;

    i = 7;
    j = 113;
    do
    {
        while (--j);
    } while (--i);
}

void Delay600us()       //@22.1184MHz
{
    unsigned char i, j;

    _nop_();
    _nop_();
    _nop_();
    i = 13;
    j = 229;
    do
    {
        while (--j);
    } while (--i);
}

void Delay1000ms()      //@22.1184MHz
{
    unsigned char i, j, k;

    _nop_();
    _nop_();
    i = 85;
    j = 12;
    k = 155;
    do
    {
        do
        {
            while (--k);
        } while (--j);
    } while (--i);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章