STM32 ADC DMA 多通道传输时通道顺序错误问题

问题终于解决了,折磨了好几天。

具体问题是什么呢,假设我有一个电压矢量U3(abc三相的导通情况为011,也就是a的下桥、bc的上桥导通),我将其导通3ms,我在3ms之中,要采样电流,那么理论上我要采样的是a相(因为电流采样电阻都连在下桥,只有下桥导通,才能测得电流。)但是呢,我发现无论怎么测试,U3导通的时候,总是在b相测到了电流,a相死活没有。

玄学阿?我测试了U5(abc为101),理论上应该是b相可以采的到电流,但实际上在a相采到了。

因为之前发现了以前写定时器的互补PWM波时,使用PWM2模式是错的,改成了PWM1后,发现了这个问题。
又以为是PWM1的问题,但是画了半天图,确认了PWM1是对的,以前写PWM2确实错了。(虽然PWM2也能跑,但与本意相违)。

终于在昨天有了重大进展,发现无论怎么样,只有ab相相反,与C相无关。这就排除了PWM1的问题。

然后又以为是电机ABC三相上,代码上定时器的通道与原理图不一样,比如A相和B相的CCR弄反了,或者以为是把ADC的通道和原理图上AB相电流通道弄反了,看了好久好久的原理图
和PCB,也没发现有啥问题。

后来开始怀疑是ADC采样的问题,但配置上也没啥问题阿。ADC2、两通道、DMA、TIM8的TRGO触发。

试着将两通道改成一通道,比如在U3导通的时候,只采样A相电流。奇迹发生了,居然采到!!又试着在U5导通的时候,采样B相电流,同样也采到了!!!

一共测试了不少个情况(只采样一个通道)

电压矢量 采样相 是否有电流 理论电流采样相
U3 A A
U3 B A
U5 A B
U5 B B

也就是说,如果只采样一个通道,那么就完全没问题,和理论是一致的。但一旦采样两相,则AB两相的电流情况就反过来了。

于是开始把重心放在是什么导致ADC DMA顺序错乱的问题上。百度了许多,确实也有人出现这个顺序错乱的问题,但主要集中在:

  • 使用标准库
  • ADC、DMA初始化顺序不对(正确顺序应该是先初始化DMA、再初始化ADC)
  • DMA开了之后,又进行ADC校准(这个ADC校准也会触发一次DMA请求,结果导致DMA的结果会往后退一项,导致顺序错误)

上述几种情况都是使用标准库才会有的,因为HAL库中,ADC与DMA是一起初始化的,且HAL库中已经没有ADC校准的函数了。

那又是为什么呢?上google搜了外网的信息,有关adc dma顺序的问题也是有,不过是关于在CubeMX的某个版本生成的代码中,把DMA初始化放在ADC初始化之后了,从而导致DMA不能用。和我的问题也不一样。

惆怅。其实在程序里手动把两个电流换一下顺序也能用,但心里就是不舒服,总感觉是一个隐患。

万念俱灰的时候,修改了一下两句代码的顺序,原来我写的顺序是:

    FOC一堆初始化
    HAL_TIM_Base_Start(&htim8);
    HAL_ADC_Start_DMA(&hadc2,(uint32_t *)ADC_Values_Raw2,2);

之前我已经调换过这两句话的顺序了,问题依旧。但这次,我将ADC_DMA开启函数拉到其他地方,ADC初始化完之后,马上就开启DMA。奇迹出现了,好了!顺序也不乱了。

我的天哪。服了。所以就是ADC的触发源(TIM8)与ADC DMA的顺序太靠近了,可能TIM8开始计时的时候触发了一次ADC?(但实际上,即使触发了一次ADC,也应该触发两次转换阿,怎么会使顺序错乱呢?小声bb)

发表评论