HAL library helps us to handle all the checking and clearing status flag bits so we don’t have to worry about them again, just use the following function as an interrupt handler routine.
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance==TIM3) //check if the interrupt comes from TIM3
{
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_9);
}
}
This Callback function is sharing among all timers interrupt. If you are using more than one Time base interrupt, you need to check the source of the interrupt before executing any command. For example, if you use TIM3 and TIM6 time base interrupt, the Callback function should be like this:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance==TIM3)
{
//do something here
}
if (htim->Instance==TIM6)
{
//do something else here
}
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance==TIM3) //check if the interrupt comes from TIM3
{
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_9);
}
}
This Callback function is sharing among all timers interrupt. If you are using more than one Time base interrupt, you need to check the source of the interrupt before executing any command. For example, if you use TIM3 and TIM6 time base interrupt, the Callback function should be like this:
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance==TIM3)
{
//do something here
}
if (htim->Instance==TIM6)
{
//do something else here
}
}
void TIM2_IRQHandler(void) //Функция обработчика прерывания от таймера 6
{
TIM2->SR &= ~TIM_SR_UIF; //Сбрасываем бит вызова прерывания.
GPIOC->ODR ^= GPIO_ODR_ODR8;//Инвертируем состояние вывода - зажигаем/гасим светодиод
}
int main()
{
NVIC_SetPriority(TIM2_IRQn, 1); //Приоритет прерывания
NVIC_EnableIRQ(TIM2_IRQn); //Разрешаем обработку прерывания от таймера 2
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; //Тактирование порта C
GPIOC->CRH |= GPIO_CRH_MODE8_0;//Вывод PC8 порта C - выход
GPIOC->CRH &= ~GPIO_CRH_CNF8;//Режим Push-Pull для вывода PC8 порта C
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;//Тактирование таймера TIM2
TIM2->PSC = 16799;//Настройка предделителя таймера
TIM2->ARR = 5000;//Загружаем число миллисекунд в регистр автоперезагрузки
TIM2->DIER |= TIM_DIER_UIE; //Разрешаем прерывание при переполнении счетчика
TIM2->CR1 |= TIM_CR1_CEN;//Запускаем счет
while(1);
}
#include "stm32f10x.h"
uint8_t i=0;
int main(void)
{
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN; // Enable PORTC Periph clock
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // Enable TIM2 Periph clock
// Clear PC8 and PC9 control register bits
GPIOC->CRH &= ~(GPIO_CRH_MODE8 | GPIO_CRH_CNF8 |
GPIO_CRH_MODE9 | GPIO_CRH_CNF9);
// Configure PC.8 and PC.9 as Push Pull output at max 10Mhz
GPIOC->CRH |= GPIO_CRH_MODE8_0 | GPIO_CRH_MODE9_0;
TIM2->PSC = SystemCoreClock / 1000 - 1; // 1000 tick/sec
TIM2->ARR = 1000; // 1 Interrupt/sec (1000/100)
TIM2->DIER |= TIM_DIER_UIE; // Enable tim2 interrupt
TIM2->CR1 |= TIM_CR1_CEN; // Start count
NVIC_EnableIRQ(TIM2_IRQn); // Enable IRQ
while(1); // Infinity loop
}
void TIM2_IRQHandler(void)
{
TIM2->SR &= ~TIM_SR_UIF; //Clean UIF Flag
if (1 == (i++ & 0x1)) {
GPIOC->BSRR = GPIO_BSRR_BS8; // Set PC8 bit
GPIOC->BSRR = GPIO_BSRR_BR9; // Reset PC9 bit
} else {
GPIOC->BSRR = GPIO_BSRR_BS9; // Set PC9 bit
GPIOC->BSRR = GPIO_BSRR_BR8; // Reset PC8 bit
}
}
Комментариев нет:
Отправить комментарий