华大HC32F460 USART DMA超时接收 爬坑

本文详细介绍了在STM32系统中使用USART、DMA和TIME0实现数据帧超时接收的配置和调试过程,包括模块配置、事件触发和隐藏关联的解析。在调试过程中发现,TIME0的某些功能并未在数据手册中明确说明,但通过实验确定了USART与TIME0通道的对应关系。此外,还分享了DMA初始化、USART设置以及接收溢出错误处理的注意事项,强调了代码细节对功能实现的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

1. 基本框图

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

 

         其中,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里没有这个操作,,不得不怀疑是不是压根就没测试接收溢出问题,,, 

<think>嗯,用户想知道如何在HC32F460芯片中实现串口通信和超时处理的示例代码和参考文档。我需要先回忆一下之前提供的引用内容,看看有没有相关的信息。 首先,引用[1]提到HC32F460使用接收超时中断代替STM32的空闲中断,需要配置Timer0 Unit2 B通道。这可能涉及到定时器和串口的配合设置。引用[2]讨论了使用DMA配合超时中断的方案,特别适合作为从机需要快速响应的情况,同时提到了GPIO复用和中断配置的问题。引用[3]中的代码片段显示DMA源地址的设置,可能涉及到寄存器地址的偏移。 接下来,用户需要示例代码和文档参考。我应该先整理实现步骤,然后给出代码结构,并指出关键配置点。比如,初始化USARTDMA、定时器,以及中断处理函数。 需要确保代码结构正确,比如USART的GPIO配置、DMA通道选择、定时器的设置,特别是超时时间的计算。引用中提到超时中断需要定时器,所以应该配置Timer0 Unit2 B。还要注意DMA的源地址是否正确,引用[3]中的+2ul可能涉及到对齐问题,需要注意。 另外,引用[2]提到华大的中断配置需要查表,容易出错,所以在代码中需要特别提醒用户注意中断向量和优先级的设置。同时,GPIO复用功能灵活,配置时要确保正确映射到USART引脚。 关于参考文档,用户手册和相关的应用笔记是必须的,比如HC32F460用户手册的USARTDMA章节,以及定时器部分。可能还需要华大提供的SDK中的示例代码作为参考,比如USART_DMA或Timer相关的例程。 在示例代码中,可能需要包括初始化函数、中断服务函数,以及主循环中的处理逻辑。例如,启动DMA接收,定时器超时后触发中断,然后在中断中处理接收到的数据,并重置相关标志。 还要注意DMA接收缓冲区的管理,确保在超时中断发生时能够正确读取数据长度,并处理数据。可能需要使用双缓冲或者环形缓冲区来提高效率,但示例代码可能简化这一点,只展示基本流程。 最后,生成相关问题时要围绕实现细节、优化方法、与其他芯片的区别,以及常见问题处理,这样用户能进一步深入理解。</think>根据参考资料,现提供HC32F460串口通信的超时处理实现方案和示例代码框架: ### 一、实现步骤 1. **硬件配置** - 配置USART引脚复用功能(需参考GPIO复用映射表)[^2] - 使能USART时钟和DMA时钟 2. **关键配置项** ```c // USART4配置(波特率/数据位/校验位) stc_usart_uart_init_t stcUartInit = { .u32Baudrate = 115200, .u32BitDirection = USART_LSB, .u32StopBit = USART_ONE_STOPBIT, .u32Parity = USART_PARITY_NONE }; // DMA配置(通道选择需参考手册映射) stc_dma_init_t stcDmaInit = { .u32IntEn = DMA_INT_ENABLE, .u32BlockSize = 1, .u32TransCnt = sizeof(rx_buffer), .u32SrcAddr = ((uint32_t)(&USART4->DR) + 2ul), // 注意地址偏移[^3] .u32DestAddr = (uint32_t)rx_buffer }; // 定时器配置(超时时间计算) stc_tim0_base_init_t stcTim0Init = { .u32Division = TIM0_CLK_DIV1, .u32Period = 0xFFFF, // 超时时间=Period/(PCLK/Division) .u32StartValue = 0 }; ``` 3. **中断配置** ```c // 注册接收超时中断(Timer0 Unit2 B通道) INTC_IrqSignOut(TIM0_2_IRQn); INTC_IrqRegister(TIM0_2_IRQn, USART_TimeoutIRQHandler); ``` ### 二、示例代码框架 ```c #define RX_BUFFER_SIZE 256 uint8_t rx_buffer[RX_BUFFER_SIZE]; void USART4_Init(void) { // 1. GPIO复用配置(PA2/TXD, PA3/RXD) GPIO_SetFunc(GPIO_PORT_A, GPIO_PIN_2|GPIO_PIN_3, GPIO_FUNC_7); // 2. USART初始化 USART_UART_Init(USART_CHANNEL_4, &stcUartInit); // 3. DMA接收配置 DMA_Init(DMA_CH0, &stcDmaInit); USART_RxDmaCmd(USART_CHANNEL_4, ENABLE); // 4. 定时器超时中断配置 TIMER_BaseInit(TIM0_UNIT2, &stcTim0Init); TIMER_IrqCmd(TIM0_UNIT2, ENABLE); } // 超时中断处理函数 void USART_TimeoutIRQHandler(void) { if(TIMER_GetStatus(TIM0_UNIT2, TIMER_BCONR_CBDF)) { TIMER_ClearStatus(TIM0_UNIT2, TIMER_BCONR_CBDF); /* 处理接收数据 */ uint16_t len = RX_BUFFER_SIZE - DMA_GetTransCount(DMA_CH0); USART_ProcessData(rx_buffer, len); /* 重启DMA接收 */ DMA_Reload(DMA_CH0, sizeof(rx_buffer)); } } ``` ### 三、参考文档 1. 《HC32F460用户手册》USART章节(描述超时中断机制)[^1] 2. 华大官方SDK中的`HC32F460_DDL_Revx.x.x\examples\usart\usart_dma`示例 3. 定时器配置参考《TIMER应用笔记》(AN0702) 4. DMA地址映射表(需特别注意外设地址偏移计算)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值