Easyelectronics.ru

Электроника для всех
Текущее время: 16 окт 2019, 08:03

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/10pcs (Любой цвет!)
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 14 ] 
Автор Сообщение
 Заголовок сообщения: Функция выполняется за разное время.
СообщениеДобавлено: 01 авг 2019, 18:45 
Заглядывает иногда
Аватара пользователя

Зарегистрирован: 28 фев 2012, 13:44
Сообщения: 102
Добрый день.
Возможно глупый вопрос, но все же.

Есть функция, которая снимает 256 показаний с АЦП.
Код:
void DataADC(void)
{
      uint16_t DataADCBuffer[270] = {0};

      PORT_ADC -> BSRR |= (uint32_t)PIN_ADC_OE << 16U;

      for(register uint16_t CounterDataADC = 0; CounterDataADC < 256; CounterDataADC++) 
      {
            DataADCBuffer[CounterDataADC] = PORT_ADC -> IDR;
            __ASM("NOP");
      }

       PORT_ADC -> BSRR |= PIN_ADC_OE;
}

Цикл FOR в данной функции выполняется периодически за разные промежутки времени. В моем случае это 250 и 260 мкС.
Соответственно из-за этого сигнал у меня иногда смещается в самом начале на 10 мкС. И именно задержка происходит в самом начале.

Если отключить полностью оптимизацию, то я постоянно получаю необходимые мне 250 мкС. При любых других настройках оптимизации, получаю периодическое смещение в эти 10 мкС.
Отключение оптимизации для меня не желательно, так как проект уже довольно большой и многое придется корректировать.

Возможно, кто то подскажет, как можно заставить этот участок выполняться за одно и тоже время!?
Для работы c STM32F4 использую TrueStudio.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Функция выполняется за разное время.
СообщениеДобавлено: 01 авг 2019, 19:15 
Старожил

Зарегистрирован: 11 сен 2012, 11:19
Сообщения: 5690
DMA ?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Функция выполняется за разное время.
СообщениеДобавлено: 01 авг 2019, 19:26 
Старожил

Зарегистрирован: 23 янв 2016, 15:37
Сообщения: 1015
Запускаешь DMA и сразу вызываешь __WFI(), тогда на F4 будет чтение стабильно за 4 такта, если нужно больше, то придется добавлять таймер.

Nosaer писал(а):
Код:
PORT_ADC -> BSRR |= (uint32_t)PIN_ADC_OE << 16U;

В BSRR можно только писать, читать и нельзя и не имеет никакого смысла.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Функция выполняется за разное время.
СообщениеДобавлено: 01 авг 2019, 20:49 
Заглядывает иногда
Аватара пользователя

Зарегистрирован: 28 фев 2012, 13:44
Сообщения: 102
Reflector писал(а):
BSRR можно только писать, читать и нельзя и не имеет никакого смысла.

Так я и не читаю.

__WFI() трогать не получится.

Про DMA не совсем понял, можно по подробнее!?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Функция выполняется за разное время.
СообщениеДобавлено: 01 авг 2019, 21:04 
Старожил

Зарегистрирован: 11 сен 2012, 11:19
Сообщения: 5690
Nosaer , вы не знаете как сие работает?
PORT_ADC -> BSRR |= PIN_ADC_OE;

Кстати а как вы синхронизируетесь с ADC?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Функция выполняется за разное время.
СообщениеДобавлено: 01 авг 2019, 21:26 
Старожил

Зарегистрирован: 23 янв 2016, 15:37
Сообщения: 1015
Nosaer писал(а):
__WFI() трогать не получится.
Про DMA не совсем понял, можно по подробнее!?

Если без __WFI и, соответственно, без прерываний, то у меня это выглядело бы примерно так:
Код:
Dma2Stream5<6> stream; // stream5, ch6 - TIM1_UP
stream.initPeriphToMem(&GPIOC->IDR, DmaSrc::_16b, buf, DmaDst::_16b_Inc, bufSize, DmaPrio::VeryHigh);

Timer1 tim;
tim.init(presc, arr);
tim.enableDmaRequests<TimDmaReq::Update>();
   
stream.enable();
tim.enable()
while(stream.isWorking()) {}

Идею это демонстрирует, на регистры перекладывай сам :) Без __WFI() будет некоторая неравномерность, но если скорость чтения не максимальна, то сдвига быть не должно. Таймер добавляет лишний такт, таким образом минимальное время между выборками - 5 тактов.


Последний раз редактировалось Reflector 01 авг 2019, 21:28, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Функция выполняется за разное время.
СообщениеДобавлено: 01 авг 2019, 21:26 
Старожил

Зарегистрирован: 10 июн 2011, 23:01
Сообщения: 3297
на какой частоте у вас МК работает, что чтение порта в память занимает целую микросекунду?

