- #ifndef __DS18B20_H__
- #define __DS18B20_H__
- /* 包含头文件 ----------------------------------------------------------------*/
- #include "at32m412_416_board.h"
- /************************** DS18B20 连接引脚定义********************************/
- #define DS18B20_DQ_GPIO_CLK CRM_GPIOB_PERIPH_CLOCK
- #define DS18B20_DQ_GPIO_PORT GPIOB
- #define DS18B20_DQ_GPIO_PIN GPIO_PINS_12
- /************************** DS18B20 函数宏定义********************************/
- #define DS18B20_DQ_0 gpio_bits_reset(DS18B20_DQ_GPIO_PORT,DS18B20_DQ_GPIO_PIN)
- #define DS18B20_DQ_1 gpio_bits_set(DS18B20_DQ_GPIO_PORT,DS18B20_DQ_GPIO_PIN)
- #define DS18B20_DQ_IN() gpio_input_data_bit_read(DS18B20_DQ_GPIO_PORT,DS18B20_DQ_GPIO_PIN)
- /************************** DS18B20 函数声明 ********************************/
- uint8_t DS18B20_Init(void);
- void DS18B20_ReadId( uint8_t * ds18b20_id);
- float DS18B20_GetTemp_SkipRom(void);
- float DS18B20_GetTemp_MatchRom(uint8_t *ds18b20_id);
- #endif
DS18B20.c
- #include "at32m412_416_board.h"
- #include "at32m412_416_clock.h"
- #include "DS18B20.h"
- /**
- * 函数功能: DS18B20 初始化函数
- * 输入参数: 无
- * 返 回 值: 0:初始化成功,检测到传感器,1:初始化失败
- * 说 明:无
- */
- uint8_t DS18B20_Init(void)
- {
- DS18B20_GPIO_Config ();
- DS18B20_DQ_1;
- DS18B20_Rst();
- return DS18B20_Presence ();
- }
- /**
- * 函数功能: 配置DS18B20用到的I/O口
- * 输入参数: 无
- * 返 回 值: 无
- * 说 明:无
- */
- static void DS18B20_GPIO_Config(void)
- {
- gpio_init_type gpio_init_structure;
- crm_periph_clock_enable(DS18B20_DQ_GPIO_CLK, TRUE);
-
- gpio_init_structure.gpio_pins = DS18B20_DQ_GPIO_PIN;
- gpio_init_structure.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
- gpio_init_structure.gpio_mode = GPIO_MODE_OUTPUT;
- gpio_init_structure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
- gpio_init(DS18B20_DQ_GPIO_PORT , &gpio_init_structure);
- }
- /**
- * 函数功能: 使DS18B20-DATA引脚变为输入模式
- * 输入参数: 无
- * 返 回 值: 无
- * 说 明:无
- */
- static void DS18B20_Mode_IPU(void)
- {
- gpio_init_type gpio_init_structure;
- gpio_init_structure.gpio_pins = DS18B20_DQ_GPIO_PIN;
- gpio_init_structure.gpio_pull = GPIO_PULL_NONE;
- gpio_init_structure.gpio_mode = GPIO_MODE_INPUT;
- gpio_init(DS18B20_DQ_GPIO_PORT, &gpio_init_structure);
- }
- /**
- * 函数功能: 使DS18B20-DATA引脚变为输出模式
- * 输入参数: 无
- * 返 回 值: 无
- * 说 明:无
- */
- static void DS18B20_Mode_Out_PP(void)
- {
- gpio_init_type gpio_init_structure;
-
- gpio_init_structure.gpio_pins = DS18B20_DQ_GPIO_PIN;
- gpio_init_structure.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
- gpio_init_structure.gpio_mode = GPIO_MODE_OUTPUT;
- gpio_init_structure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
- gpio_init(DS18B20_DQ_GPIO_PORT, &gpio_init_structure);
- }
- /**
- * 函数功能: 主机给从机发送复位脉冲
- * 输入参数: 无
- * 返 回 值: 无
- * 说 明:无
- */
- static void DS18B20_Rst(void)
- {
- DS18B20_Mode_Out_PP();
- DS18B20_DQ_0;
- delay_us(750);
- DS18B20_DQ_1;
- delay_us(15);
- }
- /**
- * 函数功能: 检测从机给主机返回的存在脉冲
- * 输入参数: 无
- * 返 回 值: 0:成功,1:失败
- * 说 明:无
- */
- static uint8_t DS18B20_Presence(void)
- {
- uint8_t pulse_time = 0;
-
- DS18B20_Mode_IPU();
- while( DS18B20_DQ_IN() && pulse_time<100 )
- {
- pulse_time++;
- delay_us(1);
- }
- if( pulse_time >=100 )
- return 1;
- else
- pulse_time = 0;
-
- while( !DS18B20_DQ_IN() && pulse_time<240 )
- {
- pulse_time++;
- delay_us(1);
- }
- if( pulse_time >=240 )
- return 1;
- else
- return 0;
- }
- /**
- * 函数功能: 从DS18B20读取一个bit
- * 输入参数: 无
- * 返 回 值: 读取到的数据
- * 说 明:无
- */
- static uint8_t DS18B20_ReadBit(void)
- {
- uint8_t dat;
-
- DS18B20_Mode_Out_PP();
- DS18B20_DQ_0;
- delay_us(10);
- DS18B20_Mode_IPU();
- if( DS18B20_DQ_IN() == SET )
- dat = 1;
- else
- dat = 0;
- delay_us(45);
-
- return dat;
- }
- /**
- * 函数功能: 从DS18B20读一个字节,低位先行
- * 输入参数: 无
- * 返 回 值: 读到的数据
- * 说 明:无
- */
- static uint8_t DS18B20_ReadByte(void)
- {
- uint8_t i, j, dat = 0;
-
- for(i=0; i<8; i++)
- {
- j = DS18B20_ReadBit();
- dat = (dat) | (j<<i);
- }
-
- return dat;
- }
- /**
- * 函数功能: 写一个字节到DS18B20,低位先行
- * 输入参数: dat:待写入数据
- * 返 回 值: 无
- * 说 明:无
- */
- static void DS18B20_WriteByte(uint8_t dat)
- {
- uint8_t i, testb;
- DS18B20_Mode_Out_PP();
-
- for( i=0; i<8; i++ )
- {
- testb = dat&0x01;
- dat = dat>>1;
- /* 写0和写1的时间至少要大于60us */
- if (testb)
- {
- DS18B20_DQ_0;
- /* 1us < 这个延时 < 15us */
- delay_us(8);
-
- DS18B20_DQ_1;
- delay_us(58);
- }
- else
- {
- DS18B20_DQ_0;
- /* 60us < Tx 0 < 120us */
- delay_us(70);
-
- DS18B20_DQ_1;
- /* 1us < Trec(恢复时间) < 无限大*/
- delay_us(2);
- }
- }
- }
- /**
- * 函数功能: 跳过匹配 DS18B20 ROM
- * 输入参数: 无
- * 返 回 值: 无
- * 说 明:无
- */
- static void DS18B20_SkipRom ( void )
- {
- DS18B20_Rst();
- DS18B20_Presence();
- DS18B20_WriteByte(0XCC); /* 跳过 ROM */
- }
- /**
- * 函数功能: 执行匹配 DS18B20 ROM
- * 输入参数: 无
- * 返 回 值: 无
- * 说 明:无
- */
- static void DS18B20_MatchRom ( void )
- {
- DS18B20_Rst();
- DS18B20_Presence();
- DS18B20_WriteByte(0X55);
- }
- /**
- * 函数功能: 在跳过匹配 ROM 情况下获取 DS18B20 温度值
- * 输入参数: 无
- * 返 回 值: 温度值
- * 说 明:无
- */
- float DS18B20_GetTemp_SkipRom ( void )
- {
- uint8_t tpmsb, tplsb;
- short s_tem;
- float f_tem;
-
- DS18B20_SkipRom ();
- DS18B20_WriteByte(0X44); /* 开始转换 */
-
- DS18B20_SkipRom ();
- DS18B20_WriteByte(0XBE); /* 读温度值 */
-
- tplsb = DS18B20_ReadByte();
- tpmsb = DS18B20_ReadByte();
-
- 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;
- }
- /**
- * 函数功能: 在匹配 ROM 情况下获取 DS18B20 温度值
- * 输入参数: ds18b20_id:用于存放 DS18B20 序列号的数组的首地址
- * 返 回 值: 无
- * 说 明:无
- */
- void DS18B20_ReadId ( uint8_t * ds18b20_id )
- {
- uint8_t uc;
-
- DS18B20_WriteByte(0x33); //读取序列号
-
- for ( uc = 0; uc < 8; uc ++ )
- ds18b20_id [ uc ] = DS18B20_ReadByte();
- }
- /**
- * 函数功能: 在匹配 ROM 情况下获取 DS18B20 温度值
- * 输入参数: ds18b20_id:存放 DS18B20 序列号的数组的首地址
- * 返 回 值: 温度值
- * 说 明:无
- */
- float DS18B20_GetTemp_MatchRom ( uint8_t * ds18b20_id )
- {
- uint8_t tpmsb, tplsb, i;
- short s_tem;
- float f_tem;
-
- DS18B20_MatchRom (); //匹配ROM
-
- for(i=0;i<8;i++)
- DS18B20_WriteByte ( ds18b20_id [ i ] );
-
- DS18B20_WriteByte(0X44); //开始转换
- DS18B20_MatchRom (); //匹配ROM
-
- for(i=0;i<8;i++)
- DS18B20_WriteByte ( ds18b20_id [ i ] );
-
- DS18B20_WriteByte(0XBE); //读温度值
-
- tplsb = DS18B20_ReadByte();
- tpmsb = DS18B20_ReadByte();
-
- 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;
- }
main.c
- /* includes */
- #include "at32m412_416_board.h"
- #include "at32m412_416_clock.h"
- #include "lcd_st7735.h"
- #include "DS18B20.h"
- int main(void)
- {
- uint8_t i, DS18B20ID[8];
- char str[50];
- float temperature;
-
- system_clock_config();
- at32_board_init();
- uart_print_init(115200);
- LcdInit();
- printf("DS18B20温度传感器信息读取\n");
- LcdFill(0,0,128,160,BLACK);
- LcdShowString(2,24,"DS18B20",RED, BLACK,16);
- LcdShow16x16Hz(60, 24, 10, YELLOW, BLACK);
- LcdShow16x16Hz(76, 24, 11, YELLOW, BLACK);
- LcdShow16x16Hz(92, 24, 12, YELLOW, BLACK);
- LcdShow16x16Hz(108, 24, 13, YELLOW, BLACK);
- LcdShow16x16Hz(2, 48, 14, YELLOW, BLACK);
- LcdShow16x16Hz(18, 48, 15, YELLOW, BLACK);
- LcdShow16x16Hz(34, 48, 16, YELLOW, BLACK);
- LcdShow16x16Hz(50, 48, 17, YELLOW, BLACK);
- LcdShow16x16Hz(66, 48, 18, YELLOW, BLACK);
- delay_ms(2000);
- while(DS18B20_Init())
- {
- printf("DS18B20温度传感器不存在\n");
- LcdFill(0,0,128,160,BLACK);
- LcdShowString(2,24,"DS18B20",RED, BLACK,16);
- LcdShow16x16Hz(60, 24, 10, YELLOW, BLACK);
- LcdShow16x16Hz(76, 24, 11, YELLOW, BLACK);
- LcdShow16x16Hz(92, 24, 12, YELLOW, BLACK);
- LcdShow16x16Hz(108, 24, 13, YELLOW, BLACK);
- LcdShow16x16Hz(2, 48, 14, YELLOW, BLACK);
- LcdShow16x16Hz(18, 48, 19, YELLOW, BLACK);
- LcdShow16x16Hz(34, 48, 20, YELLOW, BLACK);
- LcdShow16x16Hz(50, 48, 21, YELLOW, BLACK);
- delay_ms(1000);
- }
- printf("检测到DS18B20温度传感器,并初始化成功\n");
- LcdFill(0,0,128,160,BLACK);
- LcdShow16x16Hz(2, 24, 22, YELLOW, BLACK);
- LcdShow16x16Hz(18, 24, 23, YELLOW, BLACK);
- LcdShow16x16Hz(34, 24, 24, YELLOW, BLACK);
- LcdShowString(50,24,"DS18B20",RED, BLACK,16);
- LcdShow16x16Hz(108, 24, 10, YELLOW, BLACK);
- LcdShow16x16Hz(2, 48, 11, YELLOW, BLACK);
- LcdShow16x16Hz(18, 48, 12, YELLOW, BLACK);
- LcdShow16x16Hz(34, 48, 13, YELLOW, BLACK);
- LcdShow16x16Hz(50, 48, 14, YELLOW, BLACK);
- LcdShowString(66,48,",",YELLOW, BLACK,16);
- LcdShow16x16Hz(74, 48, 25, YELLOW, BLACK);
- LcdShow16x16Hz(90, 48, 26, YELLOW, BLACK);
- LcdShow16x16Hz(106, 48, 27, YELLOW, BLACK);
- LcdShow16x16Hz(2, 72, 28, YELLOW, BLACK);
- LcdShow16x16Hz(18, 72, 29, YELLOW, BLACK);
- LcdShow16x16Hz(34, 72, 30, YELLOW, BLACK);
-
- DS18B20_ReadId(DS18B20ID);
- printf("DS18B20的序列号是: 0x");
- for ( i = 0; i < 8; i ++ )
- printf ( "%.2X", DS18B20ID[i]);
- printf("\n");
-
- sprintf(str,"0x%02X%02X%02X%02X%02X%02X%02X%02X",DS18B20ID[0],DS18B20ID[1],DS18B20ID[2],DS18B20ID[3],
- DS18B20ID[4],DS18B20ID[5],DS18B20ID[6],DS18B20ID[7]);
-
- LcdShowString(8,96,"DS18B20",RED, BLACK,12);
- LcdShow16x16Hz(50, 96, 32, YELLOW, BLACK);
- LcdShow16x16Hz(66, 96, 33, YELLOW, BLACK);
- LcdShow16x16Hz(82, 96, 34, YELLOW, BLACK);
- LcdShow16x16Hz(98, 96, 35, YELLOW, BLACK);
- LcdShow16x16Hz(114, 96, 40, YELLOW, BLACK);
- LcdShowString(8,120,str,RED,BLACK,12);
- delay_ms(2000);
- while(1)
- {
- temperature=DS18B20_GetTemp_MatchRom(DS18B20ID);
- /* 打印通过 DS18B20 序列号获取的温度值 */
- printf("获取该序列号器件的温度:%.1f\n",temperature);
- LcdFill(0,0,128,160,BLACK);
- LcdShow16x16Hz(2, 8, 36, YELLOW, BLACK);
- LcdShow16x16Hz(18, 8, 37, YELLOW, BLACK);
- LcdShow16x16Hz(34, 8, 10, YELLOW, BLACK);
- LcdShow16x16Hz(50, 8, 11, YELLOW, BLACK);
- LcdShow16x16Hz(66, 8, 38, YELLOW, BLACK);
- LcdShow16x16Hz(82, 8, 39, YELLOW, BLACK);
- LcdShow16x16Hz(98, 8, 40, YELLOW, BLACK);
- LCD_ShowFloatNum1(8,32,temperature,4,RED, BLACK,24);
- LcdShow16x16Hz(70, 36, 41, RED, BLACK);
- /* 0.5s 读取一次温度值 */
- delay_ms(500);
- }
- }
以上代码均在上一个驱动LCD工程上完成,因此直接下载到开发板后,可以在LCD屏上直观得看到DS18B20实时采集的温度值变化。当然也是支持串口同步打印输出温度值变化的。
例如串口打印信息:
一段实时操作演示见B站视频:https://www.bilibili.com/video/BV1YFNnzrENG/