Question
Problem with ADC
Posted on March 18, 2015 at 13:42
I am currently stuck with a strange phenomenon, and I am not sure anymore if what I do is how I should do it...
In my appliaction with the ST FOC library 4.0, I need to do some additional A/D conversions. This needs to be done as fast as possible. First I tried to use MC_RequestRegularConv/MC_GetRegularConv. This seemed to work, but was too slow as the conversions take place in TSK_SafetyTask at a 2kHz rate only. I figured that the code there is using PWMC_ExecRegularConv to actually do the conversion. So I wrote the following function: uint16_t doADC( uint8_t u8Channel ) { ADConv_t ADConv_struct; ADConv_struct.Channel = u8Channel; ADConv_struct.SamplTime = ADC_SampleTime_56Cycles; PWMC_ADC_SetSamplingTime( oCurrSensor[M1], ADConv_struct ); return PWMC_ExecRegularConv( oCurrSensor[M1], u8Channel ); } I call this function from within main() in a loop for several different channels: #define ADC_I_BAT ADC_Channel_8 // PB0 #define ADC_T_MOTOR ADC_Channel_9 // PB1 #define ADC_AIN_1 ADC_Channel_10 // PC0 #define ADC_AIN_2 ADC_Channel_11 // PC1 #define ADC_AIN_3 ADC_Channel_12 // PC2 #define ADC_T_BOARD ADC_Channel_13 // PC3 #define ADC_V_BAT ADC_Channel_15 // PC5 while (1) { u16Throttle = doADC( ADC_AIN_1 ); u16Brake = doADC( ADC_AIN_2 ); u16Temp = doADC( ADC_T_BOARD ); fBoardTemp = calcNTC( u16Temp ); u16Temp = 65535 - doADC( ADC_T_MOTOR ); fMotorTemp = calcNTC( u16Temp ); fBattCurrent= ((float)doADC( ADC_I_BAT ) - 32768.0) / 65536.0 * 3.3 / 55e-3; fBattVoltage= (float)doADC( ADC_V_BAT ) / 65536.0 * 3.3 / 0.0279; ... } There are no calls from other locations, and I do not use the MC_RequestRegularConv/MC_GetRegularConv mechanism anymore. Basically this works fine, but there are some irregularities. On one of the channels I sometimes (maybe once out of 100 times) get a wrong result. Instead of the real value (a few 100 counts) I get something in the range of 42000. Unfortunately this is the throttle input, meaning my motor receives an audible current ''kick'' from this. I checked carefully, the signal is not present on the analog input. I know that the phase current measurement is performed simultaneously, and basically asynchronously to the above code, using regular / injected conversion ''preempting''. Furthermore, I have read ST's errata sheet for the used STM32F405RGT6, which explains something exactly in this direction, but I do not understand what is exactly meant and if this applies to my problem. So my question: is my implementation correct, is this the intended use of these FOC library calls, is maybe that device errata causing trouble here? I also wonder why only that first channel is affected. Regards Frank