打印
[STM32F7]

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

[复制链接]
308|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
童雨竹|  楼主 | 2024-11-25 07:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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[50];

/* 初始化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发送数据时,有没有其他方法处理超时问题?

使用特权

评论回复
5
Wordsworth| | 2024-11-25 07:41 | 只看该作者
这个温度计算公式很有用,刚好适合我用的LM35!

使用特权

评论回复
6
Bblythe| | 2024-11-25 07:41 | 只看该作者
我觉得LED的控制功能挺实用,有扩展到家居控制的潜力。

使用特权

评论回复
7
Pulitzer| | 2024-11-25 07:42 | 只看该作者
有没有推荐的高精度传感器,搭配STM32使用?

使用特权

评论回复
8
Clyde011| | 2024-11-25 07:42 | 只看该作者
USART2初始化代码看着很简洁,新手也能理解!

使用特权

评论回复
9
Uriah| | 2024-11-25 07:42 | 只看该作者
串口调试工具用哪个比较方便?我用Docklight偶尔会掉线。

使用特权

评论回复
10
公羊子丹| | 2024-11-25 07:42 | 只看该作者
如果温度数据采样频率更高,系统会不会有延迟问题?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

46

主题

3818

帖子

0

粉丝