[新品上市] 【APM32F107VCT6 MINI开发板测评】之串口空闲帧中断DMA接收

[复制链接]
1597|16
 楼主| woai32lala 发表于 2023-3-19 21:31 | 显示全部楼层 |阅读模式
本帖最后由 woai32lala 于 2023-3-19 21:36 编辑


    【APM32F107VCT6 MINI开发板测评】之串口空闲帧中断DMA接收

准备
发送XCOM2串口助手
波特率115200   RX   PA10
DMA1  通道channel5
  1. /**
  2. * [url=home.php?mod=space&uid=247401]@brief[/url] Definition for COM port1, connected to USART1
  3. */
  4. #define MINI_COM1                        USART1
  5. #define MINI_COM1_CLK                    RCM_APB2_PERIPH_USART1
  6. #define MINI_COM1_TX_PIN                 GPIO_PIN_9
  7. #define MINI_COM1_TX_GPIO_PORT           GPIOA
  8. #define MINI_COM1_TX_GPIO_CLK            RCM_APB2_PERIPH_GPIOA
  9. #define MINI_COM1_RX_PIN                 GPIO_PIN_10
  10. #define MINI_COM1_RX_GPIO_PORT           GPIOA
  11. #define MINI_COM1_RX_GPIO_CLK            RCM_APB2_PERIPH_GPIOA
  12. #define MINI_COM1_IRQn                   USART1_IRQn

  13. /**
  14. * [url=home.php?mod=space&uid=247401]@brief[/url] Definition for COM port2, connected to USART2
  15. */
  16. #define MINI_COM2                        USART2
  17. #define MINI_COM2_CLK                    RCM_APB1_PERIPH_USART2
  18. #define MINI_COM2_TX_PIN                 GPIO_PIN_2
  19. #define MINI_COM2_TX_GPIO_PORT           GPIOA
  20. #define MINI_COM2_TX_GPIO_CLK            RCM_APB2_PERIPH_GPIOA
  21.                                                                      
  22. #define MINI_COM2_RX_PIN                 GPIO_PIN_3
  23. #define MINI_COM2_RX_GPIO_PORT           GPIOA
  24. #define MINI_COM2_RX_GPIO_CLK            RCM_APB2_PERIPH_GPIOA
  25. #define MINI_COM2_IRQn                   USART2_IRQn

  我们平时接收固定长度的一般用普通串口中断或者DMA传送完成中断,但串口普通中断是接收到1个字节就会中断一次,这样严重拖慢了CPU的效率。DMA传送完成中断一般是用于固定字节的传输, 但是如果我们发送的数据长度是不固定的怎么办呢?STM32有串口空闲中断,HC32有串口超时钟中断,那么极海AMP32有什么呢?
图片2.png
  我们查阅用户手册发现,极海AMP32有串口空闲帧中断。
那么空闲帧是什么呢?

其实可以说和Stm32的空闲IDLE一样,就是超过1个字节连续高电平,还有断开帧等,如下图所示。
图片3.png

普通的一帧数据有起始位、1个字节数据和停止位。空闲帧没有起始位,是一帧连续高电平。断开是发送一个0x00,其实我有点疑问,那么0x00万一是有效数据视为断开帧咋那么解决,等官方解释一下,我们继续往下说。
图片4.png

像我们下面发送的两帧数据,就可以用空闲帧中断来获取,两帧数据之间有超过一个字节的高电平时间。
图片5.png
要使能空闲帧中断生效,需要我们使能空闲帧中断,也就是这个函数。
图片6.png

串口配置
  1. * [url=home.php?mod=space&uid=247401]@brief[/url]       Configures COM port.
  2. *
  3. * @param       COM: Specifies the COM port to be configured.
  4. *              This parameter can be one of following parameters:
  5. *              [url=home.php?mod=space&uid=2817080]@ARG[/url] COM1
  6. *              [url=home.php?mod=space&uid=2817080]@ARG[/url] COM2
  7. *
  8. * @retval      None
  9. */
  10. void APM_MINI_COMInit(COM_TypeDef COM, USART_Config_T* configStruct)
  11. {
  12.     GPIO_Config_T GPIO_configStruct;

  13.     /* Enable GPIO clock */
  14.     RCM_EnableAPB2PeriphClock(COM_TX_PORT_CLK[COM] | COM_RX_PORT_CLK[COM]);

  15.     if (COM == COM1)
  16.     {
  17.         RCM_EnableAPB2PeriphClock(COM_USART_CLK[COM]);
  18.     }
  19.     else
  20.     {
  21.         RCM_EnableAPB1PeriphClock(COM_USART_CLK[COM]);
  22.     }

  23.     /* Configure USART Tx as alternate function push-pull */
  24.     GPIO_configStruct.mode = GPIO_MODE_AF_PP;
  25.     GPIO_configStruct.pin = COM_TX_PIN[COM];
  26.     GPIO_configStruct.speed = GPIO_SPEED_50MHz;
  27.     GPIO_Config(COM_TX_PORT[COM], &GPIO_configStruct);

  28.     /* Configure USART Rx as input floating */
  29.     GPIO_configStruct.mode = GPIO_MODE_IN_FLOATING;
  30.     GPIO_configStruct.pin = COM_RX_PIN[COM];
  31.     GPIO_Config(COM_RX_PORT[COM], &GPIO_configStruct);

  32.     /* USART configuration */
  33.     USART_Config(COM_USART[COM], configStruct);

  34.     /* Enable USART */
  35.     USART_Enable(COM_USART[COM]);

  36. }
以上是串口相关函数,下面是DMA部分。

DMA配置
直接存储器访问 (DMA) 用于在外设与存储器之间以及存储器与存储器之间提供高速数据传输。可以在无需任何 CPU 操作的情况下通过 DMA 快速移动数据。这样节省的 CPU 资源可供其它操作使用。说白了DMA就是一个搬运工,将数据从一个地方搬到另一个地方而不需要CPU处理。作为一个搬运工,要他正常工作必须要确定几个重要的参数:
传输模式:数据从哪里搬到哪里。三种可能的传输方向:存储器到外设、外设到存储器或存储器到存储器,我们我次选择的方向是从外设到内存DMA_DIR_PERIPHERAL_SRC
通道选择:就是数据传输的是走那条道路,这里是DMA1channel5
仲裁器:多个DMA传输是优先级高的优先传输。
传输字节量:我们这里设置200,最大为65535,根据需求设置。
数据长度:每次传输的数据长度,可以一个字节,两个字节(半字),四个字节()
指针递增:如果使能了递增模式,则下一次传输的地址将是前一次传输的地址递增 1(字节)2(半字)4(),我们这里用1个字节。
循环模式:循环模式可用于处理循环缓冲区和连续数据流(例如 ADC 扫描模式)。可以使用 DMA_SxCR寄存器中的 CIRC 位使能,我们用正常模式
其他:关于DMA还有双缓冲区模式、突发传输等等其他设置,一般用不到,具体查询用户手册。
我们这里DMA只需要作为通道,不需要进行中断,DMA中断我们不使能。
图片7.png

中断接收函数
图片8.png
  1. void USART1_Isr(void)
  2. {
  3.     if(USART_ReadIntFlag(USART1, USART_INT_IDLE))
  4.     {

  5.         USART_ClearIntFlag(USART1, USART_INT_IDLE);         //清除中断标志
  6.         USART_RxData(USART1);
  7.         DMA_Disable(DMA1_Channel5);
  8.         /* Data number */
  9.         data_num = BufSize -  DMA_ReadDataNumber(DMA1_Channel5);
  10.         DMA_ConfigDataNumber(DMA1_Channel5,BufSize);
  11.         DMA_Enable(DMA1_Channel5);
  12.         APM_MINI_LEDToggle(LED2);

  13.     }
  14. }

测试
接线

图片9.png
XCOM2发送数据
图片10.png

MCU接收到数据
图片11.png

我们可以看到右侧Watch中有35个数据,且数据跟我们发送一致,数量也一致,并用过LED灯反转来表示接收数据次数,因此增加Demo测试成功。


  

DMA_UsartToMemory_IDLE.zip

3.66 MB, 下载次数: 3

tpgf 发表于 2023-4-11 16:14 | 显示全部楼层
一般来说 一帧数据的最大长度是多少呢
观海 发表于 2023-4-11 16:48 | 显示全部楼层
如何识别空闲帧是否已经传输完成了呢
 楼主| woai32lala 发表于 2023-4-11 17:41 | 显示全部楼层
观海 发表于 2023-4-11 16:48
如何识别空闲帧是否已经传输完成了呢

IDLE标志位
 楼主| woai32lala 发表于 2023-4-11 17:41 | 显示全部楼层
tpgf 发表于 2023-4-11 16:14
一般来说 一帧数据的最大长度是多少呢

不超过SIZE数据类型
guanjiaer 发表于 2023-4-12 11:11 | 显示全部楼层
使用DMA会节省的CPU 资源,那么这个节省的占比一般能达到多少呢
heimaojingzhang 发表于 2023-4-12 11:36 | 显示全部楼层
请问什么是空闲帧啊 它的具体格式是什么呢
keaibukelian 发表于 2023-4-12 11:53 | 显示全部楼层
heimaojingzhang 发表于 2023-4-12 11:36
请问什么是空闲帧啊 它的具体格式是什么呢

空闲帧的长度可配置。在 Profibus 协议中,空闲帧长度为 33 位
paotangsan 发表于 2023-4-12 12:04 | 显示全部楼层
完全由1组成的帧称为空闲帧
cemaj 发表于 2023-5-5 19:42 | 显示全部楼层
一直想要测试一下APM32F107VCT6 芯片的性能  
mollylawrence 发表于 2023-5-5 20:08 | 显示全部楼层
当DMA传输完成后,可以使用回调函数或者其他方式进行数据处理。
pl202 发表于 2023-5-5 21:23 | 显示全部楼层
在使用DMA接收串口数据时,可以开启串口空闲帧中断,并配置DMA通道为循环模式。当串口接收到完整的数据帧后,触发空闲帧中断,此时DMA通道自动打开并开始传输数据。
zerorobert 发表于 2023-5-5 22:08 | 显示全部楼层
需要注意的是,在使用DMA接收串口数据时,需要设置DMA传输数据的长度,以确保传输正确的数据量。
bartonalfred 发表于 2023-5-5 22:39 | 显示全部楼层
空闲中断接收,当一帧数据接收完成之后,串口会进入到空闲中断中去,然后在空闲中断中处理收到的数据。
pentruman 发表于 2023-5-5 22:49 | 显示全部楼层
DMA(直接内存访问)技术可以减轻CPU的负担,实现高效、快速的数据传输。
mikewalpole 发表于 2023-5-6 00:10 | 显示全部楼层
需要考虑数据的粘包和分包问题,以及对于异常情况的处理,例如溢出等。
abotomson 发表于 2023-5-7 13:55 | 显示全部楼层
串口空闲帧中断是指当串口接收到完整的数据帧后,在接收下一个数据帧之前会出现一段时间的空闲期,可以利用这段时间来进行一些处理。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

108

主题

559

帖子

6

粉丝
快速回复 在线客服 返回列表 返回顶部