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; }