华大HC32F460 USART DMA超时接收 爬坑

        USART DMA通过TIME0超时接收数据帧这个功能虽然在数据手册上提过,但是官方demo不给,网上的代码要么不全要么驱动版本不一致,于是有这个坑

1. 基本框图

涉及到的模块:USART,AOS, DMA

 华大HC32F460 USART DMA超时接收 爬坑_第1张图片

         其中,AOS模块不需要CPU的参与即可触发,触发源记为event,触发接口记为socket,socket会关联相关动作。

大坑注意:

1)图中的实线是数据手册明确说明的event和socket,需要配置,相关代码:

    /* Enable peripheral circuit trigger function. */
    PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_AOS,Enable);

    /* Set DMA trigger source. */
    DMA_SetTriggerSrc(DMA_UNIT, DMA_CH, DMA_TRG_SEL);

 2)图中的虚线是隐藏的关联,不需要明确配置(也不能),数据手册中关于TIME0的这块并没有明确说明,这是实际调试中总结出来的,原理不一定对,但是可用,啊,

根据测试,配置USART的RTOE即可开启这两个虚线,并且他们的对应关系是固定的

USART1:Timer0 Unit1 A 通道
USART2:Timer0 Unit1 B 通道
USART3:Timer0 Unit2 A 通道
USART4:Timer0 Unit2 B 通道

3)TIME0有两个实例01和02,每个实例有两个通道,即1A, 1B, 2A, 2B,这4个通道共用一个socket ,通过HTSSR配置(这个寄存器在AOS里),在USART超时例子中用不到!!!并且不知道这个和图中的虚线功能的关系,有闲心可以测试

2. 具体实现和调试

1) 初始化TIME0,按模板开启就行

2) 初始化DMA,配置socket,参考DEMO中DMA的例子

3)初始化USART,复制粘贴没毛病

在MDK中调试的适合直接写寄存器来跑流程

如图,当用USART1时,

1)使能RE, RTOE,对应的TIME01A即关联到了(即图中的虚线使能),HSTAB和HCLEB使能,

2)配置的ctrl socket触发模式,此时除能CSTA,TIME01A未触发

3)通过写CRTOF清除RTOF标志位,准备就绪

4)通过上位机发送串口数据,此时会触发CNTAR运行,CSTA会变为1,当CNTAR运行到设定数值时,RTOF置位,此时手动清除CSTA和RTOF,即超时动作,在代码里需要开启RTOIE来启用中断从而执行这个动作(还有DMA复位等)。

5)原文档中有一句 “单元 1 的通道 A 的比较匹配中断(TMR0_U1_GCMA)仅在异步计数方式
(BCONR.SYNSA=1)时可用”,实际测试USART 超时中01A是可以用同步方式的,这句话可能仅指中断不可用,

3,其他

1)DMA源地址代码给出的是DR+2,

stcDmaInit.u32SrcAddr = ((uint32_t)(&USART_CH->DR)+2ul); /* Set source address. */

此处一大坑是,DR+2的值与DR的类型有关,如果DR是指针,实际数值是DR+2*4,加一个强制转换更好

改进:stcDmaInit.u32SrcAddr = ((uint32_t)((uint32_t)(&huart->DR)+2ul)); 

2)DMA重启问题

DMA重启后,需要经过关DMA→重新设置目的地址→开DMA流程

其中,为了不出现DMA内存溢出问题,需要对DMA接收数据长度进行限制,此时对于HC32460测试表明,其传输次数寄存器需要重新配置和载入,否则会出现异常

2)接收溢出等错误处理

        HC460中UART一旦接收错误,如果不清除错误标志位,则后续接收均失败,因此错误处理是必须的。清除错误标志位时,还需要读一下接收数据寄存器,清空寄存器里面的数据以避免下一次接收失败。话说官方demo里没有这个操作,,不得不怀疑是不是压根就没测试接收溢出问题,,, 

你可能感兴趣的:(HC32F460,单片机)