Top.Mail.Ru
Уведомления
Очистить все

[Решено] работа SysTick с TIM4

Родион
(@rodion-2)
Active Member

Здравствуйте! Есть непонятный момент в работе TIM4 вместе с SysTick. Дело в том, что я настроил мигание одного светодиода с помощью SysTick, а второго с помощью TIM4 так, чтобы их периоды мигания были одинаковыми, но почему они мигают одновременно? Это же два прерывания, которые не могут вызываться одновременно. Я это понимаю так, что прерывание, вызванное TIM4 живет своей жизнью, но его постоянно прерывает SysTick для уменьшения буферной переменной. Скажите, пожалуйста, правильно ли я понимаю этот момент? Большое спасибо!

Цитата
Topic starter Размещено : 31.08.2021 01:31
Aveal
(@aveal)
Illustrious Member Admin

Добрый день!
А можете проект выслать, посмотреть, как организовано мигание?

ОтветитьЦитата
Размещено : 31.08.2021 11:02
Родион
(@rodion-2)
Active Member
#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);
	}
}
ОтветитьЦитата
Topic starter Размещено : 31.08.2021 13:51
Родион
(@rodion-2)
Active Member

Я добавил RED_OFF()  и GREEN_OFF(), потому что при выходе из отладки диоды мигали по очереди, но при этом у красного диода была небольшая задержка. Из этого всего я сделал вывод, что диоды находятся в каком-то непонятном состоянии до работы программы, поэтому нужно однозначно задать нулевое состояние на соответствующих пинах.

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

ОтветитьЦитата
Topic starter Размещено : 31.08.2021 14:09
Aveal
(@aveal)
Illustrious Member Admin

@rodion-2 ну я так понимаю, что TIM4 и SysTick одновременно (плюс-минус) запускаются, соответственно и период одновременно почти истекает, и мигают поэтому на глаз одновременно.

ОтветитьЦитата
Размещено : 31.08.2021 19:56
Aveal
(@aveal)
Illustrious Member Admin

Попробуй так:

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);
	}
}
ОтветитьЦитата
Размещено : 31.08.2021 20:04
Родион
(@rodion-2)
Active Member

@aveal Спасибо за помощь

Нравится: 1
ОтветитьЦитата
Topic starter Размещено : 31.08.2021 23:41
Поделиться: