历史上的今天
返回首页

历史上的今天

今天是:2025年02月12日(星期三)

正在发生

2019年02月12日 | STM32—cubeMX+DMA+USART 接收任意长度的数据

2019-02-12 来源:eefocus

前言  


  之前的一篇文章中我为了可以实现USART接收任意长度的数据,对HAL的库进行了修改,可以实现接收以0x0a结尾的任意长度数据,即认为接收到0x0a时接收结束,见链接:HAL USART接收任意长度。 


  然而,上述这种方法并不合适,原则上HAL库一般不去修改,不便于其他人移植程序,降低了程序中库的适用性,这是很不好的习惯,所以这种方法并不可取。 


  后查资料得知STM32中还可以利用DMA的方式实现串口的任意长度数据的接收,故开始学习DMA+串口接收任意长度的数据这种方式。


cubeMX软件配置过程


首先,第一步都是进行时钟树的配置,配置好系统的时钟,不同的芯片配置不同的时钟频率,如图。 


这里写图片描述


接着,配置USART1,选择异步asynchronous,软件自动配置了PA9和PA10管脚。 


这里写图片描述


然后,继续添加USART1的发送和接收DMA,其余默认即可。 


这里写图片描述


接着,勾选上USART1的中断使能。 


这里写图片描述


最后,生成MDK-ARM V5版本环境的程序。 


这里写图片描述


UASRT串口程序修改

//添加变量,为什么用关键字volatile见链接:[链接](http://blog.csdn.net/u014470361/article/details/78830147)

volatile uint8_t rx_len=0;

volatile uint8_t recv_end_flag=0;

uint8_t rx_buffer[200];

static void MX_USART1_UART_Init(void)

{


  huart1.Instance = USART1;

  huart1.Init.BaudRate = 115200;

  huart1.Init.WordLength = UART_WORDLENGTH_8B;

  huart1.Init.StopBits = UART_STOPBITS_1;

  huart1.Init.Parity = UART_PARITY_NONE;

  huart1.Init.Mode = UART_MODE_TX_RX;

  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;

  huart1.Init.OverSampling = UART_OVERSAMPLING_16;

  if (HAL_UART_Init(&huart1) != HAL_OK)

  {

    _Error_Handler(__FILE__, __LINE__);

  }

  //上面的usart配置代码为cubemx自动生成的,在下方添加使能idle中断和打开串口DMA接收语句

    __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);//使能idle中断

    HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE);//打开DMA接收,数据存入rx_buffer数组中。 

}



接下来修改串口中断函数。


void USART1_IRQHandler(void)

{

    uint32_t tmp_flag = 0;

    uint32_t temp;

    tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE); //获取IDLE标志位

    if((tmp_flag != RESET))//idle标志被置位

    { 

        __HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除标志位

        temp = huart1.Instance->SR;  //清除状态寄存器SR,读取SR寄存器可以实现清除SR寄存器的功能

        temp = huart1.Instance->DR; //读取数据寄存器中的数据

        HAL_UART_DMAStop(&huart1); //

        temp  = hdma_usart1_rx.Instance->NDTR;// 获取DMA中未传输的数据个数,NDTR寄存器分析见下面

        rx_len =  BUFFER_SIZE - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数

        recv_end_flag = 1;  // 接受完成标志位置1    

     }

  HAL_UART_IRQHandler(&huart1);


}



DMA通道结构体中定义了NDTR寄存器,那为什么是未传输的数据数呢,STM32的中文手册给出了该寄存器的具体说明。


typedef struct

{

  __IO uint32_t CR;     /*!< DMA stream x configuration register      */

  __IO uint32_t NDTR;   /*!< DMA stream x **number of data register**     */

  __IO uint32_t PAR;    /*!< DMA stream x peripheral address register */

  __IO uint32_t M0AR;   /*!< DMA stream x memory 0 address register   */

  __IO uint32_t M1AR;   /*!< DMA stream x memory 1 address register   */

  __IO uint32_t FCR;    /*!< DMA stream x FIFO control register       */

} DMA_Stream_TypeDef;

这里写图片描述

接着,编写主函数中串口中断的处理函数。


int main(void)

{

  HAL_Init();

  SystemClock_Config();

  MX_GPIO_Init();

  MX_DMA_Init();

  MX_USART1_UART_Init();

  while (1)

  {

        if(recv_end_flag ==1)

        {

            printf("rx_len=%d\r\n",rx_len);//打印接收长度

            HAL_UART_Transmit(&huart1,rx_buffer, rx_len,200);接收数据打印出来

            for(uint8_t i=0;i

                {

                    rx_buffer[i]=0;//清接收缓存

                }

            rx_len=0;//清除计数

            recv_end_flag=0;//清除接收结束标志位

        }

        HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE);//重新打开DMA接收     

  }

}



程序的运行效果如下图所示 ,输入任意长度数据,串口打印出接收的数据长度并打印出接收的数据。本程序设置的接收长度最大BUFFER_SIZE是200,若想接收更长的数据,也可以把BUFFER_SIZE和数组长度改大。 

这里写图片描述

推荐阅读

史海拾趣

BOPLA公司的发展小趣事

