Обработчик прерываний STM32

IDE
Offline
Зарегистрирован: 20.02.2020

Добрый вечер! Я работая с STM32F103C8T6  в Arduino IDE. С интерфейсами I2C  и SPI  работаю не через библиотеки а напрямую с регистрами. Всё хорошо работает. Но при отправки и приёме использую цикл while(),  а я хочу работать с прерываниями. Как мне объявить обработчик прерывания, например SPI ? 

b707
Offline
Зарегистрирован: 26.05.2017

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

mixail844
Offline
Зарегистрирован: 30.04.2012

b707 пишет:

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

если я правильно понимаю , ТС работает напрямую с регистрами ,то есть аддонными API не пользуется в явной форме.
я не силен в среде ардуино , но скажу что после того как прерывание,например для SPI1, будет правильно настроено , в случае STM32GENERIC  , вызоветься функция из файла STM32GENERIC/STM32/system/STM32F1/CMSIS_Src/startup_stm32f103x6.s по имени SPI1_IRQHandler , ее как раз и надо имплементировать и правильно обработать прерывание .
IDE
Offline
Зарегистрирован: 20.02.2020

Интересно, но ни чего не понял!  Я новичёк. Спасибо!

IDE
Offline
Зарегистрирован: 20.02.2020

b707 пишет:

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

https://github.com/bobc/maple-asp

IDE
Offline
Зарегистрирован: 20.02.2020

Кто нибудь поможет!?

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

Забей на абдурино, возьми Кейл и радуйся жизни.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Ты дал ссылку древний аддон, который уже 5 лет не апгрейдился. Честно говоря не стал смотреть.

В стандартном аддоне прием SPI сделан через DMA, неблокирующим. Данные складываются в память, откуда ты можешь в любое время их забрать. То есть применяя библиотеку нет нужны пользоваться прерыванием.

Если для каких-то целей ты используешь прямое управление регистрами, то и прерывание пиши на низком уровне - посмотри примеры в CMSIS.

Какого рода помощи ты ожидаешь? Пример - и правда в CMSIS можно подобрать. Личный опыт? Пока никто не откликнулся, кто на уровне регистров этим занимался... возможно это повод задуматься над тем, а почему никому не было надо? ;)) Без обид, ты ведь про свою задумку не написал, возможно и правда - нет нужды?

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Если в двух словах, то учиться лучше на готовых примерах, потому что их в интернете больше чем дофига. Если нарвешься на кал, то со временем это поймешь и это тоже будет полезный урок. Когда будешь разбирать примеры, необходимо читать доки, чтобы осознанно (ну или хотя бы как то, по началу) понимать, для чего нужны какие биты управления.

Другой вариант, выучить доки назубок и идти, огребая грабли своим путём. Нафиг, нет смысла терять время. Всё уже давно написано за нас!

В своё время делал на STM32F0 циклический вывод данных из памяти на SPI через DMA. Это было управление лентой на WS2812. Меняешь в буфере данные, они автоматом выводятся на SPI и меняются цвета на ленте WS2812. Красота! Вся времянка формируется  в SPI.

Про ArduinoIDE лучше не спрашивай. Либо ArduinoIDE, либо STM32.

Кстати, калокуб (STM32CubeMX) может помочь визуально видеть периферию на камне, я ставил, по началу, да и потом, удобно посмотреть какие пины будут заняты, куда их можно мапить, какая периферия осталась после подключения нужной. Как настраивать частоты на шинах и т.п. Но код генерить в нём не надо, больно будет. Извини, что не по-русски.

UPD: Правильные примеры можно посмотреть на сайте st.com. У них есть snippets, примеры. Пусть они только для F0 & L0 камней. Разархивировав эти snippets ты найдешь каталог SPI в котором есть примеры. Например, 01_FullDuplexCommunication, другой вариант, 02_CommunicationUsing DMA. Сиди, кури исходники, там комментариев выше крыши. Конечно разница между F1 и F0 большая, но всё таки. Мне F0 больше нравятся, их паять легче, да и поновей они.

 

IDE
Offline
Зарегистрирован: 20.02.2020

 Например, для AVR обработчик прерывания для SPI выглядит так: ISR(SPI_STC_vect ).  

С работало прерывание от SPI и программа переходит в оброботчик:

ISR (SPI_STC_vect) {

здесь выполняется код

}

 

А возможно ли типо такого сделать для STM32?

 
nik182
Offline
Зарегистрирован: 04.05.2015
void TIM1_CC_IRQHandler(void)
void TIM3_IRQHandler(void)
void USART1_IRQHandler(void)
void DMA1_Channel1_IRQHandler(void)
void SysTick_Handler(void)
void TIM6_DAC_IRQHandler(void)
void I2C1_ER_IRQHandler(void)
void SPI1_IRQHandler(void)
 
void SPI2_IRQHandler(void)
{
  /* Store SPI_SLAVE received data */
  SPI_SLAVE_Buffer_Rx[RxIdx++] = SPI_I2S_ReceiveData(SPI_SLAVE);
}
 
 
 
 
 
 
IDE
Offline
Зарегистрирован: 20.02.2020
Так и не могу попасть в обработчик!
 
