2716|2

1237

帖子

66

TA的资源

纯净的硅(中级)

楼主
 

【GD32L233C-START评测】三、GPIO应用之驱动单总线温湿度传感器DHT11 [复制链接]

 

GPIO是使用最广泛的外设之一,可以用来进行输入输出,驱动一些特殊时序的传感器。DHT11是一款有已校准数字信号输出的温湿度传感器。 其精度湿度±5%RH, 温度±2℃,量程湿度5~95%RH, 温度-20~+60℃。

手头有一块兼容arduino uno v3接口的机智云的gokit板卡,上面正好有DHT11温湿度传感器。原理图如下:

对比GD32L233C-START原理图可知,信号脚连接的是PB5.

GD32L233固件库和stm32标准固件库类似,个人认为GD32的api设计使用更加方便、简洁。一共有5组GPIO:

/* GPIOx(x=A,B,C,D,F) definitions */
#define GPIOA                      (GPIO_BASE + 0x00000000U)       /*!< GPIOA base address */
#define GPIOB                      (GPIO_BASE + 0x00000400U)       /*!< GPIOB base address */
#define GPIOC                      (GPIO_BASE + 0x00000800U)       /*!< GPIOC base address */
#define GPIOD                      (GPIO_BASE + 0x00000C00U)       /*!< GPIOD base address */
#define GPIOF                      (GPIO_BASE + 0x00001400U)       /*!< GPIOF base address */

每组有16个管脚:

/* GPIO pin definitions */
#define GPIO_PIN_0                 BIT(0)                          /*!< GPIO pin 0 */
#define GPIO_PIN_1                 BIT(1)                          /*!< GPIO pin 1 */
#define GPIO_PIN_2                 BIT(2)                          /*!< GPIO pin 2 */
#define GPIO_PIN_3                 BIT(3)                          /*!< GPIO pin 3 */
#define GPIO_PIN_4                 BIT(4)                          /*!< GPIO pin 4 */
#define GPIO_PIN_5                 BIT(5)                          /*!< GPIO pin 5 */
#define GPIO_PIN_6                 BIT(6)                          /*!< GPIO pin 6 */
#define GPIO_PIN_7                 BIT(7)                          /*!< GPIO pin 7 */
#define GPIO_PIN_8                 BIT(8)                          /*!< GPIO pin 8 */
#define GPIO_PIN_9                 BIT(9)                          /*!< GPIO pin 9 */
#define GPIO_PIN_10                BIT(10)                         /*!< GPIO pin 10 */
#define GPIO_PIN_11                BIT(11)                         /*!< GPIO pin 11 */
#define GPIO_PIN_12                BIT(12)                         /*!< GPIO pin 12 */
#define GPIO_PIN_13                BIT(13)                         /*!< GPIO pin 13 */
#define GPIO_PIN_14                BIT(14)                         /*!< GPIO pin 14 */
#define GPIO_PIN_15                BIT(15)                         /*!< GPIO pin 15 */
#define GPIO_PIN_ALL               BITS(0, 15)                     /*!< GPIO pin all */

关于gpio的所有API如下,通过函数命名和固件库里面的注释就很容易知晓其用法了:

/* function declarations */
/* reset GPIO port */
void gpio_deinit(uint32_t gpio_periph);
/* set GPIO mode */
void gpio_mode_set(uint32_t gpio_periph, uint32_t mode, uint32_t pull_up_down, uint32_t pin);
/* set GPIO output type and speed */
void gpio_output_options_set(uint32_t gpio_periph, uint8_t otype, uint32_t speed, uint32_t pin);

/* set GPIO pin bit */
void gpio_bit_set(uint32_t gpio_periph, uint32_t pin);
/* reset GPIO pin bit */
void gpio_bit_reset(uint32_t gpio_periph, uint32_t pin);
/* write data to the specified GPIO pin */
void gpio_bit_write(uint32_t gpio_periph, uint32_t pin, bit_status bit_value);
/* write data to the specified GPIO port */
void gpio_port_write(uint32_t gpio_periph, uint16_t data);

/* get GPIO pin input status */
FlagStatus gpio_input_bit_get(uint32_t gpio_periph, uint32_t pin);
/* get GPIO port input status */
uint16_t gpio_input_port_get(uint32_t gpio_periph);
/* get GPIO pin output status */
FlagStatus gpio_output_bit_get(uint32_t gpio_periph, uint32_t pin);
/* get GPIO port output status */
uint16_t gpio_output_port_get(uint32_t gpio_periph);

/* set GPIO alternate function */
void gpio_af_set(uint32_t gpio_periph, uint32_t alt_func_num, uint32_t pin);
/* lock GPIO pin bit */
void gpio_pin_lock(uint32_t gpio_periph, uint32_t pin);

