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

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管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版