你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F103ZET6 HAL库使用串口1DMA空闲中断接收数据时CNDTR寄存器问题,该如何解决?

[复制链接]
围院 提问时间:2023-10-20 17:21 / 未解决

在STM32F103ZET6开发过程中,用到HAL库中的串口1DMA空闲中断处理数据时发现:

当接收数据长度超过16字节后,(__HAL_DMA_GET_COUNTER(&huart1.hdmarx))也就是串口1的CNDTR寄存器会首先减16,然后恢复到给定长度,再次进入中断减去剩余长度(又或当长度超过16字节后空闲中断再次进入) 例如限定接收数据长度为0xFFF,当接收数据超过0x0F(例0x12)后,CNDTR寄存器会首先变为0xFF0,然后回到0xFFF,再变为0xFFE。

程序波特率115200,数据位8,停止位1。如何解决呢?

以下是部分代码块

#define UART_RX_LEN 4096
uint8_t UART_RX_BUF[UART_RX_LEN];
__IO uint16_t UART_RX_STA = 0;

/************串口中断代码***********/
void USART1_IRQHandler(void)
{
  if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET)  // 空闲中断标记被置位
  {
      __HAL_UART_CLEAR_IDLEFLAG(&huart1);  // 清除中断标记
      HAL_UART_DMAStop(&huart1);           // 停止DMA接收
      UART_RX_STA = UART_RX_LEN - huart1.hdmarx->Instance->CNDTR;  // 总数据量减去未接收到的数据量为已经接收到的数据量
      UART_RX_STA |= 0X8000;         // 标记接收结束
      HAL_UART_Receive_DMA(&huart1, UART_RX_BUF, UART_RX_LEN);  // 重新启动DMA接收
      __HAL_UART_ENABLE_IT((&huart1), UART_IT_IDLE);    //重新开启串口接收帧中断
  }
}

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();
  HAL_UART_Receive_DMA(&huart1, UART_RX_BUF, UART_RX_LEN);  // 启动DMA接收
  __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);              // 使能空闲中断
  while (1)
  {  
    if(UART_RX_STA & 0X8000)
    {
      /**********接收数据处理代码*****************/
      UART_RX_STA = 0;  // 清除标记
      UART_RX_FLAG=0;
    }
  }
}
收藏 评论6 发布时间:2023-10-20 17:21

举报

6个回答
xmshao 回答时间:2023-10-23 14:52:47
从你给出来的IDLE处理代码来看,似乎没有什么问题。




你代码里还开启了别的什么中断吗?或者代码哪里有误?


或者你把中断里的HAL_UART_Receive_DMA(&huart1, UART_RX_BUF, UART_RX_LEN);  及后面


中断使能的两句 放到你的main循环里清除标志之后试试。
butterflyspring 回答时间:2023-10-23 14:57:13
这个代码结构似乎是个人开发的,与现在库函数不同。

本身库中有完整的启动函数和中断处理函数,并有接收完成的回调函数可用。

建议还是用库中的架构为好(最好是新版),自己改写的话中间很多细节需要关注,尽量用现成的。

Stm32f103 receive IDLE_it UART .PNG
围院 回答时间:2023-10-24 11:42:15

xmshao 发表于 2023-10-23 14:52
从你给出来的IDLE处理代码来看,似乎没有什么问题。</p>
<p>

代码中还包含以下的中断,但我认为以下中断不会影响串口的接收空闲中断功能:image.pngimage.pngimage.png

围院 回答时间:2023-10-24 11:44:30

butterflyspring 发表于 2023-10-23 14:57
这个代码结构似乎是个人开发的,与现在库函数不同。</p>
<p>本身库中有完整的启动函数和中断处理函数,并有接收完 ...

使用库中的空闲中断回调函数

HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle(UART_HandleTypeDef huart, uint8_t pData, uint16_t Size)

其内部逻辑也是调用的串口空闲中断,尝试这个函数时也会出现不进位的问题。

butterflyspring 回答时间:2023-10-24 15:58:19
库中串口的中断处理与你写的代码有些许差异。
如果楼主觉得串口等逻辑是正确的,不妨看看计算时是不是数据类型转换的问题。


stm32f1 DAM define.PNG



xmshao 回答时间:2023-10-25 14:55:53

围院 发表于 2023-10-24 11:42
代码中还包含以下的中断,但我认为以下中断不会影响串口的接收空闲中断功能:!(data/attachment/foru ...

[md]要验证是否别的中断影响IDLE中断了,把UART idle中断优先级设置到最高即可验证;

另外,也可以考虑下堆栈方面的问题。再就是仔细检查下代码,变量定义、数组大小这些是否有

小疏忽的地方。

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版