历史上的今天
返回首页

历史上的今天

今天是:2024年12月03日(星期二)

正在发生

2020年12月03日 | 完美实现STM32单总线挂多个DS18B20

2020-12-03 来源:eefocus

一般常见的STM32的关于DS18B20的例程都是检测一个传感器,代码一般都是跳过ROM检测,直接获取温度值。这种写法并不适用于单总线上挂载多个DS18B20的情况,Sandeepin的这个代码就是针对这种情况完善的单总线挂多个DS18B20检测,实现获取每个DS18B20的ID和温度。


主要的DS18B20时序代码没变,增加了搜索ROM函数,获取温度时先匹配ID。


核心代码如下:


DS18B20.c文件代码:



#include "DS18B20.h"  

#include "Delay.h"  

#include "stdio.h" // printf用  

  

#define DS18B20_GPIO_NUM                 GPIO_Pin_5  

#define DS18B20_GPIO_X                  GPIOC  

#define RCC_APB2Periph_DS18B20_GPIO_X   RCC_APB2Periph_GPIOC  

  

#define DS18B20_DQ_OUT_Low          GPIO_ResetBits(DS18B20_GPIO_X,DS18B20_GPIO_NUM)   

#define DS18B20_DQ_OUT_High         GPIO_SetBits(DS18B20_GPIO_X,DS18B20_GPIO_NUM)   

#define DS18B20_DQ_IN               GPIO_ReadInputDataBit(DS18B20_GPIO_X,DS18B20_GPIO_NUM)   

  

#define MaxSensorNum 8  

unsigned char DS18B20_ID[MaxSensorNum][8];  // 存检测到的传感器DS18B20_ID的数组,前面的维数代表单根线传感器数量上限  

unsigned char DS18B20_SensorNum;            // 检测到的传感器数量(从1开始,例如显示1代表1个,8代表8个)  

  

// 配置DS18B20用到的I/O口  

void DS18B20_GPIO_Config(void)  

{  

    GPIO_InitTypeDef GPIO_InitStructure;  

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_DS18B20_GPIO_X, ENABLE);  

    GPIO_InitStructure.GPIO_Pin = DS18B20_GPIO_NUM;  

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  

    GPIO_Init(DS18B20_GPIO_X, &GPIO_InitStructure);  

    GPIO_SetBits(DS18B20_GPIO_X, DS18B20_GPIO_NUM);  

}  

  

// 引脚输入  

void DS18B20_Mode_IPU(void)  

{  

    GPIO_InitTypeDef GPIO_InitStructure;  

    GPIO_InitStructure.GPIO_Pin = DS18B20_GPIO_NUM;  

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  

    GPIO_Init(DS18B20_GPIO_X, &GPIO_InitStructure);  

}  

  

// 引脚输出  

void DS18B20_Mode_Out(void)  

{  

    GPIO_InitTypeDef GPIO_InitStructure;  

    GPIO_InitStructure.GPIO_Pin = DS18B20_GPIO_NUM;  

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  

    GPIO_Init(DS18B20_GPIO_X, &GPIO_InitStructure);  

  

}  

  

// 复位,主机给从机发送复位脉冲  

void DS18B20_Rst(void)  

{  

    DS18B20_Mode_Out();  

    DS18B20_DQ_OUT_Low;     // 产生至少480us的低电平复位信号  

    Delay_us(480);  

    DS18B20_DQ_OUT_High;    // 在产生复位信号后,需将总线拉高  

    Delay_us(15);  

}  

  

// 检测从机给主机返回的应答脉冲。从机接收到主机的复位信号后,会在15~60us后给主机发一个应答脉冲  

u8 DS18B20_Answer_Check(void)  

{  

    u8 delay = 0;  

    DS18B20_Mode_IPU(); // 主机设置为上拉输入  

    // 等待应答脉冲(一个60~240us的低电平信号 )的到来  

    // 如果100us内,没有应答脉冲,退出函数,注意:从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲  

    while (DS18B20_DQ_IN&&delay < 100)  

    {  

        delay++;  

        Delay_us(1);  

    }  

    // 经过100us后,如果没有应答脉冲,退出函数  

    if (delay >= 100)//Hu200  

        return 1;  

    else  

        delay = 0;  

    // 有应答脉冲,且存在时间不超过240us  

    while (!DS18B20_DQ_IN&&delay < 240)  

    {  

        delay++;  

        Delay_us(1);  

    }  

    if (delay >= 240)  

        return 1;  

    return 0;  

}  

  

// 从DS18B20读取1个位  

u8 DS18B20_Read_Bit(void)  

