微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > STC15F2K60S2读取DS18B20温度串口显示代码

STC15F2K60S2读取DS18B20温度串口显示代码

时间:10-02 整理:3721RD 点击:


//**************************
//程序说明:stc15f2k60s2采集ds18b20温度数据,并从串口输出
//为方便大家调试,特附该程序的项目下载地址:
//采用的是22.1184M晶振
//**************************
#include<stc15fxxxx.h>        //调用stc15f系列头文件,下载地址:  
//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;                //允许全局中断
}

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);//读取温度寄存器
}
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);
}


Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top