问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

STM32串口中断:高效编程技巧分享

创作时间:
作者:
@小白创作中心

STM32串口中断:高效编程技巧分享

引用
CSDN
13
来源
1.
https://blog.csdn.net/li391402/article/details/117559727
2.
https://blog.csdn.net/ForeverIT/article/details/81750696
3.
https://en.eeworld.com.cn/bbs/thread-1061686-1-1.html
4.
https://community.st.com/t5/stm32-mcus-products/uart-interrupt-issue-and-interrupt-generating/td-p/301896
5.
https://boardor.com/blog/stm32-serial-communication-interrupt-vs-polling
6.
https://community.st.com/t5/stm32-mcus-products/need-to-change-interrupt-priority-for-usart-dma-rx-circular/td-p/223360
7.
https://en.eeworld.com.cn/bbs/thread-140235-1-1.html
8.
https://en.eeworld.com.cn/bbs/thread-1068197-1-1.html
9.
https://community.st.com/t5/stm32-mcus-products/uart-interrupt/td-p/434534
10.
https://community.st.com/t5/stm32-mcus-products/stm32-hal-uart-receive-interrupt-stops-receiving-at-random-times/td-p/93498
11.
https://controllerstech.com/stm32-uart-3-receive-data-in-blocking-interrupt-mode/
12.
http://micromouseusa.com/?p=279
13.
https://www.cnblogs.com/xiaomengspace/articles/18074174

在嵌入式系统开发中,串口通信是最常见的数据传输方式之一。然而,随着系统复杂度的提高,简单的轮询或中断处理方式已经难以满足高性能、高可靠性的需求。本文将深入探讨如何通过中断驱动传输、DMA传输以及合理的数据管理策略,来优化STM32微控制器的串口通信效率。

01

中断处理优化

中断处理是串口通信中最关键的部分。不当的中断处理会导致数据丢失、系统响应延迟等问题。以下是一些优化中断处理的实用技巧:

1. 精简中断处理函数

中断处理函数应该尽可能简洁,避免在中断上下文中执行复杂操作。例如,数据解析、协议处理等任务应该移出中断处理函数,在主循环中进行。

void UART_Interrupt_Handler(void) {
    uint8_t data = USART1->DR; // 读取接收到的数据
    if (ring_buffer_put(&rx_buffer, data) == BUFFER_FULL) {
        // 处理缓冲区满的情况
    }
}

2. 使用循环缓冲区

循环缓冲区(Ring Buffer)是管理串口数据的有效方式。它可以在有限的内存空间内实现高效的数据存储和读取。

typedef struct {
    uint8_t *buffer;
    uint16_t head;
    uint16_t tail;
    uint16_t size;
} ring_buffer_t;

void ring_buffer_init(ring_buffer_t *rb, uint8_t *buffer, uint16_t size) {
    rb->buffer = buffer;
    rb->head = rb->tail = 0;
    rb->size = size;
}

uint8_t ring_buffer_put(ring_buffer_t *rb, uint8_t data) {
    if ((rb->head + 1) % rb->size == rb->tail) {
        return BUFFER_FULL;
    }
    rb->buffer[rb->head] = data;
    rb->head = (rb->head + 1) % rb->size;
    return BUFFER_OK;
}

3. 合理配置中断优先级

STM32的NVIC(嵌套向量中断控制器)允许配置不同中断的优先级。对于串口通信,通常需要较高的优先级以确保数据的实时性。

void NVIC_Configuration(void) {
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 主优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 从优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}
02

DMA传输优化

DMA(直接内存访问)是提高串口通信效率的关键技术。它允许数据在外部设备和内存之间直接传输,无需CPU干预,从而释放CPU资源并提高系统性能。

1. DMA模式的优势

  • 硬件级数据传输,无需CPU干涉
  • 可以与操作系统协同工作
  • 适用于高波特率和低功耗应用
  • 通过增加缓冲区大小可以改善大量数据突发情况下的性能

2. 结合IDLE中断检测数据完整性

在DMA传输中,一个常见的问题是无法预先知道要接收的数据长度。STM32的UART模块提供了IDLE中断功能,可以检测数据接收的空闲状态,从而判断数据接收是否完成。

void USART1_IRQHandler(void) {
    if (USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) {
        // IDLE中断,表示数据接收完成
        USART_ClearITPendingBit(USART1, USART_IT_IDLE);
        // 处理接收到的数据
    }
}

3. 循环模式与半传输/传输完成中断

在DMA传输中,循环模式(Circular mode)和半传输(Half-Transfer)/传输完成(Transfer-Complete)中断是非常有用的特性。

  • 循环模式允许DMA在传输完成后自动重新开始,避免手动配置
  • 半传输中断可以在数据接收一半时通知应用程序
  • 传输完成中断在数据完全接收后触发
void DMA_Configuration(void) {
    DMA_InitTypeDef DMA_InitStructure;
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)rx_buffer;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = BUFFER_SIZE;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel5, &DMA_InitStructure);
}
03

最佳实践总结

  1. 中断处理:保持中断处理函数简洁,使用循环缓冲区管理数据,合理配置中断优先级。
  2. DMA传输:利用DMA实现硬件级数据传输,结合IDLE中断检测数据完整性,使用循环模式和半传输/传输完成中断优化数据处理。
  3. 系统设计:在系统设计时充分考虑串口通信的需求,合理分配系统资源,确保串口通信的实时性和可靠性。

通过上述优化方法,可以显著提高STM32串口通信的效率和可靠性,为开发高性能嵌入式系统奠定坚实基础。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号