c#串口缓存字节数_串口基于 DMA 接收不定长数据

本文介绍了如何在STM32F103系列上利用串口空闲中断和DMA接收不定长数据,以防缓存溢出。通过设置多缓存并在每次接收后切换,确保数据完整处理。内容包括串口配置、DMA配置、空闲中断处理及应用层代码讲解。
摘要由CSDN通过智能技术生成

说明

硬件平台: STM32F103 系列

IDE: keil

策略:利用串口空闲中断实现接收不定长数据。假如串口在短时间内接收了 N 段数据,如果我们来不及处理接收的的数据。导致 DMA 接收缓存满了,(开启循环模式) DMA 会开始新的一轮传输,覆盖掉前面的数据。所以为了防止这种情况出现我们会使用多缓存(此例程使用了 4 个缓存。当然你也可以使用 N 个缓存,理论上是不限缓存数的),每接收到一段数据,就切换一次缓存。但是你的应用程序在处理接收到的缓存时,需要一次性把所有缓存的数据处理完,并且释放缓存。不支持缓存级别的先入先出队列。

技术点说明:要看懂这篇文章的,并且运用在实际工程中需要掌握以下 2 个技术点。

1 串口。主要是串口配置,这个很基础。

2 DMA 传输。这个其实也不复杂,看一下教程自己试着做个示例就基本掌握了,但是 DMA 的各种模式配置要都弄明白就有点繁琐,需要仔细看文档。对你的硬件的串口和 DMA 要很熟悉,下面我的示例代码注释会尽量“啰嗦”一些。

正题

第一步:串口的配置

串口配置和平时差不多,这里多了 1 个空闲中断。

//usart.c

/*
初始化串口 USART1
说  明:
参  数: baud 波特率
返回值: 无
*/
void USART1_Init(u32 baud)
{
    
    GPIO_InitTypeDef  GPIO_InitStructure;  //配置 GPIO 结构体
    USART_InitTypeDef USART_InitStruct;    //配置串口结构体
    NVIC_InitTypeDef  NVIC_InitStruct;     //中断配置

    //使能 USART1,GPIOA 时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);

    //PA9 (UART1_TX)
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;   //复用推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  //输出频率
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9;        //引脚 PA9
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    //PA10 (UART1_RX)
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN_FLOATING;  //浮空输入
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_10;            //引脚 PA10
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    //串口 USART1 配置
    USART_InitStruct.USART_BaudRate            = baud;                 //波特率
    USART_InitStruct.USART_WordLength          = USART_WordLength_8b;  //数据位 8 位
    USART_InitStruct.USART_StopBits            = USART_StopBits_1;     //停止位 1
    USART_InitStruct.USART_Parity              = USART_Parity_No;      //无奇偶校验
    USART_InitStruct.USART_Mode                = USART_Mode_Rx | USART_Mode_Tx;   //能收,能发
    USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  //无硬件数据流控制
    USART_Init(USART1, &USART_InitStruct);

    //串口 USART1 空闲中断配置
    NVIC_InitStruct.NVIC_IRQChannel                   = USART1_IRQn;  //中断通道
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x03;         //抢占优先级
    NVIC_InitStruct.NVIC_IRQChannelSubPrior
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值