DS18B20.c
- // =============================================
- # @Time : 2020-06-08
- # @Author : AXYZdong
- # @CSDN : https://blog.csdn.net/qq_43328313
- # @FileName: DS18B20.c
- # @Software: keil5 MDK
- // =============================================
- #include "stm32f4xx.h"
- #include "ds18b20.h"
- #include "delay.h"
-
- /*******************************************************************************
- * 函数名:DS18B20_GPIO_Config
- * 描述 :配置DS18B20用到的I/O口
- * 输入 :无
- * 输出 :无
- *******************************************************************************/
- void DS18B20_GPIO_Config(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_AHB1PeriphClockCmd(RCC_DS18B20, ENABLE); /*开启DS18B20对应的GPIO的外设时钟*/
- GPIO_InitStructure.GPIO_Pin = DS18B20_DQ_GPIO_PIN; /*选择要控制的DS18B20引脚*/
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; /*设置引脚模式输出模式*/
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; /*设置引脚的输出类型为推挽输出*/
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /*设置引脚速率为50MHz */
- GPIO_Init(DS18B20_DQ_GPIO_PORT, &GPIO_InitStructure); /*调用库函数,初始化相应GPIO*/
- }
- /*******************************************************************************
- * 函数名:DS18B20_Mode_Out
- * 描述 :使DS18B20-DATA引脚变为输出模式
- * 输入 :无
- * 输出 :无
- *******************************************************************************/
- static void DS18B20_Mode_Out(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- /*选择要控制的DS18B20_DQ_GPIO_PORT引脚*/
- GPIO_InitStructure.GPIO_Pin = DS18B20_DQ_GPIO_PIN;
- /*设置引脚模式输出模式*/
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
- /*设置引脚的输出类型为推挽输出*/
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
- /*设置引脚速率为50MHz */
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- /*调用库函数,初始化DS18B20_DQ_GPIO_PORT*/
- GPIO_Init(DS18B20_DQ_GPIO_PORT, &GPIO_InitStructure);
- }
- /*******************************************************************************
- * 函数名:DS18B20_Mode_IN
- * 描述 :使DS18B20-DATA引脚变为输入模式
- * 输入 :无
- * 输出 :无
- *******************************************************************************/
- static void DS18B20_Mode_IN(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- /*选择要控制的DS18B20_DQ_GPIO_PORT引脚*/
- GPIO_InitStructure.GPIO_Pin = DS18B20_DQ_GPIO_PIN;
- /*设置引脚模式为浮空输入模式*/
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
- /*调用库函数,初始化DS18B20_DQ_GPIO_PORT*/
- GPIO_Init(DS18B20_DQ_GPIO_PORT, &GPIO_InitStructure);
- }
- void DS18B20_Init()
- {
- DS18B20_GPIO_Config();
- }
-
- /*******************************************************************************
- * 函数名:DS18B20_Reset
- * 描述 :初始化DS18B20
- * 输入 :无
- * 输出 :无
- * 返回值:初始化成功为0,不成功为1
- *******************************************************************************/
- int DS18B20_Reset(void)
- {
- DS18B20_Mode_Out();
- int initflag = 0;
- DS18B20_DQ_H; //先置高
- delay_us(700); //延时700us,使总线稳定
- DS18B20_DQ_L; //复位脉冲,低电位
- delay_us(750); //保持至少480us,这里500us
- DS18B20_DQ_H; //拉高数据线,释放总线
- delay_us(40); //等待15-60us,这里33us
- DS18B20_Mode_IN();
- initflag = GPIO_ReadInputDataBit(DS18B20_DQ_GPIO_PORT,DS18B20_DQ_GPIO_PIN);
- delay_us(60);
- return initflag;
- }
- /*******************************************************************************
- * 函数名:DS18B20_Wbyte
- * 功能:写一个字节
- * 输入:uint8_t xbyte
- * 输出:无
- * 返回值:无
- * 备注:无
- *******************************************************************************/
- void Write_DS18B20(unsigned char xbyte)
- {
- int8_t i ,x = 0;
- DS18B20_Mode_Out();
- //8次循环实现逐位写入
- for(i = 1; i <= 8; i++)
- {
- //先取低位
- x = xbyte & 0x01;
- //写1
- if(x)
- {
- DS18B20_DQ_H;
- //拉低总线
- DS18B20_DQ_L;
- //延时15us
- delay_us(15);
- //总线写1
- DS18B20_DQ_H;
- //延时15us
- delay_us(15);
- //保持高电平
- DS18B20_DQ_H;
- delay_us(4);
- }
- //写0
- else
- {
- DS18B20_DQ_H;
- //总线拉低
- DS18B20_DQ_L;
- //延时15us
- delay_us(15);
- //总线写0
- DS18B20_DQ_L;
- //延时15us
- delay_us(15);
- //保持高电平
- DS18B20_DQ_H;
- delay_us(4);
- }
- //xbyte右移一位
- xbyte = xbyte >> 1;
- }
- }
- /*******************************************************************************
- * 函数名:DS18B20_Rbit
- * 功能:从DS18B20读一个位
- * 输入:无
- * 输出:无
- * 返回值:读取到的位
- * 备注:无
- *******************************************************************************/
- uint8_t DS18B20_Rbit(void)
- {
- //rbit是最终位数据,x是取状态变量
- uint8_t rbit = 0x00,x = 0;
- DS18B20_Mode_Out(); //改变DQ为输出模式
-
- DS18B20_DQ_H;
- DS18B20_DQ_L;
- delay_us(1);
- DS18B20_DQ_H;
-
- //延时大约3us
- //delay_us(7);
- //获取总线电平状态
- x = DS18B20_DQ_IN();
- //如果是1,则返回0x80,否则返回0x00
- if(x)
- rbit = 0x80;
- //延时大约60us
- delay_us(60);
- return rbit;
- }
- /*******************************************************************************
- * 函数名:DS18B20_Rbyte
- * 功能:从DS18B20读一个字节
- * 输入:无
- * 输出:无
- * 返回值:读取到的字节
- * 备注:无
- *******************************************************************************/
- uint8_t DS18B20_Rbyte(void)
- {
- //rbyte:最终得到的字节
- //tempbit:中间运算变量
- uint8_t rbyte = 0,i = 0, tempbit =0;
- for (i = 1; i <= 8; i++)
- {
- //读取位
- tempbit = DS18B20_Rbit();
- //右移实现高低位排序
- rbyte = rbyte >> 1;
- //或运算移入数据
- rbyte = rbyte|tempbit;
- }
- return rbyte;
- }
- /*******************************************************************************
- * 函数名:ReadTemperature
- * 功能:读取温度
- * 输入:无
- * 输出:温度值
- * 返回值:无
- * 备注:注意温度的转换
- *******************************************************************************/
- int ReadTemperature(void)
- {
- int fg; //fg:符号位
- int data; //data:温度的整数部分
- float f_data; //f_data:温度(浮点型)
-
- DS18B20_Reset(); //DS18B20初始化
- Write_DS18B20(0xcc); //跳过读序列号
- Write_DS18B20(0x44); //启动温度转换
- delay_us(200); //等待温度转换
- DS18B20_Reset(); //DS18B20初始化
- Write_DS18B20(0xcc); //跳过读序列号
- Write_DS18B20(0xbe); //读温度寄存器
-
- uint8_t TempL = DS18B20_Rbyte();
- uint8_t TempH = DS18B20_Rbyte();
- //符号位为负
- if(TempH > 0x70)
- {
- TempL = ~TempL;
- TempH = ~TempH;
- fg = 0;
- }
- else
- fg = 1;
- //整数部分
- data = TempH;
- data <<= 8;
- data = data | TempL;
- f_data = data*0.0625;
- data = f_data *10 ;
- if(fg)
- return data;
- else
- return -data;
- }
- /*******************************************************************************
- * 函数名:display
- * 功能:显示温度
- * 输入:*tab
- * 输出:温度值
- * 返回值:无
- * 备注:注意温度的转换
- *******************************************************************************/
- void display(char *tab)
- {
- tab[0] = ReadTemperature()/100 + 0x30;
- tab[1] = ReadTemperature()%100/10 + 0x30;
- tab[3] = ReadTemperature()%10 + 0x30;
- tab[2] = '.';
- tab[4] = 'C';
- }
|