STM32H743 USART DMA 空闲中断接收,收不到数据?

hhhh63 2020-01-27 08:55:02
代码如下:
void USART1_IRQHandler(void)
{
if(USART1->ISR &= USART_ISR_IDLE)
{
/* Receive Data */ // 这一句是从F4称过来的,不起作用
vu16 a = (uint16_t)(USART1->RDR & (uint16_t)0x01FF);
USART1->ICR |= USART_ICR_IDLECF; // 清除中断
u16 len = BUFSIZE - DMA2_Stream6->NDTR; //获得接收到的字节数
DMA2_Stream6->CR &= ~(1<<0); //关闭DMA传输
while( DMA2_Stream6->CR & 0X1 ); //确保DMA可以被设置

DMA2_Stream6->NDTR = m_nLen; //DMA 存储器0地址
DMA2_Stream6->CR |= 1<<0; //开启DMA传输
}
}

H743利用空闲中断接收数据,启动后能收到一条不全的数据,之后每次中断,len都是0,收不到任何信息。
对比了一下F1和F4的程序,有一句
USART_ReceiveData(USART6); // Clear IDLE interrupt flag bit
我查了一下,只有一行有效语句
return (uint16_t)(USART1->RDR & (uint16_t)0x01FF);
我把这一句加到中断过程的第一行,没有作用
请高手看看,或给一段正确的代码(寄存器版本),不胜感激。
...全文
1810 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
hhhh63 2020-05-25
  • 打赏
  • 举报
回复
引用 4 楼 韩同学叫园园 的回复:
你好,这个怎么清除CPU的缓存,要加哪一句代码呢?

对,加一行代码
// !!重要 停用CPU缓存,CPU能得到正确的DMA数据
// 地址要求32字节对齐,长度是32的位数
SCB_InvalidateDCache_by_Addr( (u32*)m_pRx, m_nLenRx );
加在获取长度之前
hhhh63 2020-05-25
  • 打赏
  • 举报
回复
对,加一行代码
// !!重要 停用CPU缓存,CPU能得到正确的DMA数据
// 地址要求32字节对齐,长度是32的位数
SCB_InvalidateDCache_by_Addr( (u32*)m_pRx, m_nLenRx );
加在获取长度之前
韩同学叫园园 2020-05-21
  • 打赏
  • 举报
回复
你好,这个怎么清除CPU的缓存,要加哪一句代码呢?
ba_wang_mao 2020-02-25
  • 打赏
  • 举报
回复
//STM32F103  DMA方式
void USART1_IRQHandler(void)
{
uint16_t ch;


if (USART_GetITStatus(USART1,USART_IT_IDLE) != RESET)
{
USART_ClearITPendingBit(USART1 , USART_IT_IDLE); //必须先清除总线空闲中断标识,然后读一下数据寄存器,DMA接收才会正确(先读SR,然后读DR才能清除空闲中断标识)注意:这句必须要,否则不能够清除中断标志位。
ch = USART_ReceiveData(USART1); //必须先清除总线空闲中断标识,然后读一下数据寄存器,DMA接收才会正确(先读SR,然后读DR才能清除空闲中断标识)注意:这句必须要,否则不能够清除中断标志位。

DMA_Cmd(DMA1_Channel5 , DISABLE); //关闭DMA,防止处理其间有数据
DMA_ClearFlag(DMA1_FLAG_GL5 | DMA1_FLAG_TC5 | DMA1_FLAG_HT5 | DMA1_FLAG_TE5);
ch = USART1_DMA_RX_BUFFER_MAX_LENGTH - DMA_GetCurrDataCounter(DMA1_Channel5);
if (ch > 0)
{
MB_USART1.Outtime_mark = TRUE;
MB_USART1.receCount = ch;
memcpy(MB_USART1.mscomm_buffer , USART1_DMA_RX_Buffer , MB_USART1.receCount);
}
DMA_SetCurrDataCounter(DMA1_Channel5 , USART1_DMA_RX_BUFFER_MAX_LENGTH);
DMA_Cmd(DMA1_Channel5, ENABLE);
}

else if (USART_GetITStatus(USART1,USART_IT_TC)!= RESET)
{
USART_ClearITPendingBit(USART1, USART_IT_TC);


DMA_ClearFlag(DMA1_FLAG_GL4 | DMA1_FLAG_TC4 | DMA1_FLAG_HT4 | DMA1_FLAG_TE4);
DMA_SetCurrDataCounter(DMA1_Channel4 , 0);

}
ba_wang_mao 2020-02-25
  • 打赏
  • 举报
回复
有库函数为什么非要用寄存器操作ARM单片机端口呢?
fareastwing 2021-06-16
  • 举报
回复
@ba_wang_mao 库函数用着一时爽,bug一出就麻烦得要死,很多应用本来就是用最简单基础的东西
hhhh63 2020-02-24
  • 打赏
  • 举报
回复
问题解决了,原因是没有清除CPU缓存。大家跟一下贴,我就结贴。

27,375

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