2018-10-02 03:06 AM
Hai,
i have been into designing a solar inverter using STMF051R4 series IC for past few years. Presently we are working
on ADC Measurement with DC voltage.The problem we are facing now is we not able to get a linearity in measurement of the dc voltage at the adc pins of the STM32 ic.We are getting different ratio for the different voltage ranges when we linearly increase the voltage with a constant difference .Can you please suggest me what kind of problem am i facing with the measurement of the voltages.Specifically can someone help me with the error i am facing right now.
I have also tried using low pass filter but couldnt find much difference in reading the values at the adc pins of the ic.
2018-10-02 10:44 PM
> This sounds like your DMA configuration, i.e. number of elements, is not right.
> DMA is a "dumb" unit that transfers the configured number of elements of configured size.
Can you Please throw some light on these statements...can you please make it more clear
2018-10-02 10:48 PM
Check out my code shown below:
This is the way i am reading the converted adc values 'max' variable
int main()
{
Start_HSE();
PORTA_CLK_EN;
PORTB_CLK_EN;
PORTC_CLK_EN;
adc_configuration();
DMA_config();
while(1)
{
max = ADC_array[0];
}
}
void DMA_config()
{
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
DMA1_Channel1->CPAR = (uint32_t) (&(ADC1->DR));
DMA1_Channel1->CMAR = (uint32_t)(ADC_array);
DMA1_Channel1->CNDTR = 1;
DMA1_Channel1->CCR |= DMA_CCR_MINC | DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_0 | DMA_CCR_TEIE | DMA_CCR_CIRC | DMA_CCR_PL_0;
DMA1_Channel1->CCR |= DMA_CCR_EN;
}
void adc_configuration()
{
GPIOC->MODER |= BIT(9) | BIT(8); // Analog mode
GPIOA->MODER |= BIT(7)| BIT(6);
ADC1->CR &= ~ADC_CR_ADEN;
RCC->APB2ENR |= RCC_APB2ENR_ADCEN; //Select a clock source for the ADC
ADC1->CFGR2 |= ADC_CFGR2_CKMODE_0;
ADC1->SMPR |= 0X00000007;
ADC1->CFGR1 |= ADC_CFGR1_CONT | ADC_CFGR1_DMACFG | ADC_CFGR1_DMAEN | ADC_CFGR1_RES_0| ADC_CFGR1_SCANDIR;
ADC1->CFGR1 &= ~(ADC_CFGR1_ALIGN | ADC_CFGR1_SCANDIR); // Right alignment, Upward scan
ADC1->SMPR &= ~ADC_SMPR_SMP; // 1.5 ADC clock cycles
ADC1->CHSELR |= ADC_CHSELR_CHSEL4 ; // Input Channel-0 is selected for conversion
//ADC Enable
ADC1->CR |= ADC_CR_ADEN;
while(!(ADC1->ISR & ADC_ISR_ADRDY));
ADC1->CR |= ADC_CR_ADSTART;
}
2018-10-02 10:49 PM
You could configure a timer interrupt to do a single channel conversion, without DMA
what rate do you need the data ?
2018-10-02 10:55 PM
Actually i am using my timers for SPWM generation and need DMA for managing my adc measurement.
2018-10-02 11:00 PM
did you do the calibration ?
which reading is correct ?
Suggest that you check your Vdda reading and do the calculations to prove its correct.
2018-10-02 11:23 PM
> Can you Please throw some light on these statements...can you please make it more clear
In your case, you will need to transfer 4 half-words (16 bit) for 4 channels. The DMA unit doesn't mind if you configure anything else, only the data would be a mess.
In other words, you must take care yourself that DMA source (ADC channels), transfer size and target area (memory buffer size and alignment) match, else you get runtime issues.
Use the DMA TC interrupt to pick up the array of ADC values, and move them out for processing. Else they are overwritten in the next conversion cycle.
I would suggest to first get the ADC setup right by its own. Just present a reasonable voltage (0V ... 3.0V) directly to the inputs, and check that the value and the memory location is correct.
Only then start to include your divider network / opamp circuitry.
2018-10-03 12:37 AM
The shown below is the ISR for DMA
void DMA1_Channel1_IRQHandler(void)
{
min = ADC_array[0];
DMA1->IFCR = DMA_IFCR_CTCIF1 ;
}
The probkem is that, when i use this ISR to read the value , the program loops within this ISR.And no other statements written after this , are not being executed.
2018-10-03 08:31 PM
I know you are looking in the reference manual,
on this line,
DMA1->IFCR = DMA_IFCR_CTCIF1
can you check the other interrupt flags and clear them too ?
2018-10-03 08:32 PM