В файле usart_f1.c написано:
 
 * Interrupt handlers.
 */
 
__weak void __irq_usart1(void) {
    usart_irq(&usart1_rb, &usart1_wb, USART1_BASE);
}
 
__weak void __irq_usart2(void) {
    usart_irq(&usart2_rb, &usart2_wb, USART2_BASE);
}
 
__weak void __irq_usart3(void) {
    usart_irq(&usart3_rb, &usart3_wb, USART3_BASE);
}
 
#ifdef STM32_HIGH_DENSITY
__weak void __irq_uart4(void) {
    usart_irq(&uart4_rb, &uart4_wb, UART4_BASE);
}
 
__weak void __irq_uart5(void) {
    usart_irq(&uart5_rb, &uart5_wb, UART5_BASE);
}
#endif

 

В скетче добавляю обработчик :

void __irq_usart1(void) {
 
}
 
Прерывание срабатывает, но в этот обработчик не заходит. Где то крутится в другом месте.
 
Может кто подскажет как сделать так бы заходил в обработчик?
mixail844
Offline
Зарегистрирован: 30.04.2012

IDE пишет:

Так и не могу попасть в обработчик!
 
В файле usart_f1.c написано:
 
 * Interrupt handlers.
 */
 
__weak void __irq_usart1(void) {
    usart_irq(&usart1_rb, &usart1_wb, USART1_BASE);
}
 
__weak void __irq_usart2(void) {
    usart_irq(&usart2_rb, &usart2_wb, USART2_BASE);
}
 
__weak void __irq_usart3(void) {
    usart_irq(&usart3_rb, &usart3_wb, USART3_BASE);
}
 
#ifdef STM32_HIGH_DENSITY
__weak void __irq_uart4(void) {
    usart_irq(&uart4_rb, &uart4_wb, UART4_BASE);
}
 
__weak void __irq_uart5(void) {
    usart_irq(&uart5_rb, &uart5_wb, UART5_BASE);
}
#endif

 

В скетче добавляю обработчик :

void __irq_usart1(void) {
 
}
 
Прерывание срабатывает, но в этот обработчик не заходит. Где то крутится в другом месте.
 
Может кто подскажет как сделать так бы заходил в обработчик?

либо неправильно насторили прерывания, либо заходит но только 1 раз  -  функции void __irq_usart1(void) {
 
}
пустой быть нежелательно ибо там обычно делают чистку флага прерывания что бы оно сработало и в следующий раз

 

nik182
Offline
Зарегистрирован: 04.05.2015

Чистку делают, что бы не сработало ещё раз сразу по выходу из текущего. 

Вид вызова прерывания зависит от тулкита установленного в иде и типа драйвера. 

STM Cube IDE совершенно бесплатно, имеет отладку и не маскирует вызовы. Выбор за Вами, но ардуино иде явно не та среда, где следует использовать приёмы глубокого проникновения в тонкости программирования STM.   

 
 
germt
Offline
Зарегистрирован: 29.09.2020

Добрый вечер, у Тебя в итоге получилось?? Если да, то напиши пожалуйста как, а то тоже бодаюсь с этим неделю - всё без толку.

Arduino studio + libmaple (hardware library: http://dan.drown.org/stm32duino/package_STM32duino_index.json)

Там есть файлик C:\Users\username\AppData\Local\Arduino15\packages\stm32duino\hardware\STM32F1\2020.8.9\cores\maple\libmaple\stm32f1\performance\isrs.S - в нём прописаны обработчики прерываний и инклуды, где они прописаны, как раз для SPI их нет, пробовал задать на подобие I2Cшных "__weak void __irq_spi1(void)" - так тоже не хочет работать.

Ещё видел кучу примеров с HAL (hardware library: https://raw.githubusercontent.com/stm32duino/BoardManagerFiles/master/ST...) STM32core но они все с DMA, а DMA я не вкуриваю от слова совсем.

А так тоже есть вариант на прерываниях на Arduino nano - всё прекрасно работает.

ПС: Почему на Arduino Studio? Потому что только с неё у меня получилось прогрузить blue pill (STM32F103C8T6 + китайский ST-Link V2).

STM32duino IDE со всеми примочками стоит, но ругается на мой ST-Link и не прогружает (обновлял firmware у ST-Link, как следствие этот ST-Link вообще отказался работать, благо, что второй есть).

Keil ставил - вообще не зашёл, даже blink скомпилировать не смог - помудохался пару дней и снёс его.

nik182
Offline
Зарегистрирован: 04.05.2015

Что бы st-link заработал, его прошивку надо обновить в программе STM32CubeProgrammer.

germt
Offline
Зарегистрирован: 29.09.2020

Так и сделал, но stm32studio ide после этого начал ругаться что серийник чипа палёный, потом ещё раз firmware перешивал а теперь вообще ide говорит что нет st-link а