赞
踩
目录
使用stm32f103c8t6的芯片,在OLED显示屏上显示DS18B20的温度值。
1.独特的单线接口 ,只需 1 个接口引脚即可通信。
2.每个设备的内部ROM上都烧写了一个独一无二的64位序列号。
3无需外部元件。
4.能够采用数据线供电,供电范围为3.0V至5.5V。
5.温度可测量范围为:-55℃至+125℃(-67℉至+257℉)。
6.温度范围超过-10℃至85℃之外时测温分辨率0.5℃。
7.以 9 位数字值方式读出温度。
8.在 1 秒( 典型值 )内把温度变换为数字。
9.用户可定义的 非易失性的温度告警设置。
10.告警搜索命令识别和寻址温度在编定的极限之外的器件(温度告警情况)。
11.应用范围包括恒温控制 工业系统 消费类产品 温度计或任何热敏系统。
本文使用的是stm32f103c8的芯片,VCC接3.3V,信号线接PB12 引脚。
- #include "ds18b20.h"
- #include "stm32f10x.h"
-
- /**************************************************************************************
- * 描 述 : 配置DS18B20用到的I/O口
- * 入 参 : 无
- * 返回值 : 无
- **************************************************************************************/
- static void DS18B20_GPIO_Config(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
-
- RCC_APB2PeriphClockCmd(DS18B20_CLK, ENABLE);
-
- GPIO_InitStructure.GPIO_Pin = DS18B20_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(DS18B20_PORT, &GPIO_InitStructure);
-
- GPIO_SetBits(DS18B20_PORT, DS18B20_PIN); //DS18B20数据引脚初始化配置为高电平输出
- }
-
- /**************************************************************************************
- * 描 述 : 配置使DS18B20-DATA引脚变为输入模式
- * 入 参 : 无
- * 返回值 : 无
- **************************************************************************************/
- static void DS18B20_Mode_IPU(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
-
- GPIO_InitStructure.GPIO_Pin = DS18B20_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
- GPIO_Init(DS18B20_PORT, &GPIO_InitStructure);
- }
-
- /**************************************************************************************
- * 描 述 : 配置使DS18B20-DATA引脚变为输出模式
- * 入 参 : 无
- * 返回值 : 无
- **************************************************************************************/
- static void DS18B20_Mode_Out_PP(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
-
- GPIO_InitStructure.GPIO_Pin = DS18B20_PIN;
-
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(DS18B20_PORT, &GPIO_InitStructure);
- }
-
- /**************************************************************************************
- * 描 述 : 主机给从机发送复位脉冲
- * 入 参 : 无
- * 返回值 : 无
- **************************************************************************************/
- static void DS18B20_Rst(void)
- {
- DS18B20_Mode_Out_PP(); //主机设置为推挽输出
-
- DS18B20_DATA_OUT(LOW); //主机至少产生480us的低电平复位信号
- Delay_us(750);
- DS18B20_DATA_OUT(HIGH); //主机在产生复位信号后,需将总线拉高
- Delay_us(15); //从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲
- }
-
- /**************************************************************************************
- * 描 述 : 检测从机给主机返回的存在脉冲
- * 入 参 : 无
- * 返回值 : 0:成功 1:失败
- **************************************************************************************/
- static u8 DS18B20_Presence(void)
- {
- u8 pulse_time = 0;
-
- DS18B20_Mode_IPU(); //主机设置为上拉输入
-
- /* 等待存在脉冲的到来,存在脉冲为一个60~240us的低电平信号
- * 如果存在脉冲没有来则做超时处理,从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲
- */
- while( DS18B20_DATA_IN() && pulse_time<100 )
- {
- pulse_time++;
- Delay_us(1);
- }
-
- if( pulse_time >=100 ) //经过100us后,存在脉冲都还没有到来
- return 1; //读取失败
- else //经过100us后,存在脉冲到来
- pulse_time = 0; //清零计时变量
-
- while( !DS18B20_DATA_IN() && pulse_time<240 ) // 存在脉冲到来,且存在的时间不能超过240us
- {
- pulse_time++;
- Delay_us(1);
- }
- if( pulse_time >=240 ) // 存在脉冲到来,且存在的时间超过了240us
- return 1; //读取失败
- else
- return 0;
- }
-
- /**************************************************************************************
- * 描 述 : 从DS18B20读取一个bit
- * 入 参 : 无
- * 返回值 : u8
- **************************************************************************************/
- static u8 DS18B20_Read_Bit(void)
- {
- u8 dat;
-
- /* 读0和读1的时间至少要大于60us */
- DS18B20_Mode_Out_PP();
- /* 读时间的起始:必须由主机产生 >1us <15us 的低电平信号 */
- DS18B20_DATA_OUT(LOW);
- Delay_us(10);
-
- /* 设置成输入,释放总线,由外部上拉电阻将总线拉高 */
- DS18B20_Mode_IPU();
-
- if( DS18B20_DATA_IN() == SET )
- dat = 1;
- else
- dat = 0;
-
- /* 这个延时参数请参考时序图 */
- Delay_us(45);
-
- return dat;
- }
-
- /**************************************************************************************
- * 描 述 : 从DS18B20读一个字节,低位先行
- * 入 参 : 无
- * 返回值 : u8
- **************************************************************************************/
- u8 DS18B20_Read_Byte(void)
- {
- u8 i, j, dat = 0;
-
- for(i=0; i<8; i++)
- {
- j = DS18B20_Read_Bit(); //从DS18B20读取一个bit
- dat = (dat) | (j<<i);
- }
-
- return dat;
- }
-
- /**************************************************************************************
- * 描 述 : 写一个字节到DS18B20,低位先行
- * 入 参 : u8
- * 返回值 : 无
- **************************************************************************************/
- void DS18B20_Write_Byte(u8 dat)
- {
- u8 i, testb;
- DS18B20_Mode_Out_PP();
-
- for( i=0; i<8; i++ )
- {
- testb = dat&0x01;
- dat = dat>>1;
- /* 写0和写1的时间至少要大于60us */
- if (testb)
- {
- DS18B20_DATA_OUT(LOW);
- Delay_us(8); //1us < 这个延时 < 15us
-
- DS18B20_DATA_OUT(HIGH);
- Delay_us(58); //58us+8us>60us
- }
- else
- {
- DS18B20_DATA_OUT(LOW);
- /* 60us < Tx 0 < 120us */
- Delay_us(70);
-
- DS18B20_DATA_OUT(HIGH);
- /* 1us < Trec(恢复时间) < 无穷大*/
- Delay_us(2);
- }
- }
- }
-
- /**************************************************************************************
- * 描 述 : 起始DS18B20
- * 入 参 : 无
- * 返回值 : 无
- **************************************************************************************/
- void DS18B20_Start(void)
- {
- DS18B20_Rst(); //主机给从机发送复位脉冲
- DS18B20_Presence(); //检测从机给主机返回的存在脉冲
- DS18B20_Write_Byte(0XCC); // 跳过 ROM
- DS18B20_Write_Byte(0X44); // 开始转换
- }
-
- /**************************************************************************************
- * 描 述 : DS18B20初始化函数
- * 入 参 : 无
- * 返回值 : u8
- **************************************************************************************/
- u8 DS18B20_Init(void)
- {
- DS18B20_GPIO_Config();
- DS18B20_Rst();
-
- return DS18B20_Presence();
- }
-
- /**************************************************************************************
- * 描 述 : 从DS18B20读取温度值
- * 入 参 : 无
- * 返回值 : float
- **************************************************************************************/
- float DS18B20_Get_Temp(void)
- {
- u8 tpmsb, tplsb;
- short s_tem;
- float f_tem;
-
- DS18B20_Rst();
- DS18B20_Presence();
- DS18B20_Write_Byte(0XCC); /* 跳过 ROM */
- DS18B20_Write_Byte(0X44); /* 开始转换 */
-
- DS18B20_Rst();
- DS18B20_Presence();
- DS18B20_Write_Byte(0XCC); /* 跳过 ROM */
- DS18B20_Write_Byte(0XBE); /* 读温度值 */
-
- tplsb = DS18B20_Read_Byte();
- tpmsb = DS18B20_Read_Byte();
-
- s_tem = tpmsb<<8;
- s_tem = s_tem | tplsb;
-
- if( s_tem < 0 ) /* 负温度 */
- f_tem = (~s_tem+1) * 0.0625;
- else
- f_tem = (s_tem * 0.0625);
-
- //这样做的目的将小数点后第一位也转换为可显示数字
- //同时进行一个四舍五入操作。
-
- return f_tem;
- }
-
-
- /*************************************END OF FILE******************************/
-
- #ifndef __DS18B20_H
- #define __DS18B20_H
-
- #include "stm32f10x.h"
- #include "delay.h"
-
- #define HIGH 1
- #define LOW 0
-
- #define DS18B20_CLK RCC_APB2Periph_GPIOB
- #define DS18B20_PIN GPIO_Pin_12
- #define DS18B20_PORT GPIOB
-
- //带参宏,可以像内联函数一样使用,输出高电平或低电平
- #define DS18B20_DATA_OUT(a) if (a) \
- GPIO_SetBits(GPIOB,GPIO_Pin_12);\
- else \
- GPIO_ResetBits(GPIOB,GPIO_Pin_12)
- //读取引脚的电平
- #define DS18B20_DATA_IN() GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12)
-
- typedef struct
- {
- u8 humi_int; //湿度的整数部分
- u8 humi_deci; //湿度的小数部分
- u8 temp_int; //温度的整数部分
- u8 temp_deci; //温度的小数部分
- u8 check_sum; //校验和
-
- }DS18B20_Data_TypeDef;
-
- u8 DS18B20_Init(void);
- float DS18B20_Get_Temp(void);
- #endif /* __DS18B20_H */
- void TEMP_Value_Conversion()
- {
- temp_data=DS18B20_Get_Temp();
- temp_data1=temp_data;
-
-
- sprintf((char*)ucbuf,"%4.2f",temp_data1);
- OLED_ShowString(72,48,(uint8_t*)ucbuf,16,1);
- OLED_ShowChinese(0,48,0,16,1);
- OLED_ShowChinese(16,48,1,16,1);
- OLED_ShowChinese(32,48,2,16,1);
- OLED_ShowChinese(48,48,3,16,1);
- OLED_ShowChar(64,48,':',16,1);
- OLED_ShowChinese(112,48,4,16,1);
-
- }
- main (void)
- {
- /* 配置系统时钟为72M */
- SystemInit();
-
-
- DS18B20_Init();
- OLED_Init();
- OLED_ColorTurn(0);//0正常显示,1 反色显示
- OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
- OLED_ShowChinese(48,16,3,16,1);
- while(1)
- {
- OLED_Refresh();
-
- TEMP_Value_Conversion();
- Delay_ms(500);
- }
- }
-
其中OLED的配置程序及接线参考之前的文章https://blog.csdn.net/qq_50749196/article/details/131022176
我这里使用的是贴片式DS18B20温度传感器(图片上方蓝色线头),OLED显示的温度保留小数点后两位数字。
完整程序已上传,有需要者自行下载:
链接:https://pan.baidu.com/s/1KbtNQGjrHjWSbZUC1efnSA?pwd=ydlz
提取码:ydlz
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。