2023-03-23 11:48 PM
I have STM8LDiscovery (with STM8L152C6T6 CPU). I need to continuously read 2 ADC channels with writing the data to the memory.
I'm doing my project in IAR EW for STM8 v. 3.11.4.
I run into the problem: channels data (ADC_DATA) continuously exchanging their places, so ADC_IN0 can be writen to either ADC_DATA[0] or to ADC_DATA[1] and vice versa for ADC_IN1. Moreover: ADC overrun error (ADC1_SR.OVER) is apearing right after the start of the application and never go away.
Looks like ADC and DMA works not in the sync. As there is overrun error in the ADC status register I assume that DMA works slower than ADC producing the conversion data.
DMA writes exactly 2 words of memory. I already have tested it by increasing the ADC_DATA array size.
My ADC and DMA configuration looks like this:
unsigned int ADC_DATA[10];
// ADC1 clock enable
CLK_PCKENR2_bit.PCKEN20 = 1;
// DMA1 clock enable
CLK_PCKENR2_bit.PCKEN24 = 1;
// ADC1_IN0 (PA5): Input, No pull-up, Interrupt disable
PA_DDR_bit.DDR5 = 0;
PA_CR1_bit.C15 = 0;
PA_CR2_bit.C25 = 0;
// ADC1_IN1 (PA6): Input, No pull-up, Interrupt disable
PA_DDR_bit.DDR6 = 0;
PA_CR1_bit.C16 = 0;
PA_CR2_bit.C26 = 0;
// ADC1 conversion complete interrupt disabled
ADC1_CR1_bit.EOCIE = 0;
// ADC1 continuous conversion mode enabled
ADC1_CR1_bit.CONT = 1;
// ADC1 clock prescale 1:2
ADC1_CR2_bit.PRESC = 1;
// ADC1 sequence selection
// PA6, PA5
ADC1_SQR1 = 0x00;
ADC1_SQR2 = 0x00;
ADC1_SQR3 = 0x00;
ADC1_SQR4 = 0x03;
// DMA channel 0 in increment mode
DMA1_C0CR_bit.MINCDEC = 1;
// DMA channel 0 in circular mode
DMA1_C0CR_bit.CIRC = 1;
// DMA channel 0 in direction: peripheral to memory
DMA1_C0CR_bit.DIR = 0;
// DMA channel 0 interrupt disabled
DMA1_C0CR_bit.TCIE = 0;
// DMA channel 0 priority LOW
DMA1_C0SPR_bit.PL0= 0;
DMA1_C0SPR_bit.PL1= 0;
// DMA channel 0 16-bit mode
DMA1_C0SPR_bit.TSIZE= 1;
// DMA number af words to transfer
DMA1_C0NDTR = 2;
// DMA channel 0 peripipheral address
DMA1_C0PARH = 0x53;
DMA1_C0PARL = 0x44;
// DMA channel 0 memory address
DMA1_C0M0ARH = (unsigned char)(((unsigned int)(&ADC_DATA[0])) / 256);
DMA1_C0M0ARL = (unsigned char)(((unsigned int)(&ADC_DATA[0])) % 256);
// DMA enabled
DMA1_GCSR_bit.GEN = 1;
// DMA channel 0 enabled
DMA1_C0CR_bit.EN = 1;
// ADC1 ON
ADC1_CR1_bit.ADON = 1;
// ADC1 start conversion
ADC1_CR1_bit.START = 1;
What could be wrong with my code?
2023-03-26 10:11 AM
I have already tested to trigger ADC with timer. However - same thing happened
2023-03-30 10:40 PM
Friends, I still desperately need some help. STM8 appears to have very small community.
Any thought can be very helpful
2023-03-31 05:55 AM
Read RM0031 with attention.
Maybe there are other problems but power-on ADC should be first step and set DMA GEN bit should be last step.