近年来,随着环保意识的提高和政府对塑料污染治理的关注,BOPLA积极响应国家号召,开始研发和推广生物基可降解材料。经过多年的努力,公司成功推出了BOPLA生物基膜材,实现了产品的绿色转型。这一创新不仅有助于减少塑料污染,还为公司赢得了更多的环保意识和绿色消费市场的青睐。

CINTERION公司的发展小趣事

2010年,电子支付与身份识别技术领域的领军企业金雅拓,全资收购了CINTERION。这一资本动作不仅为CINTERION带来了更多的资金支持,更使其在金雅拓的物联网事业部中获得了更广阔的发展空间。收购完成后,CINTERION继续保持其技术领先地位,并在金雅拓的推动下,进一步拓宽了产品线和应用领域。

Free2Move公司的发展小趣事

近年来,CINTERION与泰雷兹达成战略合作,共同推出了创新型物联网无线通信模组Cinterion MV32。这款模组结合了泰雷兹在连接管理方面的灵活性和CINTERION在无线通信模组技术上的优势,为制造商提供了快速构建和维护高性能5G设备的解决方案。这一合作不仅加强了CINTERION在物联网领域的市场地位,也为其在未来的发展中注入了新的活力。

以上五个故事均基于CINTERION在电子行业中的发展历程和成就进行描述,旨在客观呈现其在不同领域的发展轨迹和技术实力。

AMS公司的发展小趣事

近年来,随着智能电网技术的快速发展,CINTERION凭借其领先的M2M通信技术,在该领域取得了显著突破。其EU3 M2M模块因其卓越的性能和稳定性,荣获了SmartGrid.TMCnet.com颁发的2011年智能电网杰出奖。这一奖项的获得,不仅证明了CINTERION在智能电网技术创新方面的实力,也为公司在该领域的进一步发展奠定了坚实基础。

General Electric Company公司的发展小趣事
在工业自动化控制系统中,用于驱动高压电机、阀门等执行机构。
Ampire Co Ltd公司的发展小趣事
内部集成了频率补偿机制,确保在高频信号下电路的稳定性。

问答坊 | AI 解惑

关于OP07

哪位可以给我讲讲这电路上面的二极管是什么作用啊,特别是为什么要在OP07反馈和输出端加上IN4148…

查看全部问答>

中断执行完和什么也没做似的,郁闷

我用的是51系列的单片机,做的一个在中断中执行键盘扫描的程序,用的LCD1602显示,但是当中断返回后,显示器上已经输入的东西会不见, 用的是外部中断,跳沿触发方式 请帮我看一下是什么问题啊 汇编语言的,        MOV R0, ...…

查看全部问答>

一种用N+1条线实现矩阵键盘的方法

键盘输入作为最常用的输入设备仍有其不可替代的作用。下面首先对传统键盘作一个简单的介绍。 (1)传统键盘的介绍键盘的结构通常有两种形式:线性键盘和矩阵键盘。在不同的场合下,这两种键盘均得到了广泛的应用。线性键盘由若干个独立的按键组成, ...…

查看全部问答>

给安防人的动力。

3G助力 600亿元的家庭监控市场等待挖掘 早在2004年,中国视频监控行业应用市场总产值就已经达到151亿元人民币,相比2003年的123亿元人民币增长了近23%,并以每年20%左右的速度不断增长。分析机构调研显示,随着生活节奏的不断加快,家庭用户对安全 ...…

查看全部问答>

求助:我有一定的c#语言基础,我现在要开发一个GIS/GPS系统,请高手给点入门思路!

我有一定的c#语言基础,我现在要开发一个GIS系统,请高手给点入门思路! 我现在有好多问题不懂, 比如在开发GPS/GIS系统之前是不是要会制作和编辑地图? 如何将现有的电子地图应用到开发中,比如在现有地图上经度和纬度等 也许高手会觉得我问的 ...…

查看全部问答>

请教WinCE系统启动问题

我用的是一块2410的开发板,根据资料说明定制的系统下载到扳子上,系统能正确启动,但是当我使用自定义的系统编译时会提示ROM与RAM的地址冲突,提示错误为: Copy Section Offset:     8cef6f84 FileSys 4K Chunks/Mbyte: 12 ...…

查看全部问答>

ST-LINKII可以支持MDK了

ST-LINK-II 可以支持MDK使用了!MDK3.22中文版已经在realview网站上发布了,里面已经集成了支持ST-LINKII的驱动,下载安装后就可以配合ST-LINKII使用。下载地址:http://www.realview.com.cn/down-list.asp?id=487…

查看全部问答>

用手机DIY车库遥控器

几乎所有今天制造的设备是使用遥控器。这使我们的生活更容易,因为现在的趋势是使一切东西简单化,用户没有那么多时间和精力去研究较为复杂的设备。通过这一改造,现在可以用电话遥控家里的车库门,而不像以前一样只有一个遥控器装置,而且也不用再 ...…

查看全部问答>

我做了一块485通讯板子,帮我看看?

     专业做单片机软硬件开发                地址:哈尔滨市 南岗区 会展中心             ...…

查看全部问答>

请教:TI的M4单片机中的自带ROM里的程序是出厂就烧制好的吗?

用户自己能不能更改这个ROM内容,或者供用户使用?…

查看全部问答>