Дакли
Солнце 03 сентября 2017 22:47
HAL_SYSTICK_CALLBACK работает на NUCLEO-F103RB с использованием STM32CUBEMX/TRUESTUDIO, но не при использовании Arduino IDE с STM32Cores от ST-Microelectronics версии 2017.8.31. Прикрепленная эскиза Arduino Sketch не генерирует какое -либо сообщение об ошибке, но переменная OneScount никогда не уменьшается, как показано в серийном мониторе. Я предполагаю, что компилятор GCC в Arduino IDE не поддерживает атрибут __weak, связанный с подпрограммой HAL_SYSTICK_CALLBACK в STM32F1XX_HAL_CORTEX.c Файл.
Rogerclark
Солнце 03 сентября 2017 11:09
Обычно Systick используется Millis () и Delay () и т. Д. Arduino Core, но я не уверен, что это так с ядром STM.
Дакли
Пн сентября 04, 2017 1:28
Да, ядра Arduino использует один из его таймеров для Millis () и Delay (), в то время как в ядрах STM32 есть выделенный таймер Systick для получения 1 MSEC прерываний. Существует ряд процедур HAL, которые поддерживают использование этого таймера Systick для управления задачами планирования, и одним из них является функция hal_systick_callback (). Например, если вы в C: \ users \<имя пользователя>\ Appdata \ local \ arduino15 \ packages \ stm32 \ hareware \ stm32 \ 2017.8.31 \ System \ Drivers \ stm32f1xx_hal_driver \ src \ stm32f1xx_hal_cortex.c Файл, вы найдете код для серии процедур NVIC и Systick, включая
void hal_systick_irqhandler (void), который вызывает hal_systick_callback (). Подпрограмма hal_systick_callback () определяется следующим образом:
/**
* @brief Systick обратный вызов.
* @retval нет
*/
__weak void hal_systick_callback (void)
{
/* Примечание: эта функция не должна быть изменена, когда требуется обратный вызов,
HAL_SYSTICK_CALLBACK может быть реализован в пользовательском файле
*/
}
Для компилятора GCC атрибут «__weak» означает, что компиляция GCC заключается в использовании этого кода для определения по умолчанию этой подпрограммы, если только пользователь не дает свое собственное определение для этой рутины (i.эн. Без атрибута __weak), и в этом случае компилятор GCC должен использовать определение пользователя. Эта возможность широко используется для определения процедур прерывания держателя по умолчанию/месту для заполнения местоположения вектора прерывания микропроцессоров STM32.
То, что я и другие используют эту возможность микропроцессора STM32.
Таким образом, моя простая подпрограмма hal_systick_callback устанавливает один из них один раз в секунду, а мой основной процедурный цикл проверяет этот флаг, чтобы увидеть, пришло ли время что -то сделать, а затем очистит этот флаг.
В качестве примера: для правильного управления двигателем важно периодически измерять вращение вала двигателя и обновлять привод двигателя. Это лучше всего можно сделать, используя временное прерывание для чтения позиции вала двигателя, обновления значения привода двигателя и установив флаг, который планирует подпрограмму, которая использует положение вала для вычисления следующего значения привода двигателя.
Это именно то, что я хочу использовать hal_systick_callback для. То есть каждые 50 клещей (я.эн. 20 Гц) Прочитайте положение вала двигателя (с использованием возможностей квадратурного декодера STM32) и обновить значение ШИМ двигателя.
Извините за то, что был так долго завернут больше информации, чем я уверен, что вам интересно.
void hal_systick_irqhandler (void), который вызывает hal_systick_callback (). Подпрограмма hal_systick_callback () определяется следующим образом:
/**
* @brief Systick обратный вызов.
* @retval нет
*/
__weak void hal_systick_callback (void)
{
/* Примечание: эта функция не должна быть изменена, когда требуется обратный вызов,
HAL_SYSTICK_CALLBACK может быть реализован в пользовательском файле
*/
}
Для компилятора GCC атрибут «__weak» означает, что компиляция GCC заключается в использовании этого кода для определения по умолчанию этой подпрограммы, если только пользователь не дает свое собственное определение для этой рутины (i.эн. Без атрибута __weak), и в этом случае компилятор GCC должен использовать определение пользователя. Эта возможность широко используется для определения процедур прерывания держателя по умолчанию/месту для заполнения местоположения вектора прерывания микропроцессоров STM32.
То, что я и другие используют эту возможность микропроцессора STM32.
Таким образом, моя простая подпрограмма hal_systick_callback устанавливает один из них один раз в секунду, а мой основной процедурный цикл проверяет этот флаг, чтобы увидеть, пришло ли время что -то сделать, а затем очистит этот флаг.
В качестве примера: для правильного управления двигателем важно периодически измерять вращение вала двигателя и обновлять привод двигателя. Это лучше всего можно сделать, используя временное прерывание для чтения позиции вала двигателя, обновления значения привода двигателя и установив флаг, который планирует подпрограмму, которая использует положение вала для вычисления следующего значения привода двигателя.
Это именно то, что я хочу использовать hal_systick_callback для. То есть каждые 50 клещей (я.эн. 20 Гц) Прочитайте положение вала двигателя (с использованием возможностей квадратурного декодера STM32) и обновить значение ШИМ двигателя.
Извините за то, что был так долго завернут больше информации, чем я уверен, что вам интересно.
Рик Кимбалл
Пн, сентябрь 04, 2017 1:35 утра
В то время как ваш подход может работать с основным ядром HAL, это действительно не очень дружелюбно Arduino. Вы можете сделать то же самое, сделав вызов из вашей функции Loop () или добавив Serialevent функция обработчика.
volatile bool oneSecFlag = false;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
delay(100);
Serial.println("Hello World");
Serial.print("HAL Version = "); Serial.println(HAL_GetHalVersion());
}
void loop() {
process();
// put your main code here, to run repeatedly:
if (oneSecFlag) {
Serial.println("One Second Event");
Serial.print("millis() = "); Serial.println(millis());
oneSecFlag = false;
}
}
void process() {
static unsigned next_ms = 1000;
unsigned curr = millis();
if ( curr >= next_ms ) {
next_ms = (curr + 1000) - (curr % 1000);
oneSecFlag = true;
}
}
Rogerclark
Пн, сентябрь 04, 2017 2:50 утра
@dackley
Предполагая, что вы еще не используете все остальные таймеры аппаратного обеспечения, почему бы вам просто не использовать один из таймеров и настраивать его на прерывание каждые 50 мс
Предполагая, что вы еще не используете все остальные таймеры аппаратного обеспечения, почему бы вам просто не использовать один из таймеров и настраивать его на прерывание каждые 50 мс
Rogerclark
Пн сентября 04, 2017 2:57 утра
Рик
Разве Serialevent не является полным неправильным в Arduino API.
Он просто вызывается в основном после возврата loop ()
Я проверил ядро STM, и именно так они справляются с этим
https: // github.com/stm32duino/arduino_c ... в.CPP#L54
я.E Это была давняя проблема, когда люди (включая меня) предполагали, что Serialevent был асинхронным обработчиком вызовов для сериала, но это не так.
Разве Serialevent не является полным неправильным в Arduino API.
Он просто вызывается в основном после возврата loop ()
Я проверил ядро STM, и именно так они справляются с этим
https: // github.com/stm32duino/arduino_c ... в.CPP#L54
я.E Это была давняя проблема, когда люди (включая меня) предполагали, что Serialevent был асинхронным обработчиком вызовов для сериала, но это не так.
Даниэфф
Пн, сентябрь 04, 2017 7:52 утра
.Файлы INO составлены с CPP, поэтому имена искажены, попробуйте с C Scine:
extern "C" void HAL_SYSTICK_Callback(void) {...
fpistm
Пн сентября 04, 2017 9:31
На самом деле, hal_systick_callback не используется.
Используется systick_handler, он определяется в часах.C:
Используется systick_handler, он определяется в часах.C:
/**
* @brief Function called when t he tick interruption falls
* @param None
* @retval None
*/
void SysTick_Handler(void)
{
HAL_IncTick();
}
fpistm
Пн, сентябрь 04, 2017 12:29
Я проверил, как Hal_systick_callback () используется в проекте Cube:
Фактически:
Systick_handler () вызов Hal_systick_irqhandler() которые называют Hal_systick_callback()
Итак, как нам нужно определить Systick_handler Чтобы позвонить Hal_inctick () (база времени) Я думаю, что это не лучшая идея, чтобы попытаться изменить это поведение.
Одним из решений может быть добавление вызова Hal_systick_callback () в Systick_handler ()
Фактически:
Systick_handler () вызов Hal_systick_irqhandler() которые называют Hal_systick_callback()
Итак, как нам нужно определить Systick_handler Чтобы позвонить Hal_inctick () (база времени) Я думаю, что это не лучшая идея, чтобы попытаться изменить это поведение.
Одним из решений может быть добавление вызова Hal_systick_callback () в Systick_handler ()
void SysTick_Handler(void)
{
HAL_IncTick();
HAL_SYSTICK_Callback();
}
Даниэфф
Пн, сентябрь 04, 2017 12:39
У меня есть это systick_handler () {hal_inctick (); hal_systick_callback (); }, и не было никаких проблем.
Кроме того.
Кроме того.
fpistm
Пн, сентябрь 04, 2017, 14:26
Thnaks @daniel за ваш отзыв.
Я подведу пиар.
https: // github.com/stm32duino/arduino_c ... /проблемы/98
Я подведу пиар.
https: // github.com/stm32duino/arduino_c ... /проблемы/98