准备物件

  • 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温度传感器数据的更多相关文章

  1. 树莓派通过模数转换芯片ADC0832读取LM35温度传感器数据

    树莓派通过模数转换芯片ADC0832读取LM35温度传感器数据 今天和小朋友一起玩树莓派,打算来做一个测量室温的小实验.经过几个小时的研究和测试,终于能够成功读取LM35传感器的温度数据了.本文主要记 ...

  2. 用struts2标签如何从数据库获取数据并在查询页面显示。最近做一个小项目,需要用到struts2标签从数据库查询数据,并且用迭代器iterator标签在查询页面显示,可是一开始,怎么也获取不到数据,想了许久,最后发现,是自己少定义了一个变量,也就是var变量。

    最近做一个小项目,需要用到struts2标签从数据库查询数据,并且用迭代器iterator标签在查询页面显示,可是一开始,怎么也获取不到数据,想了许久,最后发现,是自己少定义了一个变量,也就是var变 ...

  3. 读取TDrawGrid之获取博易数据

    朋友叫我帮忙写个从博易读取数据的工具,可无奈数据所在控件并不是Windows标准控件,也就是说没办法通过发送系统消息来获取 相关数据,于是乎试了一下从内存直接读取,可最后并不能达到预期目的,原因是笔者 ...

  4. C#中,使用正式表达式匹配获取所需数据

    .NET中,使用正式表达式匹配获取所需数据 需求:获取一串字符串中,正则匹配出需要的数据. 例如以下字符串: string temp ="ErrorCode:-1,Message:{&quo ...

  5. 速战速决 (6) - PHP: 获取 http 请求数据, 获取 get 数据 和 post 数据, json 字符串与对象之间的相互转换

    [源码下载] 速战速决 (6) - PHP: 获取 http 请求数据, 获取 get 数据 和 post 数据, json 字符串与对象之间的相互转换 作者:webabcd 介绍速战速决 之 PHP ...

  6. iOS 直播-获取音频(视频)数据

    iOS 直播-获取音频(视频)数据 // // ViewController.m // capture-test // // Created by caoxu on 16/6/3. // Copyri ...

  7. OpenGL ES无法获取贴图数据原因

    最近在做一个项目,要从贴图中获取图像数据,查了很多资料,也琢磨很久,获取到的数据都是0.终于在一次偶然的机会,发现了端倪,成功了. 不得不说这"一分灵感"真的很重要 以下是在获取贴 ...

  8. 使用腾讯开发平台获取QQ用户数据资料

    <今天是七夕:祝大家七夕嗨皮,前可么么哒,后可啪啪啪> Tips:本篇博客将教你如何使用腾讯开发平台获取QQ用户资料 ----------------------------------- ...

  9. qt qml ajax 获取 json 天气数据示例

    依赖ajax.js类库,以下代码很简单的实现了获取天气json数据并展示的任务 [TestAjax.qml] import QtQuick 2.0 import "ajax.js" ...

随机推荐

  1. Web前端入门了解

    Web就是指万维网,网站,Web开发的方向包括Web前端,Web后台. Web前端又分为  静态Web 和 动态Web, 静态Web就是用HTML实现的. 动态Web的实现方式有多种. 动态Web的实 ...

  2. How to force the UI to refresh immediately(WPF)

    Question 0 Sign in to vote Folks, In my application, when the user hits "Submit" button, I ...

  3. XE6 FMX之控件绘制与显示

    中午,有个货随手买的2块钱的彩票,尼玛中了540块,这是啥子狗屎气运.稍微吐槽一下,现在开始正规的笔记录入.经常有朋友说为毛我的博客不更新了或者说更新的少了,为啥呢!一来自己懒了,没学习什么新的东西, ...

  4. DeviceOne开发HelloWord

    http://www.cnblogs.com/wjiaonianhua/p/5278061.html http://www.jb51.net/article/75693.htm 2015 年 9 月 ...

  5. (转载)javascript函数作用域和提前声明

    http://www.cnblogs.com/ArthurPatten/p/3274080.html 一些语言如C.java都有块级作用域,即花括号内的每一段代码都具有各自的作用域,而且变量在声明它们 ...

  6. Hibernate HQL和原生SQL查询的一点区别

    1.createSQLQuery 1.1默认查询的结果为BigDecimal 1.2通过addScalar("CGD_ID", StandardBasicTypes.LONG)可以 ...

  7. 修改LiteIDE 编辑窗口的主题

    用习惯了Visual Studio 再看其他编译器总是有点别扭,当然LiteIDE 也是能够自定义主题的,再次感叹作者的用心. 依次: 查看 -> 选项 -> LiteEditor 在编辑 ...

  8. 如何把一个表中的部分字段值插入到另一个表中去 这sql吊

    Insert into  JHAC_TB_CODE(CID,CODE,ADD_TIME,USERID,PRO_CODE,USERNAME)  select f_code.FID,f_code.Fcod ...

  9. window7下statsvn统计代码量

    下载statsvn:http://www.statsvn.org/ 将下载后的statsvn.jar放到d:\svn目录下; 打开cmd窗口切换到需要统计代码的项目目录如:d:\project\web ...

  10. Java泛型学习

    1.泛型的概念 泛型即"参数化类型",就比如我们定义方法的时候,定义一个变量,称为形参,变量值根据传进去的实参的值不同而改变.而泛型的出现,就是为了解决类型也能根据传进去的类型改变 ...