硬汉嵌入式论坛

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

[ADC] H723 ADC DMA方式,偶尔会发生超时,百思不得其解

[复制链接]

7

主题

24

回帖

50

积分

初级会员

积分
50
发表于 2025-1-2 15:18:42 | 显示全部楼层 |阅读模式
使用Freertos,但是只有一个任务每秒调用一次ADC,所以不存在重入的问题。


定义:

    typedef uint16_t adcval_t;

    typedef struct adc_t
    {
        ADC_HandleTypeDef *hadc;
        uint32_t chs; // AD采样的通道数
        volatile int adc_st;        // -1:failed, 0:running, 1:completed
        uint32_t timeout_ns; // 超时
        sram_block_t dma_buf; // DMA buffer, 预先分配在D2/D3区
    } adc_t;


函数:

void RunAdc(adc_t *adc)
{
    adc->adc_st = 0; // 清标志
    int rtv = 0;
    if (HAL_OK != HAL_ADC_Start_DMA(adc->hadc, (uint32_t *)(adc->dma_buf.pData), adc->chs)) // 启动ADC
    {
        rtv = -1;//启动失败
    }
    else
    {
        nsTmr_t ns;
        SetNsTmr(&ns, adc->timeout_ns); // 使用定时器做超时判断
        while (adc->adc_st == 0) // 等完成标志
        {
            if (IsNsTmrExpired(&ns))
            {
                rtv = -2;  // 超时
                break;
            }
        }
        if (HAL_OK != HAL_ADC_Stop_DMA(adc->hadc))
        {
            rtv = -3;//停止失败
        }
    }
    if (rtv != 0)
    {//有错,写标志,清除数据
        adc->adc_st = rtv;
        memset(adc->dma_buf.pData, 0, adc->dma_buf.size);
    }
}



中断中完成调用:
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
    if (hadc == adc2.hadc)
    {
        adc2.adc_st = 1;//完成
    }
    else if (hadc == adc3.hadc)
    {
        adc3.adc_st = 1;//完成
    }
}


ADC时钟24M,6个通道,16倍超采样。那么做一次AD需要(2.5+7.5)*16*6个ADC时钟周期=40uS,我给了1ms+3*40us的timeout。

偶尔发生超时的情况,在“rtv = -2;”,短的时候间隔几分钟,长的间隔有3天。
调试方式下,在HAL_ADC_ErrorCallback下断点,超时发生的时候也没有触发。




实在无法理解为什么AD会无法完成,请各位大侠指导一下。谢谢













回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2025-1-2 15:45:18 | 显示全部楼层
方便的话,ADC配置也分享下
回复

使用道具 举报

7

主题

24

回帖

50

积分

初级会员

积分
50
 楼主| 发表于 2025-1-3 06:40:38 | 显示全部楼层
eric2013 发表于 2025-1-2 15:45
方便的话,ADC配置也分享下

1.png
选了6个通道,4个是IO单端方式+Vbat+Temp,使用DMA




3.png
中断


4.png
DMA配置

5.png
6.png
7.png
8.png
AD的配置,6个Rank是一样的配置




回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2025-1-4 06:31:17 | 显示全部楼层
regsofweb 发表于 2025-1-3 06:40
选了6个通道,4个是IO单端方式+Vbat+Temp,使用DMA

设置抢占优先级到0,看看正常不

124.png
回复

使用道具 举报

6

主题

306

回帖

324

积分

高级会员

积分
324
发表于 2025-1-8 15:19:24 | 显示全部楼层
ADC时钟计算公式是 2.5+8.5,注意,不是7.5,手册中的7.5是在14位模式下。
回复

使用道具 举报

6

主题

306

回帖

324

积分

高级会员

积分
324
发表于 2025-1-8 15:21:29 | 显示全部楼层
企业微信截图_20250108152110.png
回复

使用道具 举报

6

主题

306

回帖

324

积分

高级会员

积分
324
发表于 2025-1-8 15:23:55 | 显示全部楼层
企业微信截图_20250108152325.png

所以是不是你采样时间计算错误造成的超时?
回复

使用道具 举报

7

主题

24

回帖

50

积分

初级会员

积分
50
 楼主| 发表于 2025-1-13 10:24:20 | 显示全部楼层
fxyc87 发表于 2025-1-8 15:23
所以是不是你采样时间计算错误造成的超时?

谢谢指正。但应该不是这个问题,因为我多给了1ms的超时,正常可定不会超
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-8-14 06:37 , Processed in 0.046321 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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