硬汉嵌入式论坛

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

[RTOS] RTOS系统中ADC采集的实时性问题

[复制链接]

20

主题

102

回帖

162

积分

初级会员

积分
162
QQ
发表于 2025-7-7 12:56:20 | 显示全部楼层 |阅读模式
是这样的,我的任务是要采集256个喷孔的对应信号,这256个喷孔都有一个点火信号,是1khz的方波。
然后我配置的ADC是1.9Mhz,开启的两倍过采样,当然,我关闭过采样也尝试过。都不对
就是外部上升沿接收这个点火信号(黄色的)之后触发中断,在中断函数里面进行任务通知ADC采集任务。
当采集完一个喷孔之后在DMA的回调函数里切换下一个喷孔。
现在的问题是采集出来的数据不对应。不知道是我的硬件没有硬实时吗?
这个如何验证呢?因为这个外部中断1khz的方波没法关闭,他从1-256循环完会自动再重新循环,所以我在ADC任务中采集够256个数组就进行任务自杀。


MPU,cache什么的都关闭掉了。 微信图片_20250707124631.jpg
ADC配置:

  hadc3.Instance = ADC3;
  hadc3.Init.Resolution = ADC_RESOLUTION_16B;
  hadc3.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc3.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc3.Init.LowPowerAutoWait = DISABLE;
  hadc3.Init.ContinuousConvMode = ENABLE;
  hadc3.Init.NbrOfConversion = 1;
  hadc3.Init.DiscontinuousConvMode = DISABLE;
  hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc3.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_ONESHOT;
  hadc3.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  hadc3.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
  hadc3.Init.OversamplingMode = ENABLE;
  hadc3.Init.Oversampling.Ratio =2;
  hadc3.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_1;
  hadc3.Init.Oversampling.TriggeredMode = ADC_TRIGGEREDMODE_SINGLE_TRIGGER;
  hadc3.Init.Oversampling.OversamplingStopReset = ADC_REGOVERSAMPLING_CONTINUED_MODE;

中断回调函数:
#define ADC_DATA_LENGTH 128    //定义采集数据长度
volatile uint32_t current_sample_index = 0; //当前采集的喷孔号
static uint16_t data[TOTAL_SAMPLES][ADC_DATA_LENGTH];  //256组


void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {   //外部中断回调函数
    BaseType_t xGPIO_risingTaskWoken = pdFALSE;
    if (GPIO_Pin == GPIO_PIN_1) {
        vTaskNotifyGiveFromISR(ADCTaskHandle, &xGPIO_risingTaskWoken);    //通知ADC采集任务
        portYIELD_FROM_ISR(xGPIO_risingTaskWoken);  //有必要的话进行任务切换
    }
}

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) {
    if (hadc->Instance == ADC3) {
        HAL_ADC_Stop_DMA(&hadc3);
        current_sample_index++;           //每采集完一个喷孔切换下一个喷孔
    }
}

ADC采集任务:
void ADCTask_Task(void *arg) {
    TickType_t previousWakeTime = xTaskGetTickCount();
    BaseType_t result;
    while (1) {
        result = ulTaskNotifyTake(pdFALSE, portMAX_DELAY);
        if (result == pdTRUE) {
            HAL_ADC_Start_DMA(&hadc3, (uint32_t *)data[current_sample_index], ADC_DATA_LENGTH);
        }
        if (current_sample_index >= TOTAL_SAMPLES) {                         //采集完256个数组开始创建打印任务
                                        xTaskCreate(PrintfTask,"PrintfTask",512,NULL,5,(TaskHandle_t *)&PrintfTaskHandle);
            vTaskDelete(NULL);
        }
    }
}





回复

使用道具 举报

7

主题

158

回帖

179

积分

初级会员

积分
179
发表于 2025-7-7 13:36:23 | 显示全部楼层
用裸机吧,分分钟秒杀,
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2025-7-8 09:09:32 | 显示全部楼层
1.9M采集256个点,基本上,远小于1ms就采集完毕了,所以对应不上是正常的。
回复

