STM32:UART-接收不定长数据

STM32:UART-接收不定长数据

前提摘要

  1. 个人说明:

  2. 参考:

    • 正点原子
    • 野火
    • ST数据手册

正文

空闲帧

在这里插入图片描述

一空闲帧所需要的时间:1位起始位+8位数据位+1位校验位+1位停止位。

编程要点

串口硬件相关宏定义,bsp_uart.h

#ifndef __BSP_UART_H
#define __BSP_UART_H

#include "stm32f10x.h"
#include <stdio.h>


#define RCC_UART_GPIO_Clk_Cmd           RCC_APB2PeriphClockCmd
#define RCC_UART_GPIO_Clk               RCC_APB2Periph_GPIOA

#define UART_GPIO_Tx_Pin                GPIO_Pin_9
#define UART_GPIO_Tx_Port               GPIOA

#define UART_GPIO_Rx_Pin                GPIO_Pin_10
#define UART_GPIO_Rx_Port               GPIOA

#define BSP_USARTx                      USART1 
#define RCC_UART_Clk_Cmd                RCC_APB2PeriphClockCmd
#define RCC_UART_Clk                    RCC_APB2Periph_USART1
#define UART_BaudRate                   115200

#define BSP_USARTx_IRQHandler           USART1_IRQHandler

void BSP_UART_Init(void);

#endif /* __BSP_UART_H */


串口模块配置,bsp_uart.c

#include "bsp_uart.h"

static void BSP_UART_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_UART_GPIO_Clk_Cmd(RCC_UART_GPIO_Clk,ENABLE);
    GPIO_InitStructure.GPIO_Pin = UART_GPIO_Tx_Pin;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(UART_GPIO_Tx_Port,&GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = UART_GPIO_Rx_Pin;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(UART_GPIO_Rx_Port,&GPIO_InitStructure);
}


static void BSP_UART_Config(void)
{
    USART_InitTypeDef USART_InitStructure;
    RCC_UART_Clk_Cmd(RCC_UART_Clk,ENABLE);
    USART_InitStructure.USART_BaudRate = UART_BaudRate;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_StopBits =USART_StopBits_1;
    USART_InitStructure.USART_WordLength =USART_WordLength_8b;
    USART_Init(BSP_USARTx,&USART_InitStructure);
    USART_ITConfig(BSP_USARTx,USART_IT_RXNE,ENABLE);
    USART_ITConfig(BSP_USARTx,USART_IT_IDLE,ENABLE);
    
    USART_Cmd(BSP_USARTx,ENABLE);
}


void BSP_UART_Init(void)
{
    BSP_UART_Config();
    BSP_UART_GPIO_Config();
}

串口不定长数据接收

主函数,main.c

#define data_size   100

typedef struct{
    uint16_t flag;
    uint16_t len;
    char data[data_size];
}Data_TypeDef;


void Data_Process(Data_TypeDef* Data_Struct)
{
    Usart_SendString(BSP_USARTx,Data_Struct->data);
    
    Data_Struct->flag = 0;
    Data_Struct->len = 0;
}



void BSP_NVIC_Config(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
    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);
}



Data_TypeDef Data_Structure;

int main(void) 
{
    BSP_UART_Init();
    BSP_NVIC_Config();
    while(1)
    {
        if(Data_Structure.flag == 1)
        {
            Data_Process(&Data_Structure);
        }
    }
}

中断服务,stm32f10x_it.c

extern Data_TypeDef Data_Structure;

void BSP_USARTx_IRQHandler(void)
{
  if(USART_GetITStatus(BSP_USARTx, USART_IT_RXNE) != RESET)
  {   
    /* Read one byte from the receive data register */
    Data_Struct.data[Data_Structure.len] = USART_ReceiveData(BSP_USARTx);
    if(++Data_Structure.len > data_size - 2)
    {
        Data_Struct.len = 0;
    }

  }
  if(USART_GetITStatus(BSP_USARTx,USART_IT_IDLE) != RESET)
  {
        BSP_USARTx->SR;
        BSP_USARTx->DR;
        Data_Structure.data[Data_Structure.len] = '\0'; 
        Data_Structure.flag = 1;
  }

}

在这里插入图片描述

这里使用软件清除RXNE标志,对USART_DR读操作可以将该位清零。

在这里插入图片描述

这里使用软件清除IDLE标志,对USART_SR,USART_DR读操作可以将该位清零。

