Здравствуйте! Есть непонятный момент в работе 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);
}
}