Для таких целей я включаю режим continuous mode + auto-injection. Так можно сканировать до 5 каналов: 1 regular и 4 injected (там как раз 4 регистра ADC_JDRx).
Ну а если хочется через DMA, то вот пример кода:
CODE
#define AVERAGING 128
#define ADC_NCHANNELS 6
static uint16_t volatile buf[AVERAGING][ADC_NCHANNELS];
void
adc_init(void)
{
/* enable clocking of ADC1, PORT A */
RCC_APB2ENR |= 0x00000204;
/* configure PA0,1,2,3,4,6 as analog inputs */
GPIOA_CRL &= 0xF0F00000;
/* enable clocking of DMA1 */
REGBIT(RCC_AHBENR, 0) = 1;
ADC1_CR2 = 0; /* turn ADC off */
timer_delay(2); /* wait at least 2 ADC clock cycles before calibration */
ADC1_CR1 = (1 << 8); /* enable scan mode */
ADC1_CR2 = (1 << 23) /* enable Vrefint */
| (1 << 8) /* enable DMA mode */
| (1 << 1) /* enable continuous conversion mode */
| (1 << 0);/* switch ADC on */
ADC1_SMPR2 = 0x3FFFFFFF; /* sample time 239.5 cycles for ch. 0-9 */
/* conversion sequence: ch. 0, 1, 2, 3, 6, 17 */
ADC1_SQR3 = (0 << 0) | (1 << 5) | (2 << 10)
| (3 << 15) | (6 << 20) | (17 << 25);
ADC1_SQR1 = ((ADC_NCHANNELS - 1) << 20); /* sequence length */
REGBIT(ADC1_CR2, 2) = 1; /* start ADC calibration */
while (REGBIT(ADC1_CR2, 2) != 0)
{
/* wait for calibration to complete */
}
DMA1_CNDTR(1) = AVERAGING * ADC_NCHANNELS;
DMA1_CPAR(1) = (uint32_t)&ADC1_DR;
DMA1_CMAR(1) = (uint32_t)buf;
DMA1_CCR(1) = (1 << 10) /* memory size 16 bits */
| (1 << 8) /* peripheral size 16 bits */
| (1 << 7) /* memory increment mode */
| (1 << 5) /* circular mode */
| (1 << 1) /* transfer complete interrupt enable */
| (1 << 0);/* channel enable */
REGBIT(ADC1_CR2, 0) = 1; /* start ADC conversions */
}
Сообщение отредактировал IgorKossak - Mar 1 2012, 14:34
Причина редактирования: [codebox]!!!