童雨竹 发表于 2024-11-25 07:40

STM32F407:实现简易的串口通信与温度监测系统

STM32F407是STM32系列中一款功能强大的微控制器,广泛应用于嵌入式领域。本文将基于STM32F407,构建一个串口通信和温度监测的系统,通过串口发送温度数据,并通过简单的命令控制LED状态。
一、项目目标
[*]使用STM32F407的ADC采集温度传感器数据。
[*]通过USART将采集的数据发送到PC端。
[*]接收PC端命令控制开发板上的LED。
二、硬件资源
[*]STM32F407开发板
[*]LM35温度传感器(模拟信号输出)
[*]USB转TTL模块(用于串口通信)
[*]LED灯及限流电阻
三、开发环境
[*]STM32CubeIDE
[*]STM32CubeMX(用于生成初始化代码)
[*]串口调试工具(如Docklight或SSCOM)
四、代码实现以下是核心代码部分:
#include "main.h"
#include <stdio.h>

ADC_HandleTypeDef hadc1;
UART_HandleTypeDef huart2;

uint16_t adc_value;
char uart_buffer;

/* 初始化ADC */
void MX_ADC1_Init(void) {
    hadc1.Instance = ADC1;
    hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
    hadc1.Init.Resolution = ADC_RESOLUTION_12B;
    hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
    hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
    hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
    hadc1.Init.ContinuousConvMode = DISABLE;
    hadc1.Init.NbrOfConversion = 1;
    HAL_ADC_Init(&hadc1);

    ADC_ChannelConfTypeDef sConfig = {0};
    sConfig.Channel = ADC_CHANNEL_0;
    sConfig.Rank = ADC_REGULAR_RANK_1;
    sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES;
    HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}

/* 初始化USART */
void MX_USART2_UART_Init(void) {
    huart2.Instance = USART2;
    huart2.Init.BaudRate = 9600;
    huart2.Init.WordLength = UART_WORDLENGTH_8B;
    huart2.Init.StopBits = UART_STOPBITS_1;
    huart2.Init.Parity = UART_PARITY_NONE;
    huart2.Init.Mode = UART_MODE_TX_RX;
    huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart2.Init.OverSampling = UART_OVERSAMPLING_16;
    HAL_UART_Init(&huart2);
}

/* 读取ADC值并转换为温度 */
float Read_Temperature(void) {
    HAL_ADC_Start(&hadc1);
    if (HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY) == HAL_OK) {
      adc_value = HAL_ADC_GetValue(&hadc1);
    }
    HAL_ADC_Stop(&hadc1);
    return (adc_value * 3.3 / 4096) * 100;// 假设LM35输出10mV/°C
}

/* 主函数 */
int main(void) {
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_ADC1_Init();
    MX_USART2_UART_Init();

    float temperature;

    while (1) {
      /* 获取温度值 */
      temperature = Read_Temperature();

      /* 通过USART发送温度数据 */
      sprintf(uart_buffer, "Temperature: %.2f C\r\n", temperature);
      HAL_UART_Transmit(&huart2, (uint8_t*)uart_buffer, strlen(uart_buffer), HAL_MAX_DELAY);

      /* 接收命令并控制LED */
      uint8_t received_char;
      if (HAL_UART_Receive(&huart2, &received_char, 1, 100) == HAL_OK) {
            if (received_char == '1') {
                HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);// 打开LED
            } else if (received_char == '0') {
                HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);// 关闭LED
            }
      }

      HAL_Delay(1000);
    }
}
五、代码解读
[*]ADC采集温度
使用STM32F407的ADC模块读取LM35的输出电压,并根据电压计算温度。

[*]USART通信
使用USART2与PC端进行通信,实现数据发送和命令接收。

[*]LED控制
接收PC端发送的命令,控制LED的开关状态。

[*]优化点
可以增加错误处理,例如检测ADC转换失败或串口超时。

六、硬件连接
[*]将LM35的输出连接到ADC输入通道(如PA0)。
[*]USB转TTL模块的TX和RX分别连接到USART2的RX和TX。
[*]LED正极接到GPIO输出引脚(如PA5),负极接地。
七、测试步骤
[*]配置STM32CubeMX生成基础初始化代码。
[*]将代码导入STM32CubeIDE,复制并粘贴上述代码。
[*]编译并烧录到STM32F407开发板。
[*]打开串口调试工具,设置波特率9600。
[*]检查温度数据输出,并尝试发送命令控制LED。

周半梅 发表于 2024-11-25 07:40

这个温度读取的代码好清晰,适合我的小项目,收藏了!

帛灿灿 发表于 2024-11-25 07:41

请问如果换成DS18B20传感器,修改起来麻烦吗?

万图 发表于 2024-11-25 07:41

用USART发送数据时,有没有其他方法处理超时问题?

Wordsworth 发表于 2024-11-25 07:41

这个温度计算公式很有用,刚好适合我用的LM35!

Bblythe 发表于 2024-11-25 07:41

我觉得LED的控制功能挺实用,有扩展到家居控制的潜力。

Pulitzer 发表于 2024-11-25 07:42

有没有推荐的高精度传感器,搭配STM32使用?

Clyde011 发表于 2024-11-25 07:42

USART2初始化代码看着很简洁,新手也能理解!

Uriah 发表于 2024-11-25 07:42

串口调试工具用哪个比较方便?我用Docklight偶尔会掉线。

公羊子丹 发表于 2024-11-25 07:42

如果温度数据采样频率更高,系统会不会有延迟问题?
页: [1]
查看完整版本: STM32F407:实现简易的串口通信与温度监测系统