I am trying to write code to play simple songs using a STM32F407G discovery board and the STM32CUBEIDE. I created an array to store the note frequency values and also one for their duration(not 100% accurate yet,just wanted to test a concept). I managed to get the buzzer to play the tones using PWM, however it does not finish my song and stops after a few tones, but if I leave the board plugged in it restarts from the beginning after a few minutes.
I have tried changing the delay before,after or in between notes and also tried playing around with the frequencies and ARR value, but to no avail. If anyone could point me in the right direction or show me where I made an error I will be grateful.
I enabled PWM output on pin A0, using the internal clock at 16MHz with 0 prescaler value. I will attach some code below: inside my while(1) loop I have: playSong():
EDIT: Solved the problem, if you change the ARR value the CNT register must be cleared to zero after every 'note', otherwise the count value could be greater than the ARR value which then causes issues.
uint32_t Frequency = C;
uint32_t CLOCK = 16000000;
int i;
/* Hap py Birth Day to you, Hap py birth day to
C4 C4 D4 C4 F4 E4 C4 C4 D4 C4 G4 */
unsigned int notes[] = { 262, 262, 294, 262, 349, 330, 262, 262, 294, 262, 392,
/* you, Hap py Birth Day dear xxxx Hap py birth
F4 C4 C4 C5 A4 F4 E4 D4 B4b B4b A4 */
349, 262, 262, 523, 440, 349, 330, 294, 466, 466, 440,
/* day to you
F4 G4 F4 */
349, 392, 349
};
unsigned int duration[] = {1,1,2,2,2,2,1,1,2,2,2,2,1,1,2,2,2,2,2,1,1,2,2,2,2};
void noTone(){
htim2.Instance->CCR1=0;
HAL_Delay(50);
}
void playSong(){
for (i = 0; i <55; i++) {
Frequency = CLOCK/notes[i];
htim2.Instance->ARR=Frequency;
htim2.Instance->CCR1=Frequency/2;
HAL_Delay(400*duration[i]);
noTone();
}
}
/* USER CODE END 0 */```
```/* USER CODE BEGIN WHILE */
while (1)
{
playSong();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}```