реклама на сайте
подробности

 
 
4 страниц V  « < 2 3 4  
Reply to this topicStart new topic
> STM32F4 ADC DMA ?
ViKo
сообщение Jul 26 2012, 10:41
Сообщение #46


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(kan35 @ Jul 26 2012, 11:58) *
Действитеьлно, флаг ловить лучше в прерывании.

100%? А потом что с ним делать?
Go to the top of the page
 
+Quote Post
kan35
сообщение Jul 26 2012, 12:00
Сообщение #47


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



В основной программе ждать семафора, в прерывании взводить семафор. А во время ожидания другие задачи получают процессорное время.
Я, кстати, еще ни одного проекта на кортексах не сделал без RTOS, если не считать бутлодеры к ним. В случае без ОСи следует искусственно отдавать вычислительные ресурсы другим задачам - машинами состояний как то.

Как вариант -можно уводить CPU в Wait for event. Полюбому DMA работает быстрее процессора.

Сообщение отредактировал kan35 - Jul 26 2012, 12:04
Go to the top of the page
 
+Quote Post
Allregia
сообщение Jul 26 2012, 20:29
Сообщение #48


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 28-06-07
Из: Israel
Пользователь №: 28 763



Вопрос немного в сторону, про М4 и настройки Кейла.
Вот окно настроек:
Прикрепленное изображение


У меня как-то раньше на LPC17xx небыло нужды туда лазить, оставлял все по дефолту.
Но тут во первых наконец хочеться разобраться что к чему, во вторых есть вопрос по F4.
Слепа ПЗУ, справа ОЗУ. И там есть ROM*/IROM* и RAM*/IRAM*.
Насколько я понял. ROM* и RAM* это если цепляются внешние на FSCM, а пурвая буква "i" означает "internal", т.е то что внутри проца.
Разбивать IROM на 2 части может понадобится для собственного бутлоадера а таже для использования части флеша как ЕЕПРОМ.
Радиобаттоны возле ROM* определяют откуда стартовать.
А вот что делает чексбокс default?

Далее - с RAM. Тут тоже можно разбить на 2 области, но для к примеру LPC17хх или для F1 не обчень понятнодля чего это надо.
И для чего нужны чекбоксы "No Init" рядом с ними?
В Кейле нет возможности сказать про какую-то переменную, что ее не надо инициализировать при старте (аналог persistant в Hi-Tech)?

А главное - у F4 две области памяти, общая 128к плюс 64к только для CPU.
Keil по умолчанию ставить первую, а вторую не использует.
По идее, правильнее всего было бы размещать в первой только е переменные, которым нужно DMA, а те, к которым обращается только процессор - во второй.
Но как распределять иак переменые и как обьяснить это линкеру?

Go to the top of the page
 
+Quote Post
ViKo
сообщение Jul 31 2012, 09:35
Сообщение #49


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



На все ваши вопросы здесь уже были ответы. Поищите по нику aaarrr.
Go to the top of the page
 
+Quote Post
Allregia
сообщение Aug 2 2012, 14:03
Сообщение #50


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 28-06-07
Из: Israel
Пользователь №: 28 763



Цитата(ViKo @ Jul 31 2012, 11:35) *
На все ваши вопросы здесь уже были ответы. Поищите по нику aaarrr.

Просто так не ищется, может быть Вы подскажите строку для поиска?
Go to the top of the page
 
+Quote Post
сарматъ
сообщение Nov 19 2012, 05:34
Сообщение #51


Частый гость
**

Группа: Участник
Сообщений: 153
Регистрация: 19-11-12
Пользователь №: 74 463



помогите пожалуйста, пытаюсь запустить ацп вот таким кодом

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 ацп не оживает, кто разбирается в чем подвох?
Go to the top of the page
 
+Quote Post
сарматъ
сообщение Nov 19 2012, 09:03
Сообщение #52


Частый гость
**

Группа: Участник
Сообщений: 153
Регистрация: 19-11-12
Пользователь №: 74 463



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

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


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

лишняя
Go to the top of the page
 
+Quote Post
сарматъ
сообщение Nov 19 2012, 12:40
Сообщение #53


Частый гость
**

Группа: Участник
Сообщений: 153
Регистрация: 19-11-12
Пользователь №: 74 463



все равно надо каждый раз делать

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

подскажите в чем собака порылась?
Go to the top of the page
 
+Quote Post
Flexz
сообщение Nov 19 2012, 15:28
Сообщение #54


Местный
***

Группа: Свой
Сообщений: 252
Регистрация: 9-10-08
Из: Московская обл.
Пользователь №: 40 797



Перепишите на обычные (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).
Go to the top of the page
 
+Quote Post
сарматъ
сообщение Nov 19 2012, 15:37
Сообщение #55


Частый гость
**

Группа: Участник
Сообщений: 153
Регистрация: 19-11-12
Пользователь №: 74 463



упс... а в f100 работали...

спасибо
Go to the top of the page
 
+Quote Post
Haamu
сообщение Jan 9 2014, 08:17
Сообщение #56


Частый гость
**

Группа: Участник
Сообщений: 90
Регистрация: 12-12-13
Пользователь №: 79 587



Необходимо измерить сигнал с нескольких каналов последовательно, сохраняя данные в память через 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 забирает данные в память.

Сообщение отредактировал Haamu - Jan 9 2014, 08:28
Go to the top of the page
 
+Quote Post

4 страниц V  « < 2 3 4
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 26th August 2025 - 02:37
Рейтинг@Mail.ru


Страница сгенерированна за 0.01453 секунд с 7
ELECTRONIX ©2004-2016