cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with STM8S103 ADC

tangsg
Associate
Posted on June 27, 2012 at 05:08

I am using STM8S103 to measure three channels of voltage signals named vs12, vs5 and vs3 respectively. Timer 4 is enabled to generate interrupt every 10ms and three voltage signals are measured alternately. That is, in the 1st 10ms interrupt, vs12 is measured. In the 2nd 10ms interrupt, vs5 is measured. In the 3rd 10ms interrupt, vs3 is measured, and so on. During each measurement, mcu makes 16 captures for further average processing. The measurement result will be displayed in HyperTerminal via UART.

The problem is that when only 1 channel (vs12, vs5, or vs3) is enabled, the measurement is correct. But when two channels are enabled, both channels' measurements are wrong. Could anyone have a look at the following code and give me some suggestions?

The C code is described as follows.

main()

{

      ADC1->CR1 |= (ADC1_CR1_SPSEL & (0x02<<4)); //fADC = 4 MHz

      ADC1->CR2 |= ADC1_CR2_ALIGN; //right aligment

     

     while(1){

           // select the ADC channel

           if (vs_sel==0){

ADC1->CSR |= (ADC1_CSR_CH & CH_VS12);

} else if (vs_sel==1){

ADC1->CSR |= (ADC1_CSR_CH & CH_VS5);

}

    }

}

Timer 4 Interrupt:

@far @interrupt void irq_system_tim4_ovf (void)

{

 // If MAX NO OF SAMPLES are taken then voltage

// values will not be recorded in array vs12_arr

no_of_sample_vals = 0;

while( no_of_sample_vals < MAX_NO_SAMPLE_VAL )

{                                            

//start ADC

ADC1->CR1 |= ADC1_CR1_ADON; //ADC powered up

ADC1->CR1 |= ADC1_CR1_ADON; //begin conversion

//check for the EOC

while (!(ADC1->CSR & ADC1_CSR_EOC)){}; 

//must read LSBs first

if (vs_sel==0){

vs12_arr[no_of_sample_vals] = ADC1->DRL;

vs12_arr[no_of_sample_vals] |= ADC1->DRH << 8;

} else if (vs_sel==1){

vs5_arr[no_of_sample_vals] = ADC1->DRL;

vs5_arr[no_of_sample_vals] |= ADC1->DRH << 8;

}

//ADC powered down

ADC1->CR1 |= ~ADC1_CR1_ADON;

no_of_sample_vals++;

}

// Update the time counter

flag_10ms = 1;

if (t_10ms==100){  /* 1 sec is completed */

 flag_1sec = 1;

t_10ms = 0;

}

t_10ms++;

vs_sel++;

if (vs_sel==3) vs_sel = 0;

// Clear the flag

    TIM4->SR1 &=~(0x01);

    return;

}

2 REPLIES 2
tangsg
Associate
Posted on June 27, 2012 at 06:04

Solved. Can anyone find the root cause? hah

klaasdc
Associate II
Posted on June 27, 2012 at 21:59

So what was the problem then? 🙂