使用道具 举报

6

主题

60

回帖

78

积分

初级会员

积分
78
发表于 2025-7-9 09:00:13 | 显示全部楼层
有没有硬件的示意图?
回复

使用道具 举报

20

主题

102

回帖

162

积分

初级会员

积分
162
QQ
 楼主| 发表于 2025-7-10 09:41:23 | 显示全部楼层
eric2013 发表于 2025-7-8 09:09
1.9M采集256个点,基本上,远小于1ms就采集完毕了,所以对应不上是正常的。

但是我的这个驱动采集的信号是1khz的,ADC开启了2倍过采样,我采集完就在回调函数里面停止了ADC,等下一次中断再通知采集
回复

使用道具 举报

20

主题

102

回帖

162

积分

初级会员

积分
162
QQ
 楼主| 发表于 2025-7-10 09:41:41 | 显示全部楼层
红烧鱼头 发表于 2025-7-9 09:00
有没有硬件的示意图?

我用的是内置的ADC,所以这个没有....
回复

使用道具 举报

20

主题

102

回帖

162

积分

初级会员

积分
162
QQ
 楼主| 发表于 2025-7-10 09:45:41 | 显示全部楼层
eric2013 发表于 2025-7-8 09:09
1.9M采集256个点,基本上,远小于1ms就采集完毕了,所以对应不上是正常的。

那我在1ms以内采集+发送应该没啥问题吧,串口好像不太行
回复

使用道具 举报

39

主题

1516

回帖

1638

积分

至尊会员

积分
1638
发表于 2025-7-10 13:30:59 | 显示全部楼层
mygod 发表于 2025-7-7 13:36
用裸机吧,分分钟秒杀,

跟使用裸机还是操作系统无任何关系
回复

使用道具 举报

6

主题

60

回帖

78

积分

初级会员

积分
78
发表于 2025-7-11 00:02:49 | 显示全部楼层
不吃鱼的猫大人 发表于 2025-7-10 09:41
我用的是内置的ADC,所以这个没有....

我的意思是,ADC通道怎么和喷孔的对应信号连接的。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2025-7-11 09:10:02 | 显示全部楼层
不吃鱼的猫大人 发表于 2025-7-10 09:45
那我在1ms以内采集+发送应该没啥问题吧,串口好像不太行

可以触发一次采集一轮,使用NORMAL模式比较方便
回复

使用道具 举报

20

主题

102

回帖

162

积分

初级会员

积分
162
QQ
 楼主| 发表于 2025-7-15 20:54:06 | 显示全部楼层
红烧鱼头 发表于 2025-7-11 00:02
我的意思是,ADC通道怎么和喷孔的对应信号连接的。

明白了,就是单通道ADC3的一个通道接的差分放大芯片的输出端,这个没啥问题
回复

使用道具 举报

20

主题

102

回帖

162

积分

初级会员

积分
162
QQ
 楼主| 发表于 2025-7-15 20:56:56 | 显示全部楼层
eric2013 发表于 2025-7-11 09:10
可以触发一次采集一轮,使用NORMAL模式比较方便

One_Shot就是这个意思吧,就是触发一次采集一轮,然后全部采集完再做别的,就是目前这个问题解决了,是啥呢,是上位机的那个信号给的有问题。
现在我想边采集边发送应该没问题吧,1.9M的ADC然后再2倍过采样之后采集128个点,然后采集完任务通知W5500去以太网发送
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2025-7-16 09:49:46 | 显示全部楼层
不吃鱼的猫大人 发表于 2025-7-15 20:56
One_Shot就是这个意思吧,就是触发一次采集一轮,然后全部采集完再做别的,就是目前这个问题解决了,是啥 ...

可以试试,就是不知道W5500速度能跟上不,简单换算下,看看速度多少。
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-8-12 00:44 , Processed in 0.052350 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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