STM32获取DHT11温度传感器数据
准备物件
- STM32F103C8T6核心板
- ST-LINK V2
- DHT11
- 杜邦线若干
连接线
STM32F103C8T6芯片管脚图
管脚说明
连接仿真器
STM32 | ST-LINKV2 |
---|---|
VCC | VCC |
GND | GND |
SWCLK | SWCLK |
SWDIO | SWDIO |
创建工程
参考STM32F103X 开发环境搭建
可将其模板复制一份
添加延时功能
在DRIVER/inc
中添加timer.h
#ifndef __TIMER_H__
#define __TIMER_H__
#include "stm32f10x.h"
void systick_init(void);
void timing_delay_decrement(void);
void delay_us(__IO uint32_t n);
#endif
对应的在DRIVER/src
中添加timer.c
#include "timer.h"
__IO uint32_t gTimingDelay;
/* SystemCoreClock / 1000 --> 1ms */
/* SystemCoreClock / 10000 --> 100us */
/* SystemCoreClock / 100000 --> 10us */
/* SystemCoreClock / 1000000 --> 1us */
void systick_init(void)
{
while (SysTick_Config(SystemCoreClock / 1000000) == 1);
}
void timing_delay_decrement(void)
{
if (gTimingDelay != 0x0)
{
gTimingDelay--;
}
}
void SysTick_Handler(void)
{
timing_delay_decrement();
}
void delay_us(__IO uint32_t n)
{
gTimingDelay = n;
while(gTimingDelay != 0);
}
点亮LED
可以看到核心板上有两个LED灯,PWR(电源)和PC13
修改USER/main.c
#include "stm32f10x.h"
#include "timer.h"
#define Led_On GPIO_SetBits(GPIOC, GPIO_Pin_13)
#define Led_Off GPIO_ResetBits(GPIOC, GPIO_Pin_13)
void LED_Init()
{
GPIO_InitTypeDef s;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
s.GPIO_Pin = GPIO_Pin_13;
s.GPIO_Mode = GPIO_Mode_Out_PP;
s.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &s);
}
int main()
{
SystemInit();
systick_init();
LED_Init();
while (1)
{
Led_On;
delay_us(500000);
Led_Off;
delay_us(500000);
}
}
<1> 由于timer.c已经实现SysTick_handler
中断实现,需要编辑USER/stm32f10x_it.c
,将SysTick_handler
函数注释
<2> 右击工程名 -> Options -> C/C++ Compiler -> Preprocessor
在"Additional include directories:"中添加$PROJ_DIR$\USER\inc\
<3> 右击工程名 -> Options -> Debugger -> Setup
在Driver中选择ST-LINK
<4> 右击工程名 -> Options -> ST-LINK -> Setup
在Reset选择Connect during reset
在Interface中选择SWD
<5> 点击编译,然后Download and Debug
-> Go
便可以看到PC13 LED灯均匀的闪烁。
串口发送数据
用于显示DHT11读取的数据
连线方式
USB-TTL | STM32 |
---|---|
VCC | VCC |
GND | GND |
RXD | PA9(TXD) |
TXD | PA10(RXD) |
如果是树莓派,可以查看GPIO管脚说明,按照上述连接即可。
添加DRIVER/inc/usart.h
#ifndef __USART_H_
#define __USART_H_
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_usart.h"
#include <stdarg.h>
#define WAIT_TC while(USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
void usart_config(void);
void usart_gpio_init(void);
void usart_param_config(void);
void usart_send_string(char *data);
void usart_printf(const char *fmt, ...);
#endif
添加DRIVER/src/usart.c
#include "usart.h"
void usart_config(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
usart_gpio_init();
usart_param_config();
}
void usart_gpio_init(void)
{
GPIO_InitTypeDef g;
g.GPIO_Speed = GPIO_Speed_50MHz;
g.GPIO_Pin = GPIO_Pin_9;
g.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &g);
g.GPIO_Pin = GPIO_Pin_10;
g.GPIO_Mode = GPIO_Mode_IN_FLOATING; //开漏输入
GPIO_Init(GPIOA, &g);
}
void usart_param_config(void)
{
USART_InitTypeDef u;
u.USART_BaudRate = 9600;
u.USART_WordLength = USART_WordLength_8b; //数据位8位
u.USART_StopBits = USART_StopBits_1; //停止位1位
u.USART_Parity = USART_Parity_No; //无校验位
u.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
u.USART_Mode = USART_Mode_Tx;
USART_Init(USART1, &u);
USART_Cmd(USART1, ENABLE);
}
void usart_send_string(char *data)
{
char *p = data;
while (p < data + strlen(data))
{
WAIT_TC;
USART_SendData(USART1, *p++);
}
}
void usart_printf(const char *fmt, ...)
{
va_list ap;
char string[64];
va_start(ap, fmt);
vsprintf(string, fmt, ap);
va_end(ap);
usart_send_string(string);
}
main.c
添加如下细节
#include "usart.h"
int main()
{
SystemInit();
systick_init();
usart_config();
LED_Init();
while (1)
{
Led_On;
usart_printf("test usart\n");
delay_us(2000000);
Led_Off;
delay_us(2000000);
}
}
打开串口工具,linux下是minicom
minicom -b 9600 -D /dev/ttyUSB0
可以看到test usart
字符,说明串口通信正常。
驱动DHT11
连线方式
DHT11 | STM32 |
---|---|
VCC | VCC |
GND | GND |
DATA | PB11 |
添加DRIVER/inc/dht11.h
#ifndef __DHT11_H__
#define __DHT11_H__
#include "timer.h"
#include "stm32f10x_gpio.h"
#define DHT11_GPIO_TYPE GPIOB
#define DHT11_GPIO_PIN GPIO_Pin_11
#define DHT11_RCC RCC_APB2Periph_GPIOB
#define DHT11_OUT_H GPIO_SetBits(DHT11_GPIO_TYPE, DHT11_GPIO_PIN)
#define DHT11_OUT_L GPIO_ResetBits(DHT11_GPIO_TYPE, DHT11_GPIO_PIN)
#define DHT11_IN GPIO_ReadInputDataBit(DHT11_GPIO_TYPE, DHT11_GPIO_PIN)
void dht11_gpio_input(void);
void dht11_gpio_output(void);
u16 dht11_scan(void);
u16 dht11_read_bit(void);
u16 dht11_read_byte(void);
u16 dht11_read_data(u8 buffer[4]);
#endif
添加DRIVER/src/dht11.c
#include "dht11.h"
void dht11_gpio_input(void)
{
GPIO_InitTypeDef g;
RCC_APB2PeriphClockCmd(DHT11_RCC, ENABLE);
g.GPIO_Pin = DHT11_GPIO_PIN;
g.GPIO_Speed = GPIO_Speed_50MHz;
g.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_Init(DHT11_GPIO_TYPE, &g);
}
void dht11_gpio_output(void)
{
GPIO_InitTypeDef g;
RCC_APB2PeriphClockCmd(DHT11_RCC, ENABLE);
g.GPIO_Pin = DHT11_GPIO_PIN;
g.GPIO_Speed = GPIO_Speed_50MHz;
g.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_Init(DHT11_GPIO_TYPE, &g);
}
void dht11_reset(void)
{
// 按照DHT11手册步骤
dht11_gpio_output();
DHT11_OUT_L;
delay_us(19000);
DHT11_OUT_H;
delay_us(30);
dht11_gpio_input();
}
u16 dht11_scan(void)
{
return DHT11_IN;
}
u16 dht11_read_bit(void)
{
while (DHT11_IN == RESET);
delay_us(40);
if (DHT11_IN == SET)
{
while (DHT11_IN == SET);
return 1;
}
else
{
return 0;
}
}
u16 dht11_read_byte(void)
{
u16 i;
u16 data = 0;
for (i = 0; i < 8; i++)
{
data <<= 1;
data |= dht11_read_bit();
}
return data;
}
u16 dht11_read_data(u8 buffer[5])
{
u16 i = 0;
dht11_reset();
if (dht11_scan() == RESET)
{
//检测到DHT11响应
while (dht11_scan() == RESET);
while (dht11_scan() == SET);
for (i = 0; i < 5; i++)
{
buffer[i] = dht11_read_byte();
}
while (dht11_scan() == RESET);
dht11_gpio_output();
DHT11_OUT_H;
u8 checksum = buffer[0] + buffer[1] + buffer[2] + buffer[3];
if (checksum != buffer[4])
{
// checksum error
return 1;
}
}
return 0;
}
修改USER/main.c
#include "dht11.h"
int main()
{
SystemInit();
systick_init();
usart_config();
LED_Init();
while (1)
{
Led_On;
u8 buffer[5];
double hum;
double temp;
if (dht11_read_data(buffer) == 0)
{
hum = buffer[0] + buffer[1] / 10.0;
temp = buffer[2] + buffer[3] / 10.0;
}
usart_printf("___{\"temperature\": %.2f, \"humidness\": %.2f}___\n", temp, hum);
delay_us(2000000);
Led_Off;
delay_us(2000000);
}
}
编译、运行,发现串口可以收到温度信息。
minicom -b 9600 -D /dev/ttyUSB0
STM32获取DHT11温度传感器数据的更多相关文章
- 用c#实现编写esp32单片机获取DHT11温度传感器参数
欢迎爱好c#的爱好者,本文章我们将用C#的nanoframework框架来编写获取esp32单片机上的DHT11传感器的温度和湿度 实现我们需要准备配置好esp32的环境可以看看之前写的esp32搭建 ...
- 树莓派通过模数转换芯片ADC0832读取LM35温度传感器数据
树莓派通过模数转换芯片ADC0832读取LM35温度传感器数据 今天和小朋友一起玩树莓派,打算来做一个测量室温的小实验.经过几个小时的研究和测试,终于能够成功读取LM35传感器的温度数据了.本文主要记 ...
- 用struts2标签如何从数据库获取数据并在查询页面显示。最近做一个小项目,需要用到struts2标签从数据库查询数据,并且用迭代器iterator标签在查询页面显示,可是一开始,怎么也获取不到数据,想了许久,最后发现,是自己少定义了一个变量,也就是var变量。
最近做一个小项目,需要用到struts2标签从数据库查询数据,并且用迭代器iterator标签在查询页面显示,可是一开始,怎么也获取不到数据,想了许久,最后发现,是自己少定义了一个变量,也就是var变 ...
- 读取TDrawGrid之获取博易数据
朋友叫我帮忙写个从博易读取数据的工具,可无奈数据所在控件并不是Windows标准控件,也就是说没办法通过发送系统消息来获取 相关数据,于是乎试了一下从内存直接读取,可最后并不能达到预期目的,原因是笔者 ...
- C#中,使用正式表达式匹配获取所需数据
.NET中,使用正式表达式匹配获取所需数据 需求:获取一串字符串中,正则匹配出需要的数据. 例如以下字符串: string temp ="ErrorCode:-1,Message:{&quo ...
- 速战速决 (6) - PHP: 获取 http 请求数据, 获取 get 数据 和 post 数据, json 字符串与对象之间的相互转换
[源码下载] 速战速决 (6) - PHP: 获取 http 请求数据, 获取 get 数据 和 post 数据, json 字符串与对象之间的相互转换 作者:webabcd 介绍速战速决 之 PHP ...
- iOS 直播-获取音频(视频)数据
iOS 直播-获取音频(视频)数据 // // ViewController.m // capture-test // // Created by caoxu on 16/6/3. // Copyri ...
- OpenGL ES无法获取贴图数据原因
最近在做一个项目,要从贴图中获取图像数据,查了很多资料,也琢磨很久,获取到的数据都是0.终于在一次偶然的机会,发现了端倪,成功了. 不得不说这"一分灵感"真的很重要 以下是在获取贴 ...
- 使用腾讯开发平台获取QQ用户数据资料
<今天是七夕:祝大家七夕嗨皮,前可么么哒,后可啪啪啪> Tips:本篇博客将教你如何使用腾讯开发平台获取QQ用户资料 ----------------------------------- ...
随机推荐
- 谈谈培训机构的"骗局"给新人一些建议
前言 本文只谈"骗局",不谈其他,绝不引战,如有错误,希望指出我会及时改正,想要讨论的可以在留言区写下你的观点和经历. 为什么要写这篇文章呢,近些年培训这个话题也比较火,很多在看这 ...
- vue-cli脚手架npm相关文件解读(4)utils.js
系列文章传送门: 1.build/webpack.base.conf.js 2.build/webpack.prod.conf.js 3.build/webpack.dev.conf.js 4.bui ...
- VS2015 安装nuget离线包nupkg文件
最近在做项目进度管理时,想通过安装net.sf.mpxj-for-csharp包读取.mpp格式文件,通过Nuget在线安装时,出现以下情况,无法安装,故开启离线安装道路. 离线安装步骤如下: 一.下 ...
- django开发总结
首先我用的是虚拟机,python3.6+django1.11.0: 为了版本的一致,以及在环境种更好的体验,我们需要的是先用虚拟环境virtualenv其命令有: 1.创建环境(name是虚拟环境名字 ...
- 微信原图泄露的只能是 Exif ,你的隐私不在这!!!
版权声明: 本账号发布文章均来自公众号,承香墨影(cxmyDev),版权归承香墨影所有. 每周会统一更新到这里,如果喜欢,可关注公众号获取最新文章. 未经允许,不得转载. 序 最近很多公众号都推送了关 ...
- The C++ Programming Language 学习笔记 第7章 函数
1.关于内联函数(inline) 借用一下书中的例子. inline int fac(int n) { ) ? :n*fac(n-); } inline描述符给编译器一个提示,要求 ...
- [2017-08-25]100行CSharp代码利用dynamic写个DSL(特定领域语言)
最近看<CLR via C#(第4版)> 读到第五章末尾dynamic基元类型时,看了下作者的一个利用dynamic动态调用string类型的Contains方法(静态方法)的实现,突然发 ...
- 大数据平台搭建-spark集群安装
版本要求 java 版本:1.8.*(1.8.0_60) 下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downl ...
- 性能测试系列学习 day1
性能测试的最终目标是为了最大限度的满足用户的需求,我们通常为了达到以下目标而进行性能测试: (1)评估系统的能力:测试中得到的负荷和响应时间数据可以被用于验证所计划的模型的能力,并帮助作出决策: (2 ...
- 最近找java实习面试被问到的东西总结(Java方向)
时间,就是这么很悄悄的溜走了将近两个年华,不知不觉的,研二了,作为一个一般学校的研究生,不知道该说自己是不学无术,还是说有过努力,反正,这两年里,有过坚持,有过堕落,这不,突然间,有种开窍的急迫感,寻 ...