打印
[经验分享]

DS18B20的应用

[复制链接]
83|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tpgf|  楼主 | 2025-4-12 13:52 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
一、Onewire初始化代码
加载“Onewire.c”文件,主函数中添加“Onewire.h”头文件;
调节软件延迟时长(全部扩大10倍即可){解释:蓝桥杯给的资料是89C52的代码,由于开发板使用的是stc15系列,所以扩大十倍}
编写温度数据获取函数,并且在头文件中定义;
编写用户功能函数;
二、注意:多个.c文件的使用
不管有多少个函数,C总是从main()主函数开始执行。
一个工程里面包括多个.c的文件,其实每个.c的文件里就是一系列函数而已。
一般更多的.C文件,要配合其.H文件来使用,变量的定义,函数的定义均放置在头文件中
如果要使用这些函数,要在头文件里加入#include“XXX.h”
三、DS18B20的驱动函数
(1)init_ds18b20



(2)Write_DS18B20​​​​​​​



(3)Read_DS18B20



四、DS18B20温度读取函数
bit Temper_Flag = 0 ;
unsigned int Temp;

unsigned long Temp_get(void)
{
        unsigned char low,high;
       
        if(Temper_Flag == 0 )
        {
                Temper_Flag = 1 ;
                init_ds18b20();
                Write_DS18B20(0XCC);
                Write_DS18B20(0X44);               
        }
        else if( Temper_Flag == 1 )
        {
                Temper_Flag = 0 ;
                init_ds18b20();//启动总线
                Write_DS18B20(0XCC);//发送跳过ROM指令
                Write_DS18B20(0XBE);//发送读暂存器指令
               
                low=Read_DS18B20();//读暂存器的低8位
                high=Read_DS18B20();        //读暂存器的高8位
                Temp=high&0X0F;  // SSSS  XXXX  高4位清零(符号位)
                Temp <<= 8;                        //        Temp =Temp << 8;高8位向左移8位
                Temp |= low;                         // Temp =Temp | low;存储低8位       
//       
        }
        return Temp;
}

五、功能实现(代码)
(1)<onewire.h>
#ifndef __ONEWIRE_H
#define __ONEWIRE_H

unsigned long Temp_get(void);

#endif
(2)<onewire.c>
#include <STC15F2K60S2.H>
#include <intrins.h>


sbit DQ = P1^4;  //单总线接口

void Delay1us(unsigned int us)                //@11.0592MHz
{
        unsigned int i=0;
        for(i=0;i<us;i++)
        {
                _nop_();        _nop_();        _nop_();               
        }
}

//DS18B20设备初始化
bit init_ds18b20(void)
{
        bit init_flag = 1;
       
        DQ =1 ;
        Delay1us(10);
        DQ =0 ;
        Delay1us(600);
        DQ =1 ;
        Delay1us(70);
        init_flag = DQ ;
        Delay1us(200);
       
        return init_flag;
}

//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
        unsigned char i=0;
       
        for(i=0;i<8;i++)
        {
                DQ = 0;
                Delay1us(2);
                DQ = (dat & 0x01); // 1100 1100 & 0000 0001 = 0000 0000
                Delay1us(60);
                dat >>=1;
                DQ = 1;
                Delay1us(1);
        }
        Delay1us(50);
}

//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
        unsigned char dat;
        unsigned char i=0;
       
        for(i=0;i<8;i++)
        {
                DQ = 0;
                Delay1us(2);
                dat >>=1;
                DQ = 1;
                Delay1us(5);
                if(DQ==1)
                {
                        dat |= 0x80;  //0000 0000 | 1000 0000 = 1000 0000   
                }
                Delay1us(55);
        }
        DQ = 1;
        Delay1us(10);
        return dat;
}

//unsigned long Temp_get(void)
//{
//        unsigned char low,high;
//        unsigned int Temp;
//       
//        init_ds18b20();                               
//        Write_DS18B20(0XCC);        //发送跳过ROM指令
//        Write_DS18B20(0X44);        //发送启动温度转换指令
//        Delay1us(200);                //延迟
//       
//        init_ds18b20();                                //启动总线
//        Write_DS18B20(0XCC);       
//        Write_DS18B20(0XBE);       
//       
//        low=Read_DS18B20();               
//        high=Read_DS18B20();       
//       
//        Temp=high&0X0F;                          // SSSS  XXXX   
//        Temp <<= 8;                                                //        Temp =Temp << 8;
//        Temp |= low;                                         // Temp =Temp | low;
//        return Temp;
//}

