cancel
Showing results for 
Search instead for 
Did you mean: 

How to use Timer6 and Timer7 at the same time?

MQi.1
Senior II

I used Timer6 and Timer7 on STM32L433CCT6, used Timer6 for tone generation and Timer7 for tone toggle generation, the ISR is:

 

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim)
{
	if(htim == &htim6)
	{
		HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0);
		//TIM6->CNT = toneFreq[0];
	}
	else if(htim == &htim7)
	{
		if(flagOnOff == SET)
		{
			if(msTone >= toneOn[toneFreqIndex])
			{
				flagOnOff = RESET;
				msTone = 0;
				GPIOA->MODER &= ~(GPIO_MODER_MODER0);	// From output to input
			}
			else
			{
				msTone++;
			}
		}
		else		// flagOnOff == RESET
		{
			if(msTone >= toneOff[toneFreqIndex])
			{
				flagOnOff = SET;
				msTone = 0;
				GPIOA->MODER |= GPIO_MODER_MODER0_0;	// From input to output
			}
			else
			{
				msTone++;
			}
		}
	}
	else
	{;}
}

 

the related variables are:

 

extern int toneFreq[] = {130, 146, 164, 174, 196, 220, 246};	// prescale value of Timer6 is 71
extern int toneOn[] = {9000, 8000, 7000, 6000, 5000, 4000, 3000};		// miliseconds, prescale value of Timer7 is 7199
extern int toneOff[] = {1000, 2000, 3000, 4000, 5000, 6000, 7000};		// 10us = 1 tick

int msTone = 0;		// miliseconds

volatile bool flagOnOff = SET;

 

now, the tone was OK, the toggle affection was not, did I lost anything?

5 REPLIES 5
KnarfB
Principal III

The overall pattern testting for tim6 tim7 is okay. 

How many interrupts per second does your code generate? Maybe the CPU is overrun by interrupts, which can easily happen, especially when using HAL.

Try relaxing the interrupt frequency for testing.

hth

KnarfB

Probably consequence of unrealistically high interrupt rate (1MHz of TIM6), especially in conjunction with Cube/HAL (and potentially no or low compiler optimization).

Generate the tone using PWM/Toggle on a timer which has some TIMx_CHx pin available, and then the on/off pattern using interrupt gets realistic.

JW

 

The main clock is 72M, after scale, the frequency for Timer6 is 1M, Timer7 is 10K. The tone frequency is in range:

* Notes		Frequency(Hz)			Cycle/Period				ARR value
*    C4				261					1M/261=3831				65535-261/2=65405
*    D4				293					1M/293=3412				65535-293/2=65389
*    E4				329					1M/329=3039				65535-329/2=65371
*    F4				349					1M/349=2865				65535-349/2=65361
*    G4				392					1M/392=2551				65535-392/2=65339
*    A4				440					1M/440=2272				65535-440/2=65315
*    B4				493					1M/493=2028				65535-493/2=65289

It's impossible to handle 1M interrupts per second with HAL and almost impossible without (actually totally impossible at 72 MHz). Use PWM for frequency generation.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice

I found a solution - set flag in Timer7 ISR and judge it in Timer6 ISR:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim)
{
	if(htim == &htim6)
	{
		if(flagOnOff == SET)
		{
			HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0);
			//HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, SET);	// PNP - SS8550
			//HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, RESET);	// NPN - SS8050
			//TIM6->CNT = toneFreq[0];
		} else {
			//HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, SET);	// PNP - SS8550
			HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, RESET);	// NPN - SS8050
			//HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0);
		}

	}
	else if(htim == &htim7)
	{
		if(flagOnOff == SET)
		{
			if(msTone >= toneOn[toneFreqIndex])
			{
				flagOnOff = RESET;
				msTone = 0;
				//GPIOA->MODER &= ~(GPIO_MODER_MODER0);	// From output to input

			}
			else
			{
				msTone++;
			}
		}
		else		// flagOnOff == RESET
		{
			if(msTone >= toneOff[toneFreqIndex])
			{
				flagOnOff = SET;
				msTone = 0;
				//GPIOA->MODER |= GPIO_MODER_MODER0_0;	// From input to output
			}
			else
			{
				msTone++;
			}
		}
	}
	else
	{;}
}