STM32 入门 + 传感器采集 + 显示 综合实验

STM32 入门 + 传感器采集 + 显示 综合实验,基于 STM32F103C8T6(蓝桥杯/最小系统板)。


一、系统总体方案

复制代码
温湿度传感器  →  USART1(RX)  →  STM32F103
                                       │
                                       ├── USART2(TX) → PC串口助手(调试)
                                       └── GPIO → 74HC595 → 4位数码管

硬件选型(最常见组合)

模块 型号 说明
MCU STM32F103C8T6 72MHz,3.3V
温湿度 DHT11 单总线(简单)
数码管 4位共阳/共阴 带 74HC595 移位寄存器
下载 ST-Link V2 SWD 接口

推荐 :如果你不想自己写 DHT11 驱动,也可以用 SHT30(I2C),稳定性更好。


二、硬件连接表(重点)

1、DHT11 → STM32

DHT11 STM32F103 说明
VCC 3.3V
GND GND
DATA PA0 推挽输出 / 输入切换

2、数码管(74HC595) → STM32

74HC595 STM32 说明
SER PB12 数据
RCLK PB13 锁存
SRCLK PB14 时钟
OE GND 使能
VCC 5V 数码管供电

数码管类型一定要确认

  • 共阳:段码取反
  • 共阴:段码原样

三、核心源码

1、DHT11 驱动(单总线)

c 复制代码
// dht11.h
#ifndef __DHT11_H
#define __DHT11_H

#include "stm32f10x.h"

uint8_t DHT11_Read(uint8_t *temp, uint8_t *humi);

#endif
c 复制代码
// dht11.c
#include "dht11.h"
#include "delay.h"

#define DHT11_PIN GPIO_Pin_0
#define DHT11_PORT GPIOA

static void DHT11_Mode_OUT(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = DHT11_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(DHT11_PORT, &GPIO_InitStructure);
}

static void DHT11_Mode_IN(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = DHT11_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(DHT11_PORT, &GPIO_InitStructure);
}

uint8_t DHT11_Read(uint8_t *temp, uint8_t *humi)
{
    uint8_t buf[5] = {0};
    uint8_t i, j;

    DHT11_Mode_OUT();
    GPIO_ResetBits(DHT11_PORT, DHT11_PIN);
    Delay_ms(18);
    GPIO_SetBits(DHT11_PORT, DHT11_PIN);
    Delay_us(30);
    DHT11_Mode_IN();

    if(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN) != 0)
        return 1;

    while(!GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN));
    while(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN));

    for(i=0;i<5;i++)
    {
        for(j=0;j<8;j++)
        {
            while(!GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN));
            Delay_us(40);
            buf[i] <<= 1;
            if(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN))
                buf[i] |= 1;
            while(GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN));
        }
    }

    if(buf[0]+buf[1]+buf[2]+buf[3] != buf[4])
        return 2;

    *humi = buf[0];
    *temp = buf[2];
    return 0;
}

2、74HC595 驱动数码管

c 复制代码
// seg.c
#include "seg.h"
#include "stm32f10x_gpio.h"

#define SER_H()   GPIO_SetBits(GPIOB, GPIO_Pin_12)
#define SER_L()   GPIO_ResetBits(GPIOB, GPIO_Pin_12)
#define RCLK_H()  GPIO_SetBits(GPIOB, GPIO_Pin_13)
#define RCLK_L()  GPIO_ResetBits(GPIOB, GPIO_Pin_13)
#define SRCLK_H() GPIO_SetBits(GPIOB, GPIO_Pin_14)
#define SRCLK_L() GPIO_ResetBits(GPIOB, GPIO_Pin_14)

// 共阳数码管段码(0~9)
const uint8_t SegCode[10] = {
    0xC0,0xF9,0xA4,0xB0,0x99,
    0x92,0x82,0xF8,0x80,0x90
};

void Seg_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}

void Seg_SendByte(uint8_t dat)
{
    for(uint8_t i=0;i<8;i++)
    {
        (dat & 0x80) ? SER_H() : SER_L();
        SRCLK_H(); SRCLK_L();
        dat <<= 1;
    }
}

void Seg_Display(uint16_t num)
{
    Seg_SendByte(SegCode[num/1000]);
    Seg_SendByte(SegCode[num%1000/100]);
    Seg_SendByte(SegCode[num%100/10]);
    Seg_SendByte(SegCode[num%10]);
    RCLK_H(); RCLK_L();
}

3、串口打印(调试用)

c 复制代码
// usart.c
void USART1_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    USART_InitStructure.USART_BaudRate = 115200;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Tx;

    USART_Init(USART1, &USART_InitStructure);
    USART_Cmd(USART1, ENABLE);
}

4、Main 主逻辑

c 复制代码
int main(void)
{
    uint8_t temp = 0, humi = 0;

    Delay_Init();
    Seg_Init();
    USART1_Init();

    while(1)
    {
        if(DHT11_Read(&temp, &humi) == 0)
        {
            // 显示温度(例如 25°C → 显示 25)
            Seg_Display(temp);

            // 串口打印
            printf("Temp:%dC Humi:%d%%\r\n", temp, humi);
        }
        Delay_ms(1000);
    }
}

四、串口上位机显示效果

复制代码
Temp:26C Humi:58%
Temp:26C Humi:57%
Temp:27C Humi:56%

参考代码 STM32F103-串口控制数码管显示温湿度数据 www.youwenfan.com/contentcsv/103447.html

五、常见问题排查

现象 原因
数码管不亮 共阳/共阴段码搞反
DHT11 一直 0 延时不准(必须精准 µs)
数值跳动 未加延时 / 电源不稳
串口乱码 晶振频率 ≠ 72MHz
相关推荐
Industio_触觉智能2 小时前
瑞芯微RK3576机器视觉场景之割草机+无人清扫车
嵌入式硬件·硬件工程·边缘计算·智能硬件·rk3576·割草机·rk3576j
0x3F(小茶)2 小时前
STM32 Bootloader与OTA升级
c语言·stm32·单片机·嵌入式硬件·物联网
Wallystech-Linda2 小时前
[特殊字符] How Mesh WiFi Is Tested: A Complete Engineering Validation Guide
嵌入式硬件
嵌入式-老费2 小时前
esp开发与应用(数码管类应用)
嵌入式硬件
fie88892 小时前
51单片机 NRF24L01 接收程序
嵌入式硬件·mongodb·51单片机
agathakuan2 小时前
從零開始在家開發 IoT: VM編譯到Windows燒錄與逐sector抹除原因
嵌入式硬件·iot·virtualmachine
XINVRY-FPGA2 小时前
XC7Z035-2FFG900I Xilinx/AMD Zynq-7000 SoC FPGA
人工智能·嵌入式硬件·计算机视觉·fpga开发·硬件工程·dsp开发·fpga
fffzd2 小时前
STM32:串口--DMA
stm32·单片机·嵌入式硬件·串口·dma·回调函数
踏着七彩祥云的小丑2 小时前
嵌入式测试学习第 28 天:网络调试助手使用、TCP服务端客户端实操
单片机·嵌入式硬件·学习