/* toggle GPIO pin status */
void gpio_bit_toggle(uint32_t gpio_periph, uint32_t pin);
/* toggle GPIO port status */
void gpio_port_toggle(uint32_t gpio_periph);

编写dht11驱动头文件DHT.h如下:

#ifndef DHT_H_
#define DHT_H_

#include "gd32l23x.h"

#define DHT_TIMEOUT 				10000		

typedef struct {
	float hum;
	float temp;
} DHT_data;

typedef enum {
	DHT11,
	DHT22
} DHT_type;

typedef struct {
	uint32_t DHT_Port;	
	uint16_t DHT_Pin;		
	DHT_type type;			
	uint8_t pullUp;			
} DHT_sensor;

DHT_data DHT_getData(DHT_sensor *sensor); 

#endif

 

编写dht11驱动源文件DHT.c如下:

#include "DHT.h"

#define lineDown() 	gpio_bit_reset(sensor->DHT_Port, sensor->DHT_Pin)  
#define lineUp()		gpio_bit_set(sensor->DHT_Port, sensor->DHT_Pin)  
#define getLine()		(gpio_input_bit_get(sensor->DHT_Port, sensor->DHT_Pin) == SET)
#define Delay(d)		delay_ms(d)

static void goToOutput(DHT_sensor *sensor) 
{
  lineUp();
  if(sensor->pullUp == 1) 	
	{
	  gpio_mode_set(sensor->DHT_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, sensor->DHT_Pin);
  } 
	else 
	{
	 gpio_mode_set(sensor->DHT_Port, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, sensor->DHT_Pin);
  }	  
	gpio_output_options_set(sensor->DHT_Port, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, sensor->DHT_Pin);
}

static void goToInput(DHT_sensor *sensor) 
{
  if(sensor->pullUp == 1) 
	{
	  gpio_mode_set(sensor->DHT_Port, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, sensor->DHT_Pin);			
  } 
	else 
	{
	   gpio_mode_set(sensor->DHT_Port, GPIO_MODE_INPUT, GPIO_PUPD_NONE, sensor->DHT_Pin);			
  }
}

DHT_data DHT_getData(DHT_sensor *sensor) 
{
	DHT_data data = {0.0f, 0.0f};
	goToOutput(sensor);
	lineDown();
	Delay(15);
	lineUp();
	goToInput(sensor);
	uint16_t timeout = 0;
	while(getLine()) {
		timeout++;
		if (timeout > DHT_TIMEOUT) return data;
	}
	timeout = 0;
	while(!getLine()) {
		timeout++;
		if (timeout > DHT_TIMEOUT) return data;
	}
	timeout = 0;
	while(getLine()) {
		timeout++;
		if (timeout > DHT_TIMEOUT) return data;
	}
	
	uint8_t rawData[5] = {0,0,0,0,0};
	for(uint8_t a = 0; a < 5; a++) {
		for(uint8_t b = 7; b != 255; b--) {
			uint32_t hT = 0, lT = 0;
			while(!getLine()) lT++;
			timeout = 0;
			while(getLine()) hT++;
			if(hT > lT) rawData[a] |= (1<<b);
		}
	}
	if((uint8_t)(rawData[0] + rawData[1] + rawData[2] + rawData[3]) == rawData[4]) {
		if (sensor->type == DHT22) {
			data.hum = (float)(((uint16_t)rawData[0]<<8) | rawData[1])*0.1f;
			if(!(rawData[2] & (1<<7))) {
				data.temp = (float)(((uint16_t)rawData[2]<<8) | rawData[3])*0.1f;
			}	else {
				rawData[2] &= ~(1<<7);
				data.temp = (float)(((uint16_t)rawData[2]<<8) | rawData[3])*-0.1f;
			}
		}
		if (sensor->type == DHT11) {
			data.hum = (float)rawData[0];
			data.temp = (float)rawData[2];;
		}
	}
	return data;	
}

 

main.c测试代码:

#include "gd32l23x.h"
#include "DHT.h"
#include "delay.h"
static DHT_sensor livingRoom = {GPIOB, GPIO_PIN_5, DHT11, 0};
DHT_data d;
int main(void)
{
	delay_init();
    rcu_periph_clock_enable(RCU_GPIOB);	
    while(1) 
	{
		d = DHT_getData(&livingRoom); 
        delay_ms(500);				
    }
}

 

测试调试效果:

此帖出自GD32 MCU论坛

最新回复

用结构构来写驱动,值得学习,谢谢了,以后还得多学习大佬的作品。  详情 回复 发表于 2022-5-18 09:11
点赞 关注
 

回复
举报

6587

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

这个DHT11也确实常用,

GD32的api也确实用起来方便

此帖出自GD32 MCU论坛
 
 
 

回复

6841

帖子

11

TA的资源

版主

板凳
 
用结构构来写驱动,值得学习,谢谢了,以后还得多学习大佬的作品。
此帖出自GD32 MCU论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表