на 10 микросекунд имеено удлинняется сам цикл (длительность импульса на PIN_ADC_OE), или всё-таки целиком смещается относительно старта (Кстати а как вы синхронизируетесь с ADC?) при той же длительности?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Функция выполняется за разное время.
СообщениеДобавлено: 01 авг 2019, 22:07 
Старожил

Зарегистрирован: 08 авг 2013, 09:43
Сообщения: 2277
Nosaer писал(а):
Так я и не читаю.

Читаете. reg |= 123 раскрывается в reg = reg | 123. А чтобы правую часть вычислить, нужно сначала считать reg.


Последний раз редактировалось NStorm 01 авг 2019, 22:36, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Функция выполняется за разное время.
СообщениеДобавлено: 01 авг 2019, 22:15 
Заглядывает иногда
Аватара пользователя

Зарегистрирован: 28 фев 2012, 13:44
Сообщения: 102
dosikus_2 писал(а):
Nosaer , вы не знаете как сие работает?
PORT_ADC -> BSRR |= PIN_ADC_OE;

Теперь понял в чем ошибка)

dosikus_2 писал(а):
Кстати а как вы синхронизируетесь с ADC?

Один из Таймеров на ШИМ настроен, с него и тактирую.

_pv писал(а):
на какой частоте у вас МК работает, что чтение порта в память занимает целую микросекунду?
на 10 микросекунд имеено удлинняется сам цикл (длительность импульса на PIN_ADC_OE), или всё-таки целиком смещается относительно старта (Кстати а как вы синхронизируетесь с ADC?) при той же длительности?


Частота МК приличная, 21 Мгц.
Если собирать проект без оптимизации, то к моему удивлению, чтение порта занимает что то в районе 1 мкс. Это еще если значение "CounterDataADC", хранить в регистре, иначе и того больше. Если использовать оптимизацию, то намного быстрее, до 1 мкс я догонял с помощью нескольких __ASM("NOP");

На 10 микросекунд удлиняется импульс на PIN_ADC_OE. Я ориентируюсь именно на его длину.
Товарищи Reflector и dosikus_2 мне указали на мою оплошность в управлении этим пином. Завтра подправлю, возможно в этом в какой то степени еще и есть моя ошибка.

П.С. Опыта работы с ARM у меня не так много, поэтому возможно какие то моменты я упускаю.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Функция выполняется за разное время.
СообщениеДобавлено: 01 авг 2019, 22:17 
Старожил

Зарегистрирован: 11 сен 2012, 11:19
Сообщения: 5690
Nosaer писал(а):
Один из Таймеров на ШИМ настроен, с него и тактирую.


Ну вот же и источник реквеста готов...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Функция выполняется за разное время.
СообщениеДобавлено: 02 авг 2019, 10:05 
Старожил
Аватара пользователя

Зарегистрирован: 01 ноя 2011, 23:51
Сообщения: 821
Ну так еще в ваши 10мкс может попасть какое-то прерывание которое выполнится посередь вашей ф-ции..


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Функция выполняется за разное время.
СообщениеДобавлено: 02 авг 2019, 10:48 
Старожил
Аватара пользователя

Зарегистрирован: 22 июл 2017, 11:48
Сообщения: 3643
Упускаете то, что несколько NOP-ов могут пропускаться и не исполняться самим ядром, оно так решает само по себе.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Функция выполняется за разное время.
СообщениеДобавлено: 02 авг 2019, 10:55 
Старожил
Аватара пользователя

Зарегистрирован: 23 июл 2010, 09:54
Сообщения: 202
Откуда: Чебоксары
Nosaer писал(а):
Про DMA не совсем понял, можно по подробнее!?

Здесь всё описано - AN4666


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Функция выполняется за разное время.
СообщениеДобавлено: 02 авг 2019, 15:49 
Заглядывает иногда
Аватара пользователя

Зарегистрирован: 28 фев 2012, 13:44
Сообщения: 102
dosikus_2 писал(а):
Nosaer писал(а):
Один из Таймеров на ШИМ настроен, с него и тактирую.


Ну вот же и источник реквеста готов...

Я так понял связка DMA+TIM PWM? Пока слабо представляю как это все запустить вместе. Но постараюсь освоить. Спасибо

BusMaster писал(а):
Упускаете то, что несколько NOP-ов могут пропускаться и не исполняться самим ядром, оно так решает само по себе.

Это первое, на что я грешил, но после того как я их вырезал, картина абсолютно не изменилась.

kos писал(а):
Ну так еще в ваши 10мкс может попасть какое-то прерывание которое выполнится посередь вашей ф-ции..

Данная функция выполняется в прерывании с наивысшим приоритетом, поэтому на другие прерывания оно никак реагировать не должно.

Exeland писал(а):
Nosaer писал(а):
Про DMA не совсем понял, можно по подробнее!?

Здесь всё описано - AN4666

Спасибо, ознакомлюсь.


После исправления косяка со считывание регистра BSRR, пауза с 10 мкС сократилась до 6. Но это все еще критично для меня.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 14 ] 

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB