问题终于解决了,折磨了好几天。
具体问题是什么呢,假设我有一个电压矢量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)