2024-11-09 01:04 AM - edited 2024-11-09 01:08 AM
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?
2024-11-09 01:50 AM
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
2024-11-09 02:09 AM - edited 2024-11-09 02:11 AM
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
2024-11-09 02:20 AM - edited 2024-11-09 02:22 AM
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
2024-11-09 10:48 AM
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.
2024-11-24 06:56 PM
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
{;}
}