Здравствуйте! Есть непонятный момент в работе TIM4 вместе с SysTick. Дело в том, что я настроил мигание одного светодиода с помощью SysTick, а второго с помощью TIM4 так, чтобы их периоды мигания были одинаковыми, но почему они мигают одновременно? Это же два прерывания, которые не могут вызываться одновременно. Я это понимаю так, что прерывание, вызванное TIM4 живет своей жизнью, но его постоянно прерывает SysTick для уменьшения буферной переменной. Скажите, пожалуйста, правильно ли я понимаю этот момент? Большое спасибо!
Добрый день!
А можете проект выслать, посмотреть, как организовано мигание?
#define GREEN_ON() GPIO_SetBits(GPIOD, GPIO_Pin_12) #define GREEN_OFF() GPIO_ResetBits(GPIOD, GPIO_Pin_12) #define RED_ON() GPIO_SetBits(GPIOD, GPIO_Pin_14) #define RED_OFF() GPIO_ResetBits(GPIOD, GPIO_Pin_14) #define RED_TOGGLE() GPIO_ToggleBits(GPIOD, GPIO_Pin_14) #define DELAY 1000 static uint16_t sysTickCount = 0; void InitLEDs(void) { GPIO_InitTypeDef GPIO_Init_LED; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); GPIO_Init_LED.GPIO_Mode = GPIO_Mode_OUT; GPIO_Init_LED.GPIO_OType = GPIO_OType_PP; GPIO_Init_LED.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_Init_LED.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init_LED.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOD, &GPIO_Init_LED); } /******************************************************************************************/ void InitTIM4 (void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); TIM_TimeBaseInitTypeDef timer; timer.TIM_Prescaler = 16000 - 1; timer.TIM_CounterMode = TIM_CounterMode_Up; timer.TIM_Period = 1000 - 1; timer.TIM_ClockDivision = 0; TIM_TimeBaseInit(TIM4, &timer); TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE); TIM_Cmd(TIM4, ENABLE); NVIC_EnableIRQ(TIM4_IRQn); } /***************************************************************************************/ void SysTick_Handler(void) // 1 ms { if ( sysTickCount ) { sysTickCount--; } } /***************************************************************************************/ void TIM4_IRQHandler(void) { if ( TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET ) { TIM_ClearITPendingBit(TIM4, TIM_IT_Update); RED_TOGGLE(); } } /******************************************************************************************/ int main(void) { InitLEDs(); InitTIM4(); SysTick_Config(SystemCoreClock/1000); while (1) { GREEN_OFF(); RED_OFF(); GREEN_ON(); DelayLed(DELAY); GREEN_OFF(); DelayLed(DELAY); } }
Я добавил RED_OFF() и GREEN_OFF(), потому что при выходе из отладки диоды мигали по очереди, но при этом у красного диода была небольшая задержка. Из этого всего я сделал вывод, что диоды находятся в каком-то непонятном состоянии до работы программы, поэтому нужно однозначно задать нулевое состояние на соответствующих пинах.
Когда я добавил RED_OFF() и GREEN_OFF(), диоды стали мигать точно одновременно, но нужно сбросить программу после выхода из отладчика, чтобы мигание диодов синхронизировать друг с другом.
@rodion-2 ну я так понимаю, что TIM4 и SysTick одновременно (плюс-минус) запускаются, соответственно и период одновременно почти истекает, и мигают поэтому на глаз одновременно.
Попробуй так:
int main(void) { InitLEDs(); GREEN_OFF(); RED_OFF(); InitTIM4(); SysTick_Config(SystemCoreClock/1000); DelayLed(500); while (1) { GREEN_ON(); DelayLed(DELAY); GREEN_OFF(); DelayLed(DELAY); } }