新手上路
- 积分
- 27
- 金钱
- 27
- 注册时间
- 2022-7-8
- 在线时间
- 4 小时
|
1金钱
各位大佬们好,萌新请教一个问题:
工程功能:用cubeMX配置ADC,启用了DMA模式。不连续转换、ADC全局中断未开。ADC1通道1独立模式采样。ADC的触发方式用TIM3的TRGO信号。TIM3配置为溢出update event。目的是用定时器控制ADC的采样时间,比如目前我控制在1ms,dma采样1000次。然后用dma的一般完成回调和全部完成回调函数,给主函数一个信号,半完成就printf前面500次数据,全部完成就printf后面500次数据。由于printf时间比dma久,会关掉ADC。全部printf后,打开ADC周期循环上述功能。
问题异常:程序跑第一轮,数据正常。但是第二轮之后,随机某个位置,ADC的采样周期和实际对不上,采样的时间与定时器不符合。但是调试如果启动adc后启动延时就没这个问题。请问大佬们,如果不要延时如何处理?
- #define NUM_MAX 1024
- #define NUM_HALF NUM_MAX/2
- uint16_t AdcBuf[NUM_MAX];
- short puthalf=0;
- short putplt=0;
- short putcpl=0;
- void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
- {
- putcpl=1;
- // printf("半完成\r\n");
- puthalf=1;
- // putcpl=1;
- }
- void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
- {
- // printf("完成\r\n");
- putplt=1;
- // putcpl=0;
- // HAL_ADC_Stop(&hadc1);//此处stop经测试不能用hal_adc_stop_dma
- }
复制代码
int main(void)
{
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC1_Init();
MX_TIM3_Init();
int count = 1;
HAL_ADCEx_Calibration_Start(&hadc1);//校准adc引脚
// HAL_TIM_Base_Start(&htim3);//定时器
// HAL_ADC_Start_DMA(&hadc1, (uint32_t*)AdcBuf, NUM_MAX);
// if (puthalf==0 && putplt==0 ) {
//
// HAL_ADC_Start_DMA(&hadc1, (uint32_t*)AdcBuf, NUM_MAX);
// }
while (count++)
{
if (puthalf==0 && putplt==0 ) {
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC1_Init();
MX_TIM3_Init();
HAL_TIM_Base_Start(&htim3);//定时器
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)AdcBuf, NUM_MAX);
rt_thread_mdelay(1);
}
//if (putcpl==0 ) {
if (puthalf==1 )
{
rt_kprintf("\r\n");
rt_kprintf("BUFF-A:");
rt_kprintf("\r\n");
for(int g=0;g<NUM_HALF;++g)
{
rt_kprintf("%d ",AdcBuf[g]);
}
rt_kprintf("\r\n");
puthalf=0;
// rt_thread_mdelay(1);
}
if ( putplt==1)
{
// HAL_ADC_Stop_DMA(&hadc1);
HAL_ADC_Stop(&hadc1);
// HAL_TIM_Base_Stop(&htim3);
// HAL_TIM_Base_Stop(&htim3);
rt_kprintf("\r\n");
rt_kprintf("BUFF-B:");
rt_kprintf("\r\n");
for (int h = NUM_HALF; h < NUM_MAX; ++h)
{
rt_kprintf("%d ",AdcBuf[h]);
}
rt_kprintf("\r\n");
rt_memset(AdcBuf, 0, sizeof(AdcBuf));
// rt_thread_mdelay(1);
putcpl=0;
putplt=0;
}
// rt_thread_mdelay(10);
}
return RT_EOK;
}
|
|