总结


本文均为原创,欢迎转载,请注明文章出处:CSDN:https://blog.csdn.net/ZipingPan/ARM。百度和各类采集站皆不可信,搜索请谨慎鉴别。技术类文章一般都有时效性,本人习惯不定期对自己的博文进行修正和更新,因此请访问出处以查看本文的最新版本。

非原创博客会在文末标注出处,由于时效原因,可能并不是原创作者地址(已经无法溯源)。

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 在STM32F103系列微控制器中,可以使用DMA(直接内存访问)来实现串口接收不定数据。下面是实现的大致步骤: 1. 首先,需要配置串口进行接收: - 初始化串口,并设置波特率、数据位、停止位等参数。 - 打开串口接收中断,以便在接收数据时触发中断。 - 开启DMA的UART接收通道。 2. 配置DMA: - 设置DMA通道的源地址为串口数据寄存器地址。 - 设置DMA通道的目的地址为接收数据的存储位置,可以是单个变量或数组。 - 设置DMA数据传输的度为最大接收数据度。 - 配置DMA通道为循环模式,以便在接收数据时自动重新启动DMA传输。 3. 在串口接收中断的处理函数中,可以在每次接收数据时检查DMA是否已经接收到足够的数据。可以根据接收到的数据情况进行进一步处理,例如打印数据或进行其他操作。 需要注意的是,在使用DMA接收不定数据时,需要确保DMA传输的度足够,以便接收到的数据不会超出DMA缓冲区的范围。此外,为了避免数据丢失或覆盖,建议在处理接收到的数据之前判断DMA是否已经完成传输。 总的来说,通过配置USART接收中断和DMA通道,可以实现STM32F103系列微控制器的串口DMA接收不定数据的功能。这种方法可以在保证低功耗的同时,提高系统的效率和响应速度。 ### 回答2: 在STM32F103系列微控制器中,使用DMA(直接存储器访问)来接收不定数据是一种高效和可靠的方法。 首先,我们需要配置串口通信的DMA接收功能。通过设置串口的DMA接收使能位(RXDMAEN),可以使用DMA来接收数据。然后,通过配置DMA控制器的通道、缓冲区和传输度等参数,将数据从串口接收到DMA缓冲区中。 在不定数据接收的情况下,可以通过设置DMA传输完成中断(TC)来判断数据是否接收完整。每当DMA接收到指定度的数据时,将触发一个DMA传输完成中断,在中断服务程序中可以处理接收到的数据以及进行后续操作。 另外,为了区分每一帧数据的开始和结束,可以通过给数据添加开始标志和结束标志的方式进行帧同步。当接收到一个完整的帧后,可以通过软件逻辑进行数据处理和分析。 需要注意的是,不定数据接收可能存在干扰和错误。为了提高接收数据的可靠性,可以通过一些策略来进行数据完整性检查和错误处理,如校验和检验、超时机制等。 综上所述,使用DMA接收不定数据需要配置串口的DMA接收使能位,并设置DMA控制器的相关参数。通过中断服务程序和逻辑判断,可以实现对不定数据接收和处理。 ### 回答3: STM32F103是一种具有DMA(直接内存访问)功能的微控制器,它可以用于实现串口接收不定数据。在进行串口DMA接收不定数据之前,需要先配置串口和DMA的相关寄存器。 首先,需要使能串口的DMA接收模式。可以通过设置串口控制寄存器CR3的位DMA-RX使能。然后,将DMA的通道选择为串口的接收通道。 接下来,需要配置DMA的相关寄存器,包括源和目的地址、传输度和数据流向等。对于串口DMA接收,源地址通常是串口的数据寄存器,目的地址是存储接收数据的缓冲区。传输度可设置为一个较大的值,以确保能够接收不定数据数据流向应设置为从外设到内存。 然后,需要配置DMA的传输模式,包括循环模式和自动请求使能。循环模式可以确保DMA在接收完指定度的数据后,自动重新开始传输。自动请求使能则用于自动触发DMA传输。 最后,可以通过使能DMA的接收完成中断来对接收到的数据进行处理。当DMA接收完成后,会触发DMA的中断,可以在中断函数中处理接收到的数据,比如打印输出或进行其他操作。 综上所述,通过配置串口和DMA的相关寄存器,并处理DMA的接收完成中断,就可以实现STM32F103串口DMA接收不定数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Pan2iping

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值