Кто любит RISC в жизни, заходим, не стесняемся.
wss60
Потрогал лапой паяльник
Сообщения: 350 Зарегистрирован: Пт сен 10, 2010 20:48:01
Откуда: Минск
Сообщение
wss60 » Вс мар 22, 2020 08:24:39
Здравствуйте!
Кто нибудь запускал ADC на STM32F303 на максимальной скорости - Dual interleaved mode?
АЦП не хочет работать на максимальной частоте 72MHz, если уменьшить частоту(HCLK/2) в два раза то все работает.
Делал, как написано
здесь
Спойлер Код: Выделить всё
void adc12Init (void){
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
GPIOA->MODER |= GPIO_MODER_MODER0; //CH_B - Analog mode
GPIOA->MODER |= GPIO_MODER_MODER1; //CH_A - Analog mode
GPIOA->MODER |= GPIO_MODER_MODER6; //CH_B - Analog mode
RCC->AHBENR |= RCC_AHBENR_ADC12EN; //ADC Clock Enable
RCC->CFGR2 |= RCC_CFGR2_ADCPRE12_NO; //ADC12 - AHB clock
ADC1_2->CCR |= (0x2<<16); //00:(Asynchronous clock mode), 01: HCLK/1, 10: HCLK/2, 11: HCLK/4
ADC1_2->CCR |= (4<<8); //Delay
ADC1_2->CCR |= (7<<0); //Interleaved mode only
//ADC voltage regulator enable
ADC1->CR &=~ADC_CR_ADVREGEN;
ADC2->CR &=~ADC_CR_ADVREGEN;
//Calibration adc1_2
ADC1->CR |= ADC_CR_ADCAL;
while (ADC1->CR & ADC_CR_ADCAL);
ADC2->CR |= ADC_CR_ADCAL;
//adc1,2 enable
ADC1->CR |= ADC_CR_ADEN;
ADC2->CR |= ADC_CR_ADEN;
while ((ADC1->ISR & ADC_ISR_ADRD) == 0);
while ((ADC2->ISR & ADC_ISR_ADRD) == 0);
ADC1->CFGR |= ADC_CFGR_RES_1; //ADC1 - 8bit
ADC2->CFGR |= ADC_CFGR_RES_1; //ADC2 - 8bit
ADC1->SQR1 |= ADC_SQR1_SQ1_0; //ADC1_IN1
ADC2->SQR1 |= ADC_SQR1_SQ1_1 | ADC_SQR1_SQ1_0; //ADC2_IN3
// Set sampling time for regular group 1
ADC1->SMPR1 &=~ADC_SMPR1_SMP1; //1.5 ADC clock cycles
ADC2->SMPR1 &=~ADC_SMPR1_SMP1; //1.5 ADC clock cycles
ADC1->CFGR |= ADC_CFGR_CONT; //0: Single conversion mode, 1: Continuous conversion mode
ADC1->CFGR |= ADC_CFGR_OVRMOD;
ADC1->CR |= ADC_CR_ADSTART;
}
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089 Зарегистрирован: Вс июн 19, 2016 09:32:03
Сообщение
Reflector » Вс мар 22, 2020 11:43:26
[uquote="wss60",url="/forum/viewtopic.php?p=3816456#p3816456"]Делал, как написано
здесь [/uquote]
Ну давай сравним. Это написано в AN4195:
1.Ensure that ADVREGEN[1:0]=01, and that the ADC voltage regulator startup time has elapsed.
Дополнительно в RM:
ADVREG enable sequence
1. Change ADVREGEN[1:0] bits from ‘10’ (disabled state, reset state) into ‘00’.
2. Change ADVREGEN[1:0] bits from ‘00’ into ‘01’ (enabled state)
Это у тебя в коде:
Код: Выделить всё
//ADC voltage regulator enable
ADC1->CR &=~ADC_CR_ADVREGEN;
ADC2->CR &=~ADC_CR_ADVREGEN;
wss60
Потрогал лапой паяльник
Сообщения: 350 Зарегистрирован: Пт сен 10, 2010 20:48:01
Откуда: Минск
Сообщение
wss60 » Вс мар 22, 2020 20:39:17
Reflector, Спасибо!!!!
Из-за невнимательности больше двух часов мучился…
Получилось так (может кому пригодится):
Спойлер Код: Выделить всё
#define ADC_BUFF_SIZE 100
unsigned short adcDataBuff[ADC_BUFF_SIZE];
//DMA
void DMA1_Channel1_IRQHandler (void){
DMA1->IFCR |= DMA_IFCR_CGIF1;
//..............
ADC1->CR |= ADC_CR_ADSTART; //start adc
}
void dma1Init (void){
RCC->AHBENR |= RCC_AHBENR_DMA1EN; //DMA Clock enable
DMA1_Channel1->CCR |= DMA_CCR_MINC; //Memory increment mode
DMA1_Channel1->CCR &=~DMA_CCR_DIR; //Read from peripheral
DMA1_Channel1->CCR |= DMA_CCR_PL; //Channel priority level - Very high
DMA1_Channel1->CCR |= DMA_CCR_MINC; //Memory increment mode enabled
DMA1_Channel1->CCR |= DMA_CCR_PSIZE_1; //32bit
DMA1_Channel1->CCR |= DMA_CCR_MSIZE_1; //32bit
DMA1_Channel1->CNDTR = (uint32_t)ADC_BUFF_SIZE; //Number of data to transfer
DMA1_Channel1->CPAR = (uint32_t)&ADC1_2->CDR; //Peripheral address register
DMA1_Channel1->CMAR = (uint32_t)&adcDataBuff; //Memory address register
DMA1_Channel1->CCR |= DMA_CCR_TCIE; //
DMA1_Channel1->CCR |= DMA_CCR_CIRC; //
DMA1->IFCR |= 0x0F; //Reset flags
NVIC_SetPriority(DMA1_Channel1_IRQn, 1);
NVIC_EnableIRQ (DMA1_Channel1_IRQn);
DMA1_Channel1->CCR |= DMA_CCR_EN;
}
//ADC
void adc12Init (void){
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
GPIOA->MODER |= GPIO_MODER_MODER1; //Analog mode
GPIOA->MODER |= GPIO_MODER_MODER6; //Analog mode
RCC->AHBENR |= RCC_AHBENR_ADC12EN; //ADC Clock Enable
RCC->CFGR2 |= RCC_CFGR2_ADCPRE12_NO; //ADC12 <- AHB clock
ADC1_2->CCR |= (0x1<<16); //00:(Asynchronous clock mode - PLL), 01: HCLK/1, 10: HCLK/2, 11: HCLK/4
ADC1_2->CCR |= (4<<8); //Delay
ADC1_2->CCR |= (7<<0); //Interleaved mode only
//ADC voltage regulator reset
ADC1->CR &=~ADC_CR_ADVREGEN;
ADC2->CR &=~ADC_CR_ADVREGEN; delay_us(100);
//ADC voltage regulator enable
ADC1->CR |= ADC_CR_ADVREGEN_0;
ADC2->CR |= ADC_CR_ADVREGEN_0;
//Calibration adc1_2
ADC1->CR |= ADC_CR_ADCAL;
while(ADC1->CR & ADC_CR_ADCAL);
ADC2->CR |= ADC_CR_ADCAL;
while(ADC2->CR & ADC_CR_ADCAL);
//adc1_2 enable
ADC1->CR |= ADC_CR_ADEN;
while (!(ADC1->ISR & ADC_ISR_ADRD));
ADC2->CR |= ADC_CR_ADEN;
while (!(ADC2->ISR & ADC_ISR_ADRD));
ADC1->CFGR |= (2<<3); //DataResolution: 0 12-bit, 1 10-bit, 2 8-bit, 3 6-bit
ADC2->CFGR |= (2<<3); //DataResolution: 0 12-bit, 1 10-bit, 2 8-bit, 3 6-bit
ADC1->SQR1 |= ADC_SQR1_SQ1_0; //ADC1_IN1
ADC2->SQR1 |= ADC_SQR1_SQ1_1 | ADC_SQR1_SQ1_0; //ADC2_IN3
//Set sampling time for regular group 1
ADC1->SMPR1 |= (0<<3); //1.5 ADC clock cycles
ADC2->SMPR1 |= (0<<9); //1.5 ADC clock cycles
//ADC1->CFGR |= ADC_CFGR_CONT; //0: Single conversion mode, 1: Continuous conversion mode
//ADC2->CFGR |= ADC_CFGR_CONT; //0: Single conversion mode, 1: Continuous conversion mode
ADC1->CFGR |= ADC_CFGR_OVRMOD;
ADC2->CFGR |= ADC_CFGR_OVRMOD;
//DMA
ADC1_2->CCR |= (3<<14); //MDMA 2: 12 and 10-bit resolution, 3: 8 and 6-bit resolution
//External trigger
ADC1->CFGR |= (0x2<<10); //EXTEN
ADC1->CFGR |= (0x4<<6); //EXTSEL - TIM3
ADC1->CR |= ADC_CR_ADSTART;
}
//TIMER
void tim3Init (void){
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
TIM3->PSC = 4-1;
TIM3->ARR = 2-1;
TIM3->CR2 |= TIM_CR2_MMS_1; //output (TRGO)
TIM3->CR1 |= TIM_CR1_CEN;
}