bit Temper_Flag = 0 ;
unsigned int Temp;

unsigned long Temp_get(void)
{
        unsigned char low,high;
       
        if(Temper_Flag == 0 )
        {
                Temper_Flag = 1 ;
                init_ds18b20();
                Write_DS18B20(0XCC);
                Write_DS18B20(0X44);               
        }
        else if( Temper_Flag == 1 )
        {
                Temper_Flag = 0 ;
                init_ds18b20();//启动总线
                Write_DS18B20(0XCC);//发送跳过ROM指令
                Write_DS18B20(0XBE);//发送读暂存器指令
               
                low=Read_DS18B20();//读暂存器的低8位
                high=Read_DS18B20();        //读暂存器的高8位
                Temp=high&0X0F;  // SSSS  XXXX  高4位清零(符号位)
                Temp <<= 8;                        //        Temp =Temp << 8;高8位向左移8位
                Temp |= low;                         // Temp =Temp | low;存储低8位       
//       
        }
        return Temp;
}

(3)main.c
#include <STC15F2K60S2.H>
#include <intrins.h>
#include<onewire.h>

unsigned char Key_Value = 0;

unsigned char tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,\
                                                                                 0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10,\
                                                                                 0XBF,0XFF};
unsigned char DigCom=0;
unsigned char DigBuf[8] = {20,20,20,20,20,20,20,20};

unsigned char LED_Bit=0XFF;
unsigned char Actuator_Bit=0X00;

#define LEDx_ON(n)         { LED_Bit&=_crol_(0XFE,n-1); P0=LED_Bit; P2|=0X80;        P2&=0X9F;        P2&=0X1F;}
#define LEDx_OFF(n) { LED_Bit|=_crol_(0X01,n-1); P0=LED_Bit; P2|=0X80;        P2&=0X9F;        P2&=0X1F;}

#define Buzzer_ON         Actuator_Bit|=0x40; P0=Actuator_Bit;        P2|=0XA0;        P2&=0XBF; P2&=0X1F;               
#define Buzzer_OFF         Actuator_Bit&=0XBF; P0=Actuator_Bit;        P2|=0XA0;        P2&=0XBF;        P2&=0X1F;
#define Relay_ON                 Actuator_Bit|=0x10; P0=Actuator_Bit;        P2|=0XA0;        P2&=0XBF;        P2&=0X1F;
#define Relay_OFF         Actuator_Bit&=0XEF; P0=Actuator_Bit;        P2|=0XA0;        P2&=0XBF;        P2&=0X1F;

unsigned char LED = 1 ;
unsigned int LED_tt =0;
bit LED_Ref = 0 ;

unsigned int SEG_tt =0;                //定义一个数码管计数时间标识位
bit SEG_Ref = 0 ;                                        //定义一个数码管刷新标识位
bit SEG_Run = 0 ;                                        //定义一个控制数码管运行标识位
unsigned int Num = 999 ;

unsigned int Temp_tt =0;                //定义一个温度传感刷新及时变量
bit Temp_Ref =0;                                                //定义一个温度传感刷新标志位
unsigned int Temper = 0 ;                //定义一个存储温度数据的变量(16位)
unsigned char Temp_Vaue = 0 ;                        //定义一个只存储温度整数数据的变量
unsigned long Temp_DotValue = 0 ;        //定义一个计算温度带小数位的变量


void All_Init(void);
void Delay_MS(unsigned int ms);
void Key_Scan(void);
void Timer0Init(void);                //1毫秒@11.0592MHz

void main(void)
{
        All_Init();
        Timer0Init();
        EA=1;ET0=1;
       
        while(1)
        {
                                if(Temp_Ref==1)
                {
                        Temp_Ref=0;       
//                        Temp_Vaue=Temp_get()>>4;
//                        DigBuf[0]=21;DigBuf[1]=21;DigBuf[2]=21;DigBuf[3]=21;DigBuf[4]=21;
//                        DigBuf[5]=21;DigBuf[6]=Temp_Vaue/10;DigBuf[7]=Temp_Vaue%10;       
                                Temp_DotValue = Temp_get()*625; //扩大一万倍
                       
                        DigBuf[0]=21;DigBuf[1]=21;
                        DigBuf[2]=Temp_DotValue/100000;
                        DigBuf[3]=Temp_DotValue%100000/10000+10;// 显示带小数点的码值
                        DigBuf[4]=Temp_DotValue%10000/1000;
                        DigBuf[5]=Temp_DotValue%1000/100;
                        DigBuf[6]=Temp_DotValue%100/10;
                        DigBuf[7]=Temp_DotValue%10;                                       
                }
               
                Key_Scan();
                if(Key_Value==7){Key_Value=0;SEG_Run = 1 ;}
                if(Key_Value==6){Key_Value=0;SEG_Run = 0 ;}
                if(Key_Value==5){Key_Value=0;LEDx_ON(1);Buzzer_ON;}
                if(Key_Value==4){Key_Value=0;LEDx_OFF(1);Buzzer_OFF;}
               
               
        }
       
}

