DS18B20温度模块驱动(STM32)

2019-07-14 12:29发布

一、前期准备
单片机:STM32F103C8T6
开发环境:MDK5.14
库函数:标准库V3.5
DS18B20模块:淘宝有售
在这里插入图片描述 二、实验效果
在这里插入图片描述
在这里插入图片描述 三、驱动原理
看数据手册。
需要完整工程或者有问题的请加QQ:1002521871,验证:呵呵。 四、驱动代码
ds18b20.h #ifndef __DS18B20_H__ #define __DS18B20_H__ #include "stm32f10x.h" #include "gpio.h" #include "delay.h" #define DS18B20_Direction_I {GPIOA->CRL &= 0XFFFFFFF0; GPIOA->CRL |= 8;} #define DS18B20_Direction_O {GPIOA->CRL &= 0XFFFFFFF0; GPIOA->CRL |= 3;} #define DS18B20_DQ_O PAout(0) #define DS18B20_DQ_I PAin(0) extern uint8_t DS18B20_IsOnline(void) ; extern void DS18B20_StartConversion(void); extern uint8_t DS18B20Configuration(void); extern int16_t DS18B20_GetTemperature(void); #endif ds18b20.c #include "ds18b20.h" //复位DS18B20 void DS18B20_Reset(void) { DS18B20_Direction_O; //SET PG11 OUTPUT DS18B20_DQ_O = 0; //拉低DQ DelayUs(750); //拉低750us DS18B20_DQ_O = 1; //DQ=1 DelayUs(15); //15US } //等待DS18B20的回应 //返回1:未检测到DS18B20的存在 //返回0:存在 uint8_t DS18B20_IsOnline(void) { uint16_t retry = 0; DS18B20_Direction_I; //SET PA0 INPUT while (DS18B20_DQ_I && retry < 200) { retry++; DelayUs(1); }; if(retry >= 200) { return 1; } else { retry = 0; } while (!DS18B20_DQ_I && retry < 240) { retry ++; DelayUs(1); }; if(retry >= 240) { return 1; } return 0; } //从DS18B20读取一个位 //返回值:1/0 uint8_t DS18B20_ReadBit(void) { uint8_t data; DS18B20_Direction_O; DS18B20_DQ_O = 0; DelayUs(2); DS18B20_DQ_O = 1; DS18B20_Direction_I; DelayUs(12); if(DS18B20_DQ_I) { data = 1; } else { data = 0; } DelayUs(50); return data; } //从DS18B20读取一个字节 //返回值:读到的数据 uint8_t DS18B20_ReadByte(void) { uint8_t i, j, dat; dat = 0; for (i = 1; i <= 8; i ++) { j = DS18B20_ReadBit(); dat = (j << 7) | (dat >> 1); } return dat; } //写一个字节到DS18B20 //dat:要写入的字节 void DS18B20_WriteByte(uint8_t dat) { uint8_t j; uint8_t testb; DS18B20_Direction_O; //SET PG11 OUTPUT; for (j = 1; j <= 8; j ++) { testb = dat & 0x01; dat >>= 1; if (testb) { DS18B20_DQ_O = 0; // Write 1 DelayUs(2); DS18B20_DQ_O = 1; DelayUs(60); } else { DS18B20_DQ_O = 0; // Write 0 DelayUs(60); DS18B20_DQ_O = 1; DelayUs(2); } } } //开始温度转换 void DS18B20_StartConversion(void) { DS18B20_Reset(); DS18B20_IsOnline(); DS18B20_WriteByte(0xcc); // skip rom DS18B20_WriteByte(0x44); // convert } //初始化DS18B20的IO口 DQ 同时检测DS的存在 //返回1:不存在 //返回0:存在 uint8_t DS18B20Configuration(void) { GPIO_InitTypeDef MyGPIO; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能PORTA口时钟 MyGPIO.GPIO_Pin = GPIO_Pin_0; //PORTA.00 推挽输出 MyGPIO.GPIO_Mode = GPIO_Mode_Out_PP; MyGPIO.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &MyGPIO); DS18B20_DQ_O = 1; //输出1 DS18B20_Reset(); return DS18B20_IsOnline(); } //从ds18b20得到温度值 //精度:0.1C //返回值:温度值 (-550~1250) int16_t DS18B20_GetTemperature(void) { uint8_t temp; uint8_t TL,TH; int16_t tem; DS18B20_StartConversion(); // ds1820 start convert DS18B20_Reset(); DS18B20_IsOnline(); DS18B20_WriteByte(0xCC); // skip rom DS18B20_WriteByte(0xBE); // convert TL = DS18B20_ReadByte(); // LSB TH = DS18B20_ReadByte(); // MSB if(TH > 7) { TH = ~TH; TL = ~TL; temp = 0; //温度为负 } else { temp = 1; //温度为正 } tem = TH; //获得高八位 tem <<= 8; tem += TL; //获得底八位 tem = (float)tem * 0.625; //转换 if(temp) { return tem; //返回温度值 } else { return -tem; } } 由于作者能力有限,有不妥之处欢迎指正,邮箱alex_hua@foxmail.com