Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32F4 ADC DMA ?
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
Страницы: 1, 2
сарматъ
помогите пожалуйста, пытаюсь запустить ацп вот таким кодом

RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; // Разрешить тактирование порта PORTA
//Конфигурирование PORTA.0 - аналоговый вход
GPIOA->MODER |= (GPIO_MODER_MODER0 << (0 * 2));; //Очистить биты MODE


//Конфигурирование PORTA.1 - аналоговый вход
GPIOA->MODER |= (GPIO_MODER_MODER0 << (1 * 2)); //Очистить биты MODE

RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; //подаем тактирование АЦП
//RCC->CFGR &= ~RCC_CFGR_ADCPRE; //входной делитель
ADC1->CR1 = 0; //
ADC1->CR2 = 0; //
ADC1->JSQR = 0; //
// ADC1->CR2 |= ADC_CR2_CAL; //запуск калибровки
// while (!(ADC1->CR2 & ADC_CR2_CAL)){ }; //ждем окончания калибровки

ADC1->CR2 = ADC_CR2_JEXTSEL; //выбрать источником запуска разряд JSWSTART
ADC1->CR2 |= ADC_CR2_JEXTEN; //разр. внешний запуск инжектированной группы
ADC1->CR2 |= ADC_CR2_CONT; //режим непрерывного преобразования
ADC1->CR1 |= ADC_CR1_SCAN; //режим сканирования (т.е. несколько каналов)
ADC1->CR1 |= ADC_CR1_JAUTO; //автомат. запуск инжектированной группы
ADC1->JSQR = ((2-1)<<20); //задаем количество каналов в инжектированной группе
ADC1->JSQR |= (0<<(5*3)); //номер канала для первого преобразования
ADC1->JSQR |= (1<<(5*2)); //номер канала для четвертого преобразования



ADC1->CR2 |= ADC_CR2_ADON; //включить АЦП
ADC1->CR2 |= ADC_CR2_JSWSTART; //запустить процес преобразования

закомментированные строки - то что осталось от f100

на f4 ацп не оживает, кто разбирается в чем подвох?
сарматъ
конкретно не работает непрерывное преобразование после каждого цикла приходится ставить
ADC1->CR2 |= ADC_CR2_JSWSTART;
while (!(ADC1->SR & ADC_SR_JEOC));

разобрался строка


ADC1->CR2 |= ADC_CR2_JEXTEN; //разр. внешний запуск инжектированной группы

лишняя
сарматъ
все равно надо каждый раз делать

ADC1->CR2 |= ADC_CR2_JSWSTART; //запустить процес преобразования
while (!(ADC1->SR & ADC_SR_JEOC));

подскажите в чем собака порылась?
Flexz
Перепишите на обычные (regular) каналы, injected не могут работать в непрерывном режиме сами по себе.
Цитата
Note: Injected channels cannot be converted continuously. The only exception is when an injected
channel is configured to be converted automatically after regular channels in continuous
mode (using JAUTO bit), refer to Auto-injection section).
сарматъ
упс... а в f100 работали...

спасибо
Haamu
Необходимо измерить сигнал с нескольких каналов последовательно, сохраняя данные в память через DMA. Измерять надо крайне быстро. Действую таким образом: выбираю канал, запускаю АЦП. Вот кусок кода:
Код
if(ModeStruct.Discreteness_hall) {
    if ((step_counter % ModeStruct.Discreteness_hall) == 0) {
        ADC1->SQR3 = ADC_Channel_0;
        ADC1->CR2 |= ADC_CR2_SWSTART;    //Start ADC
    }
}
if (ModeStruct.Discreteness_l) {
    if ((step_counter % ModeStruct.Discreteness_l) == 0) {
        ADC1->SQR3 = ADC_Channel_1;
        ADC1->CR2 |= ADC_CR2_SWSTART;    //Start ADC
    }
}
if (ModeStruct.Discreteness_diff) {
    if ((step_counter % ModeStruct.Discreteness_diff) == 0) {
        ADC1->SQR3 = ADC_Channel_2;
        ADC1->CR2 |= ADC_CR2_SWSTART;    //Start ADC
    }
}

Вот инициализация (тоже кусок):
Код
ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b;
ADC_InitStruct.ADC_ScanConvMode = DISABLE;
ADC_InitStruct.ADC_ContinuousConvMode = DISABLE;
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStruct.ADC_NbrOfConversion = 1;
ADC_Init(ADC1, &ADC_InitStruct);

Внимание, вопрос. Если я использую только один АЦП, нужна ли инициализация ADC_CommonInit(&ADC_CommonInitStruct)?
Какая частота тактирования у АЦП? В заблуждение ввел предделитель в вышеупомянутой ADC_CommonInitStruct. Если я работаю только с одним АЦП, его тактовая частота будет равна частоте шины APB2 без всяких предделителей?
Если чатстота APB2 = 84 МГц, а частота ядра 168Мгц, то в моем случае на оцифровку одного канала будет 15*(186/84) = 15*2 = 30 системных тиков. Верно? Если да, то поидее должен успеть оцифровать до запуска следующего канала. Но для подстраховки, перед запуском очередного преобразования, как лучше проверить (поять же, максимально быстро) завершилось ли предыдущее преобразование? Пробовал перед началом преобразования проверять флаг конца преобразования (EOC), но он похоже сбрасывается, когда DMA забирает данные в память.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.