582驱动DS18B20

目录

以582为例,驱动DS18B20,可以移植到CH573、CH579等MCU上。

主函数所在源文件↓

#include "CH58x_common.h"
#include "DS18B20.h"

/* CMD_ROM:
 *  0x33    读ROM
 *  0x55    指定芯片
 *  0xCC    跳过ROM阶段
 *  0xF0    芯片搜索
 *  0xEC    报警芯片
 */

/* CMD_RAM:
 *  0x4E    写RAM
 *  0xBE    读RAM
 *  0x44    温度转换
 *  0x48    RAM数据复制到EEPROM
 *  0xB8    EEPROM报警值复制到RAM
 *  0xB4    工作方式切换
 */

/*********************************************************************
 * @fn      DebugInit
 *
 * @brief   调试初始化
 *
 * @return  none
 */
void DebugInit(void)
{
    GPIOA_SetBits(GPIO_Pin_9);
    GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
    GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);
    UART1_DefInit();
}

/*********************************************************************
 * @fn      main
 *
 * @brief   主函数
 *
 * @return  none
 */
int main()
{
    SetSysClock(CLK_SOURCE_PLL_60MHz);

    DebugInit();
    PRINT("start\n");

    while(1)
    {
        unsigned char status, data_l,  data_h = 0;
        unsigned short temprera_16 = 0;
        float temprera = 0;

        status = DS18B20_Reset();
        if(!status)
            PRINT("1Reset_OK\n");
        DS18B20_Write_Byte(0xCC);   //跳过ROM阶段
        DS18B20_Write_Byte(0x44);   //温度转换

        status = DS18B20_Reset();
        if(!status)
            PRINT("2Reset_OK\n");
        DS18B20_Write_Byte(0xCC);   //跳过ROM阶段
        DS18B20_Write_Byte(0xBE);   //读RAM

        data_l = DS18B20_Read_Byte();   //读低八位
        data_h = DS18B20_Read_Byte();   //读高八位
        PRINT("DATA = 0x%x 0x%x\n", data_h, data_l);

        temprera_16 = ((uint16_t)data_h << 8) | data_l;
        if(temprera_16 & 0x8000)
        {
            PRINT("-\n");       //高位是负的,懒得转换了,参考下手册吧
        }
        else
        {
            temprera = temprera_16 * 0.0625;
        }
        PRINT("temprera = %f ℃\n", temprera);

        DelayMs(1000);
    }
}

头文件↓

#ifndef _DS18B20_H_
#define _DS18B20_H_

#include "CH58x_common.h"
//#include "CH58x_gpio.h"

#define DQ_PIN_GROUP_A  0
#define DQ_PIN_GROUP_B  1

#define DQ_PIN_GROUP  DQ_PIN_GROUP_A    //选择582的A组还是B组GPIO
#define DQ_PIN  GPIO_Pin_4

#if DQ_PIN_GROUP == DQ_PIN_GROUP_A
#define DQ_IN           GPIOA_ModeCfg(DQ_PIN, GPIO_ModeIN_PU)
#define DQ_GPIO_READ    GPIOA_ReadPortPin(DQ_PIN)
#define DQ_OUT          GPIOA_ModeCfg(DQ_PIN, GPIO_ModeOut_PP_5mA)
#define DQ_PULLUP       GPIOA_SetBits(DQ_PIN)
#define DQ_PULLDOWN     GPIOA_ResetBits(DQ_PIN)

#else
#define DQ_IN           GPIOB_ModeCfg(DQ_PIN, GPIO_ModeIN_PU)
#define DQ_GPIO_READ    GPIOB_ReadPortPin(DQ_PIN)
#define DQ_OUT          GPIOB_ModeCfg(DQ_PIN, GPIO_ModeOut_PP_5mA)
#define DQ_PULLUP       GPIOB_SetBits(DQ_PIN)
#define DQ_PULLDOWN     GPIOB_ResetBits(DQ_PIN)
#endif

unsigned char DS18B20_Reset();
void DS18B20_Write_Bit(unsigned char bit);
unsigned char DS18B20_Read_Bit();
void DS18B20_Write_Byte(unsigned char tx_data);
unsigned char DS18B20_Read_Byte();

#endif /* SRC_DS18B20_H_ */

源文件↓

#include "DS18B20.h"

#define DS18B20_DELAYUS(X)   DelayUs(X)

#define  RESET_START_RELAY  480     //协议标准,不建议修改
#define  RESET_SAMPLING_RELAY  60   //15 <= n <= 300

#define  WRITE_BIT_START_RELAY  15  //n >= 15
#define  WRITE_BIT_RELAY  45        //15 <= n <= 45
                                    //60 <= WRITE_BIT_START_RELAY+WRITE_BIT_RELAY <= 120
#define  READ_BIT_START_RELAY  1    //协议标准,不建议修改
#define  READ_BIT_SAMPLING_RELAY  15
#define  READ_BIT_RELEASE_RELAY  45

/* 复位信号,判断是否收到存在脉冲*/
unsigned char DS18B20_Reset()
{
    DQ_OUT;
    DQ_PULLDOWN;
    DS18B20_DELAYUS(RESET_START_RELAY);         //复位起始信号

    DQ_IN;
    DS18B20_DELAYUS(RESET_SAMPLING_RELAY);      //延时足够的时长后采样
    if(DQ_GPIO_READ == 0)       //收到存在脉冲
    {
        while(DQ_GPIO_READ == 0);   //等待存在脉冲结束
        return 0;
    }
    else                        //未检测到存在脉冲
    {
        return 1;
    }
}

/*按位写*/
void DS18B20_Write_Bit(unsigned char bit)
{
    DQ_OUT;
    DQ_PULLDOWN;
    DS18B20_DELAYUS(WRITE_BIT_START_RELAY);     //按位写时序的起始信号

    if(bit)
    {
        DQ_PULLUP;                      //写1,再保持一定时长
        DS18B20_DELAYUS(WRITE_BIT_RELAY);
    }
    else
    {
        DS18B20_DELAYUS(WRITE_BIT_RELAY);       //写0, 保持拉低即可
        DQ_PULLUP;
    }
}

/*按位读*/
unsigned char DS18B20_Read_Bit()
{
    DQ_OUT;
    DQ_PULLDOWN;
    DS18B20_DELAYUS(READ_BIT_START_RELAY);     //按位读时序的起始信号
    DQ_IN;          //拉低1s总线后释放,交给从机控制

    DS18B20_DELAYUS(READ_BIT_SAMPLING_RELAY);     //选取一个时间点采样
    if(DQ_GPIO_READ)    //高电平
    {
        DS18B20_DELAYUS(READ_BIT_RELEASE_RELAY);    //等待从机释放总线
        return 1;
    }
    else
    {
        DS18B20_DELAYUS(READ_BIT_RELEASE_RELAY);    //等待从机释放总线
        return 0;
    }
}

/*按字节写*/
void DS18B20_Write_Byte(unsigned char tx_data)
{
    for(unsigned char i=0; i<8; i++)
    {
        DS18B20_Write_Bit(tx_data & 0x01);
        tx_data >>= 1;
    }
}

/*按字节读*/
unsigned char DS18B20_Read_Byte()
{
    unsigned char rx_data = 0;
    for(unsigned char i=0; i<8; i++)
    {
        rx_data >>= 1;
        if(DS18B20_Read_Bit())
            rx_data |= 0x80;
    }
    return rx_data;
}
posted @ 2023-03-10 17:11  JayWell  阅读(195)  评论(0编辑  收藏  举报