void All_Init(void)
{
        P0 = 0X00;//先设置关闭蜂鸣器继电器的P0输出值(全关)
        P2 |=0XA0;// 1010 0000 将P27 P25 设置为1 其他位保持不变
        P2 &=0XBF;// 1011 1111将P26设置为0 其他位保持不变
        P2 &=0X1F;// 0001 1111关闭所有的74HC573锁存器
       
        P0 = 0XFF;//1111 1111 先设置关闭所有的LED的P0输出值(全关)
        P2 |=0X80;//1000 0000 将P27设置为1 其他位保持不变
        P2 &=0X9F;//1001 1111 将P26 P25设置为0 其他位保持不变
        P2 &=0X1F;//0001 1111 关闭所有的74HC573锁存器
       
        P0 = 0X00;//1111 1111 //先设置选择数码管位选的P0输出值(全不选)
        P2 |=0XC0;//1100 0000 将P27设置为1 其他位保持不变
        P2 &=0XDF;//1101 1111 将P26 P25设置为0 其他位保持不变
        P2 &=0X1F;// 0001 1111 关闭所有的74HC573锁存器
       
}
void Delay_MS(unsigned int ms)                //@11.0592MHz
{
        unsigned char i, j;

        while(ms--)
        {
        _nop_();
        i = 2;
        j = 199;
        do
        {
                while (--j);
        } while (--i);
}
}


void Key_Scan(void)
{
        if(P30 == 0)
        {
                Delay_MS(10);
                if(P30 == 0)  Key_Value=7;
                while(!P30);
        }
       
                if(P31 == 0)
        {
                Delay_MS(10);
                if(P31 == 0)  Key_Value=6;
                while(!P31);
        }
                if(P32 == 0)
        {
                Delay_MS(10);
                if(P32 == 0)  Key_Value=5;
                while(!P32);
        }
                if(P33 == 0)
        {
                Delay_MS(10);
                if(P33 == 0)  Key_Value=4;
                while(!P33);
        }
               
       
}

void Timer0(void) interrupt 1
{
        P0 = 0X00;
        P2 |=0XC0;  // P2=P2|0XC0;   XXXX XXXX | 1100 0000 = 11XX XXXX
        P2 &=0XDF;         // P2=P2&0XDF;   11XX XXXX & 1101 1111 = 110X XXXX       
        P2 &=0X1F;                //关闭所有的74HC573锁存器       
       
        P0=tab[DigBuf[DigCom]];       
        P2 |=0XE0;                        //        P2=P2|0XE0;   XXXX XXXX | 1110 0000 = 111X XXXX
        P2 &=0XFF;                         // P2=P2&0XDF;   11XX XXXX & 1101 1111 = 110X XXXX       
        P2 &=0X1F;                        //关闭所有的74HC573锁存器
       
        P0=(0X01<<DigCom);         //然后选中第一个数码管
        P2|=0XC0;  // P2=P2|0XC0;   XXXX XXXX | 1100 0000 = 11XX XXXX
        P2&=0XDF;         // P2=P2&0XDF;   11XX XXXX & 1101 1111 = 110X XXXX       
        P2&=0X1F;                //关闭所有的74HC573锁存器

        if(++DigCom == 8)DigCom = 0 ;
       
       
        if(++LED_tt == 1000) {LED_tt = 0 ; LED_Ref = 1 ;}

        if(++SEG_tt==1000){SEG_tt=0;SEG_Ref=1;}
       
        if(++Temp_tt==1000){Temp_tt=0;Temp_Ref=1;}
               
}
void Timer0Init(void)                //1毫秒@11.0592MHz
{
        AUXR |= 0x80;                  //定时器时钟1T模式
        TMOD &= 0xF0;                 //设置定时器模式
        TL0 = 0xCD;                   //设置定时初始值
        TH0 = 0xD4;                   //设置定时初始值
        TF0 = 0;                     //清除TF0标志
        TR0 = 1;                     //定时器0开始计时
}
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/La_gloire/article/details/137185414

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2201

主题

16568

帖子

17

粉丝