Bootstrap

STM32外设应用

1. 什么是STM32外设?

STM32微控制器集成了多种外设,这些外设可以帮助我们实现各种功能,比如控制LED灯、读取传感器数据、与其他设备通信等。常见的外设有GPIO(通用输入输出)、ADC(模数转换器)、UART(通用异步收发传输器)、SPI(串行外围接口)和I2C(集成电路间通信)。

2. 如何开始使用STM32外设?

首先,你需要准备一个STM32开发板,比如STM32F103。然后,安装必要的开发工具,如STM32CubeIDE。这个软件可以帮助你编写代码、配置外设和下载程序到开发板上。

3. GPIO(通用输入输出)

GPIO是最基本的外设,可以配置为输入或输出模式。比如,你可以用它来控制一个LED灯的亮灭,或者读取一个按钮的状态。

  • 代码示例

c复制

#include "main.h"
#include "stm32f4xx_hal.h"

void SystemClock_Config(void);
static void MX_GPIO_Init(void);

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    while (1)
    {
        // 点亮 LED
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
        HAL_Delay(1000);
        // 熄灭 LED
        HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
        HAL_Delay(1000);
    }
}

static void MX_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    __HAL_RCC_GPIOA_CLK_ENABLE();
    GPIO_InitStruct.Pin = GPIO_PIN_5;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
4. ADC(模数转换器)

ADC可以将模拟信号转换为数字信号,比如测量温度或光照强度。

  • 代码示例

c复制

#include "main.h"
#include "stm32f4xx_hal.h"

ADC_HandleTypeDef hadc1;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_ADC1_Init();
    uint32_t adc_value;
    while (1)
    {
        HAL_ADC_Start(&hadc1);
        if (HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY) == HAL_OK)
        {
            adc_value = HAL_ADC_GetValue(&hadc1);
            // 处理 ADC 值
        }
        HAL_Delay(100);
    }
}

static void MX_ADC1_Init(void)
{
    ADC_ChannelConfTypeDef sConfig = {0};
    hadc1.Instance = ADC1;
    hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
    hadc1.Init.Resolution = ADC_RESOLUTION_12B;
    hadc1.Init.ScanConvMode = DISABLE;
    hadc1.Init.ContinuousConvMode = DISABLE;
    hadc1.Init.DiscontinuousConvMode = DISABLE;
    hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
    hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
    hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
    hadc1.Init.NbrOfConversion = 1;
    hadc1.Init.DMAContinuousRequests = DISABLE;
    hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
    if (HAL_ADC_Init(&hadc1) != HAL_OK)
    {
        Error_Handler();
    }
    sConfig.Channel = ADC_CHANNEL_0;
    sConfig.Rank = 1;
    sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
    if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
    {
        Error_Handler();
    }
}
5. UART(通用异步收发传输器)

UART用于设备间的数据交换,比如将数据发送到电脑。

  • 代码示例

c复制

#include "main.h"
#include "stm32f4xx_hal.h"
#include "stdio.h"

UART_HandleTypeDef huart1;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_USART1_UART_Init();
    char message[] = "Hello, STM32!\r\n";
    while (1)
    {
        HAL_UART_Transmit(&huart1, (uint8_t *)message, sizeof(message) - 1, HAL_MAX_DELAY);
        HAL_Delay(1000);
    }
}

static void MX_USART1_UART_Init(void)
{
    huart1.Instance = USART1;
    huart1.Init.BaudRate = 115200;
    huart1.Init.WordLength = UART_WORDLENGTH_8B;
    huart1.Init.StopBits = UART_STOPBITS_1;
    huart1.Init.Parity = UART_PARITY_NONE;
    huart1.Init.Mode = UART_MODE_TX_RX;
    huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart1.Init.OverSampling = UART_OVERSAMPLING_16;
    if (HAL_UART_Init(&huart1) != HAL_OK)
    {
        Error_Handler();
    }
}
6. SPI(串行外围接口)

SPI是一种高速串行通信协议,常用于与外部存储器、显示屏、传感器等设备的通信。

7. I2C(集成电路间通信)

I2C是一种用于连接低速设备的通信协议,比如EEPROM、传感器等。

  • 代码示例

c复制

#define EEPROM_ADDRESS 0xA0 // 设备地址
#define EEPROM_WIGHT_OFFSET 0x00 // 写入地址偏移
#define EEPROM_READ_OFFSET 0x01 // 读取地址偏移
uint8_t data_buffer[1]; // 读写数据缓冲区

// 写数据到EEPROM
HAL_StatusTypeDef I2C_Write(uint16_t MemAddress, uint8_t *pData, uint16_t Size)
{
    return HAL_I2C_Mem_Write(&hi2c1, EEPROM_ADDRESS, MemAddress << 1, I2C_MEMADD_SIZE_8BIT, pData, Size, HAL_MAX_DELAY);
}

// 从EEPROM读数据
HAL_StatusTypeDef I2C_Read(uint16_t MemAddress, uint8_t *pData, uint16_t Size)
{
    return HAL_I2C_Mem_Read(&hi2c1, EEPROM_ADDRESS, MemAddress << 1, I2C_MEMADD_SIZE_8BIT, pData, Size, HAL_MAX_DELAY);
}

// 使用示例
I2C_Write(EEPROM_WIGHT_OFFSET, data_buffer, 1); // 写入数据
I2C_Read(EEPROM_READ_OFFSET, data_buffer, 1); // 读取数据
8. 实战案例:基于STM32的环境监测系统

你可以用STM32和DHT11温湿度传感器来制作一个环境监测系统。通过UART将数据发送到电脑,然后在电脑上显示温湿度信息。

  • 硬件组件

    • STM32微控制器(如STM32F103)

    • DHT11温湿度传感器

    • USB转UART模块

    • 电源模块

  • 软件功能

    • 读取DHT11传感器的数据

    • 通过UART将数据发送到PC

    • 在PC上显示温湿度信息

  • 代码示例

c复制

#include "stm32f1xx_hal.h"
#include "dht11.h"

// UART句柄
UART_HandleTypeDef huart1;

// 初始化UART
void UART_Init(void)
{
    huart1.Instance = USART1;
    huart1.Init.BaudRate = 9600;
    huart1.Init.WordLength = UART_WORDLENGTH_8B;
    huart1.Init.StopBits = UART_STOPBITS_1;
    huart1.Init.Parity = UART_PARITY_NONE;
    huart1.Init.Mode = UART_MODE_TX_RX;
    HAL_UART_Init(&huart1);
}

// 主函数
int main(void)
{
    HAL_Init();
    SystemClock_Config();
    UART_Init();
    DHT11_Init();
    char buffer[50];
    uint8_t temperature, humidity;
    while (1)
    {
        // 读取温湿度数据
        if (DHT11_Read(&temperature, &humidity) == DHT11_OK)
        {
            // 格式化数据
            sprintf(buffer, "Temp: %d C, Humidity: %d %%\n", temperature, humidity);
            // 通过UART发送数据
            HAL_UART_Transmit
;