硬汉嵌入式论坛

 找回密码
 立即注册
查看: 565|回复: 2
收起左侧

[技术讨论] STM32F1HAL库的HAL_TIM_OC_Stop_DMA疑似有Bug

[复制链接]

1

主题

3

回帖

6

积分

新手上路

积分
6
发表于 2023-5-17 10:57:47 | 显示全部楼层 |阅读模式
前天发了一个关于使用TIM输出比较+DMA做脉冲控制的帖子,

由于包装了一层步进电机控制使得问题不够简明,遂今天再重新做了一个工程,经过测试HAL库可能存在的bug。
bug的现象是使用HAL_TIM_OC_Start_DMA开启定时器后如果DMA传输未完成时用HAL_TIM_OC_Stop_DMA来结束会导致下次开启定时器的初始发生电平变化。
CubeMX的配置不变,具体如下:
img1.png
img2.png
img3.png
复现Bug的程序
主程序
[C] 纯文本查看 复制代码
__weak void TaskOutput(void const * argument)
{
  /* USER CODE BEGIN TaskOutput */
  int cnt = 0;
  const int size = 20;
  uint16_t BUF[size]; //DMA传输比较值到CCR1寄存器
  /* 生成测试数据 */
  BUF[0] = 100;
  for (size_t i = 1; i < size; i++)
  {
    BUF[i] = BUF[i-1] + 100;
  }
  /* Infinite loop */
  for(;;)
  {
    TIM2->CNT = 0;
    TIM2->CCR1 = BUF[0];
    PinDEBUG1(1); //翻转IO,Debug用
    HAL_TIM_OC_Start_DMA(&htim2,
                        TIM_CHANNEL_1,
                        (uint32_t*)&BUF[1],
                        19);
    osDelay(1);
    cnt ++;
    if (cnt > 5 && cnt < 15)
    {
        HAL_TIM_OC_Stop_DMA(&htim2, TIM_CHANNEL_1);
    }
    osDelay(100);
  }
  /* USER CODE END TaskOutput */
}


在中断回调里面
一次传输会进入三次中断,DMA传输中断,开启输出比较的中断和最后一次比较发生的中断,
下面分别对三次中断做处理。
[C] 纯文本查看 复制代码
int endflag = 0; //用来跳过因使能中断而产生的中断
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
    PinDEBUG2(1);
    if (endflag == 1)
    {
        endflag = 0;
        PinDEBUG2(0);
        return;
    }
    if (__HAL_TIM_GET_ITSTATUS(&htim2, TIM_IT_CC1) == RESET)
    {
        __HAL_TIM_ENABLE_IT(&htim2, TIM_IT_CC1);
        endflag = 1;
        PinDEBUG2(0);
        return;
    }
    __HAL_TIM_DISABLE_IT(&htim2, TIM_IT_CC1);
    HAL_TIM_OC_Stop_DMA(&htim2, TIM_CHANNEL_1);
    PinDEBUG2(0);
    PinDEBUG1(0);
}


测试
打开逻辑分析仪,复位单片机可以看到以下波形
img4.png
先看异常波形
img5.png
再看看异常波形
img6.png

附件
程序位于 Core/Src/freertos.c Line182、Line271
引脚
TIM2_CH0  ---  PA0
debug1Pin  ---  PF0
debug2Pin  ---  PF1
STM32F103ZE_TIM_OC_DMA_0517.rar (1.46 MB, 下载次数: 3)
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106590
QQ
发表于 2023-5-18 07:57:27 | 显示全部楼层
我认为楼主应该搞个DMA双缓冲来控制DMA传输数值,有时间的话,可以试试是否可行。

开半传输完成中断和传输完成中断。进入最后一次后,在半传输完成里面将DMA前一半缓冲清除为一个值(你看看设置为多少合适,设置为0还是为ARR,或者其它,目的是不再触发脉冲了),传输完成中断里面将后面半个缓冲也清除为这个值,然后关闭DMA,这样应该就避免了末尾的随机情况。
回复

使用道具 举报

1

主题

3

回帖

6

积分

新手上路

积分
6
 楼主| 发表于 2023-5-18 21:00:22 | 显示全部楼层
问题已暂时解决,具体请移步STM32中文论坛:https://shequ.stmicroelectronics.cn/thread-640156-1-1.html
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-26 06:38 , Processed in 0.166082 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表