Closed board707 closed 1 year ago
Привет! В процедуру инициализации таймера нужно добавить строку HAL_RCC_TIM_CLK_ENABLE(); Функцию attribute__((isr)) void TIM0_5_IRQHandler(void) {
HAL_TIM_IRQHandler(&htim1);
} Перенести в wm_it.c, и туда же добавить объявление extern TIM_HandleTypeDef htim1; Все работает
PS. Но так прерывания не обрабатываются. :) Принято в обработчике прерывания делать минимальные движения с кодом. Например там можно инкрементировать key_flag. А код из blink() имплементировать в loop() без HAL_Delay(500)
В стиле Ардуино это будет так
`#include
void Error_Handler_tim(void); static void TIM1_Init(void);
TIM_HandleTypeDef htim1; static volatile uint8_t key_flag = 0;
void setup() {
printf("Led Demo\r\n");
pinMode(LED0,OUTPUT);
pinMode(LED1,OUTPUT);
pinMode(LED2,OUTPUT);
TIM1_Init();
}
void loop() {
if (key_flag % 3 == 0)
{
digitalWrite(LED0,LOW);
digitalWrite(LED1,HIGH);
digitalWrite(LED2,HIGH);
}
else if (key_flag % 3 == 1)
{
digitalWrite(LED0,HIGH);
digitalWrite(LED1,LOW);
digitalWrite(LED2,HIGH);
}
else
{
digitalWrite(LED0,HIGH);
digitalWrite(LED1,HIGH);
digitalWrite(LED2,LOW);
}
}
static void TIM1_Init(void) { __HAL_RCC_TIM_CLK_ENABLE(); htim1.Instance = TIM1; htim1.Init.Unit = TIM_UNIT_MS; htim1.Init.Period = 1000; htim1.Init.AutoReload = TIM_AUTORELOAD_PRELOAD_ENABLE; if (HAL_TIM_Base_Init(&htim1) != HAL_OK) { printf("TIM init error\r\n"); Error_Handler_tim(); }
if (HAL_TIM_Base_Start_IT(&htim1) != HAL_OK)
{
printf("TIM start_it error\r\n");
Error_Handler_tim();
}
HAL_NVIC_SetPriority(TIM_IRQn, 0); HAL_NVIC_EnableIRQ(TIM_IRQn); }
void Error_Handler_tim(void) { while (1); }
void HAL_TIM_Callback(TIM_HandleTypeDef *htim) {
if (htim->Instance == TIM1)
{
key_flag++;
}
} ` Для AIR103 лампочки надо перестроить Проверял в новой сборке для HAL 0.6.0
Да, спасибо, работает. То что нужен запуск тактирования - это понятно. А вот почему нужно TIM0_5_IRQHandler(void) обязательно в wm_it.c перенести - не вполне понимаю.
так прерывания не обрабатываются. :) Принято в обработчике прерывания делать минимальные движения
это я в курсе :) но в данном случае, считаю, обработчик получился совсем небольшим, всего-то мы пишем три бита в регистр порта.
Кстати, в примере hal_led у вас есть небольшая ошибка. В качестве задержки стоит функция HAL_DELAY(500); Но это же в микросекундах, как я понял. Реально если запустить пример так как он написан - светодиоды горят все три вполнакала. Я заменил HAL_DELAY(500); на delay(500) и лампочки стали мигать как положено.
Да... там я проморгал. Пример был подготовлен раньше чем мы правки в Core сделали. HAL_Delay() - это микросекунды На счет wm_it.c сам тоже озадачился... С другой стороны в STM32 HAL тоже такой подход, Видимо китайцы один к одному слизали :)
Думаю, что по итогам этой ветки TIM0_5_IRQHandler(void) надо добавить в wm_it.c по дефолту. А __HAL_RCC_TIM_CLK_ENABLE() куда-нибудь в HAL_INIT() или Arduino.c. А вот инициализацию самого таймера пусть пользователи делают сами, я попробую для этого библиотеку написать, типа как HardwareTimer() для СТМ
Так можно... Но есть одно НО! Нужно понять сколько пользовательских таймеров и под какими номерами можно выделить ардуинщику. Бикоз, в будущем, будет стоять задача интегрировать RTOS. Я пока не знаю какие номера таймеров она может занять.
Думаю что нужно предусмотреть работу как в РТОС, так и без нее. Затачивать чип только под РТОС, как это сделано в ЕСП32 - мне бы очень не хотелось. А это значит, что при работе на "голом чипе" нужно отдать пользователю все имеющиеся таймеры, а под РТОС - ввести ограничения. То есть я за то, чтобы пока никаких таймеров под РТОС не резервировать.
Извиняюсь, а в Дискуссиях Вы мои сообщения видите? А то что-то совсем ничего не пишете :)
Тогда в Arduino.h нужно определить все доступные таймеры, а в wm_it.c добавить хендлеры для них.
в wm_it.c добавить хендлеры для них.
Таймеры создать надо, а вот хендлеров больше не нужно, если я не ошибаюсь. Прерывание то у нас одно единственное на все 6 таймеров. И хендлер один, он уже в wm_tim.c определен. Пользователю нужно будет сконфигурировать и запустить таймер и зарегистрировать кэлбек для него.
Не одно
Кстати, можно функции millis(),micros(),delay(),delayMicroseconds() сделать на TIM0 и вернуть тики процессора к миллисекундам. Будет как в настоящем Ардуино... Хотя особого смысла я в этом не вижу :)
хм, вы меня озадачили.... а сейчас они в чем? Вроде пользовался уже delay() - похоже на миллисекунды :)
Сейчас все работает так как задекларировано. В мс и мкс. За счет того что системные тики перестроены на микросекундные интервалы(были миллисекунды).
Это не существенная нагрузка на ядро. При тактовой в 240Мгц это всего лишь 1/240 производительности. Но можно все вернуть в зад и сделать на таймере
Попытался помигать диодом через таймер. Взял пример работы с таймером из SDK и ример HAL_LED Сконфигурировал таймер с периодом в 1 сек и в обработчик прерывания по переполнению положил код мигания светодиодами из HAL_LED. Код компилируется без ошибок, но не мигает. Вот код. Посмотрите, может что посоветуете.