{  

    u8 data;  

    DS18B20_Mode_Out();  

    DS18B20_DQ_OUT_Low; // 读时间的起始:必须由主机产生 >1us <15us 的低电平信号  

    Delay_us(2);  

    DS18B20_DQ_OUT_High;  

    Delay_us(12);  

    DS18B20_Mode_IPU();// 设置成输入,释放总线,由外部上拉电阻将总线拉高  

    if (DS18B20_DQ_IN)  

        data = 1;  

    else  

        data = 0;  

    Delay_us(50);  

    return data;  

}  

  

// 从DS18B20读取2个位  

u8 DS18B20_Read_2Bit(void)//读二位 子程序  

{  

    u8 i;  

    u8 dat = 0;  

    for (i = 2; i > 0; i--)  

    {  

        dat = dat << 1;  

        DS18B20_Mode_Out();  

        DS18B20_DQ_OUT_Low;  

        Delay_us(2);  

        DS18B20_DQ_OUT_High;  

        DS18B20_Mode_IPU();  

        Delay_us(12);  

        if (DS18B20_DQ_IN)  dat |= 0x01;  

        Delay_us(50);  

    }  

    return dat;  

}  

  

// 从DS18B20读取1个字节  

u8 DS18B20_Read_Byte(void)  // read one byte  

{  

    u8 i, j, dat;  

    dat = 0;  

    for (i = 0; i < 8; i++)  

    {  

        j = DS18B20_Read_Bit();  

        dat = (dat) | (j << i);  

    }  

    return dat;  

}  

  

// 写1位到DS18B20  

void DS18B20_Write_Bit(u8 dat)  

{  

    DS18B20_Mode_Out();  

    if (dat)  

    {  

        DS18B20_DQ_OUT_Low;// Write 1  

        Delay_us(2);  

        DS18B20_DQ_OUT_High;  

        Delay_us(60);  

    }  

    else  

    {  

        DS18B20_DQ_OUT_Low;// Write 0  

        Delay_us(60);  

        DS18B20_DQ_OUT_High;  

        Delay_us(2);  

    }  

}  

  

// 写1字节到DS18B20  

void DS18B20_Write_Byte(u8 dat)  

{  

    u8 j;  

    u8 testb;  

    DS18B20_Mode_Out();  

    for (j = 1; j <= 8; j++)  

    {  

        testb = dat & 0x01;  

        dat = dat >> 1;  

        if (testb)  

        {  

            DS18B20_DQ_OUT_Low;// 写1  

            Delay_us(10);  

            DS18B20_DQ_OUT_High;  

            Delay_us(50);  

        }  

        else  

        {  

            DS18B20_DQ_OUT_Low;// 写0  

            Delay_us(60);  

            DS18B20_DQ_OUT_High;// 释放总线  

            Delay_us(2);  

        }  

    }  

}  

  

//初始化DS18B20的IO口,同时检测DS的存在  

u8 DS18B20_Init(void)  

{  

    DS18B20_GPIO_Config();  

    DS18B20_Rst();  

    return DS18B20_Answer_Check();  

}  

  

// 从ds18b20得到温度值,精度:0.1C,返回温度值(-550~1250),Temperature1返回浮点实际温度  

float DS18B20_Get_Temp(u8 i)  

