Перейти к содержанию
    

Действитеьлно, флаг ловить лучше в прерывании.

100%? А потом что с ним делать?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В основной программе ждать семафора, в прерывании взводить семафор. А во время ожидания другие задачи получают процессорное время.

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

 

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

Изменено пользователем kan35

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Вот окно настроек:

post-28763-1343333487_thumb.png

 

У меня как-то раньше на 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, а те, к которым обращается только процессор - во второй.

Но как распределять иак переменые и как обьяснить это линкеру?

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На все ваши вопросы здесь уже были ответы. Поищите по нику aaarrr.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На все ваши вопросы здесь уже были ответы. Поищите по нику aaarrr.

Просто так не ищется, может быть Вы подскажите строку для поиска?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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));

 

подскажите в чем собака порылась?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Перепишите на обычные (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).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...