sysTick частота манипуляций?
Мне нужно высокоточное прерывание для моего STM32F7. Задача - увеличить счетчик на каждом тике. Частота ЦП составляет до 216 МГц (из таблицы), что означает, что длительность такта около 5 нс может быть достигнута, верно?
После некоторых интернет-исследований я обнаружил, что для этой цели можно использовать sysTick. Я должен просто настроить SysTick следующим образом:
/** Configure the Systick interrupt time */
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
/**Configure the Systick */
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
Я переключаю вывод GPIO внутри функции SysTick_Handler, чтобы проверить частоту выполнения, и она составляет 1 мс.
Я хочу, чтобы длительность тика составляла 1 микросекунду, поэтому я заменил 1000 (в коде) на 100, затем я попробовал другие числа, но, похоже, ничто не влияет на длительность 1 мс.
Я что-то здесь упускаю? Есть ли лучшее решение, чем sysTick, для достижения этой цели?
Благодарю.
1 ответ
Вы не можете (и не должны!) Увеличивать некоторую переменную каждый такт. Вместо этого вы должны использовать аппаратный таймер (TIMx
) для такого точного измерения.
В общем, подходящих подходов мало:
Используйте планировщик. Установите аппаратный таймер для генерации прерывания при переполнении и настройте его на переполнение один раз в 20–20 мс в зависимости от необходимой детализации времени. В процедуре прерывания проверьте, если вы должны
do_something()
в текущем цикле планирования и сделать, если так. Чрезвычайно важно, чтобы подпрограмма прерывания была короткой и, конечно, конечной (без длительных программных циклов и т. Д.), Особенно когда период таймера короткий.Используйте одноразовые таймеры. Если вам нужно выполнить только одну подпрограмму или порядок строго определен, вы можете использовать следующий подход. В конце вашего
do_something()
, настройте и запустите аппаратный таймер, который запуститсяdo_something()
снова через необходимое количество времени. Так что в режиме прерывания вы просто запускаетеdo_something()
затем в началеdo_something()
Вы сбрасываете таймер, делаете свою работу и снова настраиваете таймер. Таким образом, вы можете контролировать задержку до одного такта. Однако это решение гораздо сложнее поддерживать и расширять.Объединить. Вы можете использовать планировщик, который запускает одноразовый таймер, чтобы точно контролировать время начала выполнения.
Планирование является сильно исследованной областью разработки программного обеспечения MCU. Об этом много статей, а также о зрелых операционных системах реального времени для микроконтроллеров, способных на это, и многое другое, например FreeRTOS или ChibiOS. Если это коммерческий проект, вы обычно должны использовать общие инструменты, такие как FreeRTOS, вместо того, чтобы писать свой собственный планировщик. Однако, конечно, это очень познавательно - и это весело!