{  

    //u8 flag;  

    u8 j;//匹配的字节  

    u8 TL, TH;  

    short Temperature;  

    float Temperature1;  

    DS18B20_Rst();  

    DS18B20_Answer_Check();  

    DS18B20_Write_Byte(0xcc);// skip rom  

    DS18B20_Write_Byte(0x44);// convert  

    DS18B20_Rst();  

    DS18B20_Answer_Check();  

  

    // DS18B20_Write_Byte(0xcc);// skip rom  

    //匹配ID,i为形参  

    DS18B20_Write_Byte(0x55);  

    for (j = 0; j < 8; j++)  

    {  

        DS18B20_Write_Byte(DS18B20_ID[i][j]);  

    }  

  

    DS18B20_Write_Byte(0xbe);// convert  

    TL = DS18B20_Read_Byte(); // LSB     

    TH = DS18B20_Read_Byte(); // MSB    

    if (TH & 0xfc)  

推荐阅读

史海拾趣

Data Device Corporation公司的发展小趣事

Data Device Corporation(DDC)成立于1964年,总部位于美国纽约。在创立之初,DDC就专注于为军事和商业航空领域提供高质量的数据接口产品。凭借其卓越的技术实力和对市场的敏锐洞察,DDC迅速在电子行业中崭露头角。通过与各大军事机构和航空公司的紧密合作,DDC不断推出符合市场需求的新产品,逐步奠定了自己在行业中的领先地位。

国兴(GOODSKY)公司的发展小趣事

在电子行业中,竞争日益激烈,DDC也面临着诸多挑战。然而,DDC始终保持着清醒的头脑和坚定的信念,积极应对挑战并寻找机遇。通过不断优化产品结构、提高生产效率、降低成本等措施,DDC不断提高自身的竞争力。同时,DDC还积极关注行业发展趋势和市场变化,及时调整战略方向,确保公司能够在激烈的竞争中立于不败之地。

请注意,这些故事是基于DDC公司的发展历程和事实进行的概述,具体的细节和情节可能需要根据实际情况进行补充和调整。

e2v technologies公司的发展小趣事

随着电子行业的快速发展,e2v不断拓展其产品线,以满足市场的多样化需求。除了传统的图像传感器产品外,公司还开发了示波器数据转换器、高性能图像处理器等,广泛应用于科学、医学、工业、汽车和电信等领域。这些产品的推出,不仅拓展了e2v的市场空间,也为其带来了可观的经济效益。

Diotec Electronics Corp公司的发展小趣事

随着产品的不断成熟和市场的认可,Diotec开始积极拓展国内外市场。公司加强与国际知名电子企业的合作,不断提升产品的品质和技术水平。同时,Diotec还注重品牌建设,通过一系列的市场推广活动,提高了品牌的知名度和美誉度。这些努力使Diotec的产品在电子行业中占据了重要的地位,成为众多客户的首选供应商。

Fischer Elektronik公司的发展小趣事

Fischer Elektronik公司成立于1969年,是德国在高性能散热器和半导体制冷领域的领先制造商。成立之初,公司专注于研发和生产电子元器件的关键部件,如散热器和连接器,以满足当时快速增长的电子行业对高效散热解决方案的需求。凭借其精湛的工艺和严格的质量控制,Fischer Elektronik迅速在市场中站稳脚跟,并开始在仪器仪表、通讯/网络、交通/汽车和工业/自动化等领域展露头角。

CTS [CTS Corporation]公司的发展小趣事

为了满足全球市场的需求,CTS开始实施全球化扩张战略。公司在北美、亚洲和欧洲等地设立了生产设施,以便更好地服务全球客户。同时,CTS还积极与各地的合作伙伴建立紧密的合作关系,共同推动电子元器件和传感器市场的发展。

问答坊 | AI 解惑

刚才把开发板单片机的串口烧了,郁闷!

单片机(STC89C52)VCC是5V, GPS(MTK M89)VCC是4.3V RXD连TXD,TXD连RXD 用万用表量的时候GPS的串口是4.8V,GPS的是3.6V 不知道怎么的就烧了?为什么没接串口之前MCU的RXD、TXD都有4.8的电压? 小弟刚入门还请指点迷经,要怎么联才可以让MCU读到GPS ...…

查看全部问答>

51看门狗,求救!!!

一个有关看门狗(AT89s51)的问题问一下高手们。 1.看门狗是一个寄存器吧,它里面有些啥标识符。里面会有像TMOD寄存器里的GATE、C/T#、M1、M1.....吗? 2.还有在用它的时候,为什么要写入:              ...…

查看全部问答>

在wince的任务栏下如何将网卡图标增加上去?

我的wince系统的网卡驱动已经增加上了,而且可以正常使用,但在wince系统的任务栏上却没有网卡的图标。 请问高手我该怎么办?…

查看全部问答>

在应用层能不能直接读某个地址的值?

如题: EVC下代码如下: addr = (unsigned char *)( 0xBFA00000 + 24+ i*2 ); code = *addr; RETAILMSG(1, (TEXT(\"The DTMF code is %x .\\r\\n\"),code)); 复制代码 我是没读出来!…

查看全部问答>

Freescale的ARM® Cortex™-M4 微控制器系列Kinetis 好久才能上市?

Freescale的ARM® Cortex™-M4 微控制器系列Kinetis 好久才能上市?   很想玩玩ARM® Cortex™-M4 内核的MCU,不知道有没有机会。   年初的时候使用过NXP的 LPC1000系列的ARM® Cortex™-M0, 感觉不错  ...…

查看全部问答>

请教城主一个MCO的问题,你以前回复的帖子!

版主发表于 2010-8-24 17:44 | 只看该作者 回复 引用 评分 报告 返回版面 TOP   得分:0…

查看全部问答>

wince6.0 mass storage,RNDIS 和activesync USB 连接的实现方法探讨

S5pv210 下有现成的注册表 IF BSP_USBFN_RNDIS [HKEY_LOCAL_MACHINE\\Drivers\\USB\\FunctionDrivers]     \"DefaultClientDriver\"=- ; erase previous default     \"DefaultClientDriver\"=\"RNDIS\" ENDIF IF BSP_US ...…

查看全部问答>

帮忙gerber转PCB

求帮忙把gerber文件转成pcb文件…

查看全部问答>