This is the sixth day of my participation in the August More text Challenge. For details, see:August is more challenging
If you want to play a song, you must use a passive buzzer, because the passive buzzer emits sound through the output frequency of PWM. When the PWM frequency is set to a certain value, the buzzer will emit the sound of do re mi Fa so La xi. This allows music to be played through the passive buzzer.
The driving principle diagram is as follows:To achieve the chord tone must be controlled through two IO ports, one of which controls the power supply of the buzzer, the other controls the frequency of oscillation.
The following code directly:
#ifndef __BUZZER_H
#define __BUZZER_H
#include "stm8s103f3p.h"
// Do re mi fa so La xi
#define BUZZER_LOW_DO_1 (262) / / ARR value of 2045
#define BUZZER_LOW_RE_2 (294) / / ARR value of 1820
#define BUZZER_LOW_MI_3 (330) / / ARR value of 1620
#define BUZZER_LOW_FA_4 (349) / / ARR value of 1525
#define BUZZER_LOW_SO_5 (392) / / ARR value of 1355
#define BUZZER_LOW_LA_6 (440) / / ARR value of 1205
#define BUZZER_LOW_XI_7 (494) / / ARR value of 1078
/ / alto
#define BUZZER_MIDDLE_DO_1 (523) / / ARR
#define BUZZER_MIDDLE_RE_2 (587) / / ARR
#define BUZZER_MIDDLE_MI_3 (659) / / ARR
#define BUZZER_MIDDLE_FA_4 (698) / / ARR
#define BUZZER_MIDDLE_SO_5 (784) / / ARR
#define BUZZER_MIDDLE_LA_6 (880) / / ARR
#define BUZZER_MIDDLE_XI_7 (988) / / ARR
/ / high
#define BUZZER_HIGH_DO_1 (1047) / / ARR
#define BUZZER_HIGH_RE_2 (1175) / / ARR
#define BUZZER_HIGH_MI_3 (1319) / / ARR
#define BUZZER_HIGH_FA_4 (1397) / / ARR
#define BUZZER_HIGH_SO_5 (1568) / / ARR
#define BUZZER_HIGH_LA_6 (1760) / / ARR
#define BUZZER_HIGH_XI_7 (1976) / / ARR
typedef enum
{
FREQ_2K,
FREQ_2K3,
FREQ_2K6,
FREQ_2K9,
FREQ_NO,
FREQ_LOW_DO_1,
FREQ_LOW_RE_2,
FREQ_LOW_MI_3,
FREQ_LOW_FA_4,
FREQ_LOW_SO_5,
FREQ_LOW_LA_6,
FREQ_LOW_XI_7
} FREQ_Type; // Frequency type
typedef enum
{
MONO = 0./ / mono
POLY_ON = 1.// Start the chord
POLY_OFF = 2 // Turn off the chord
} Tone_Type; // Sound type of the buzzer
typedef struct
{
FREQ_Type Freq; / / frequency
unsigned char OSCTime; // Duration of oscillation. The minimum unit is 10ms
unsigned char PWRTime; // Power supply duration, the minimum unit is 10ms
} TONE_Def; // Tonal structures
void buzzer_gpio_init(void);
void BeepPwrOn(void);
void BeepPwrOff(void);
void BEEP_On(void);
void BEEP_Off(void);
void TIM1_Init(void);
void BuzzerStart(Tone_Type ToneType);
void BuzzerCtrl(void);
void BEEP_SetFreq(FREQ_Type Freq);
void MusicStart(void);
#endif /* __BUZZER_H */
Copy the code
First, the fixed frequency is defined in the header file using a macro definition. When using, the specified frequency is called directly through the macro definition.
#include "buzzer.h"
#include "stm8s103f3p.h"
#include "delay.h"
_Bool Beep_Power @PD_ODR:3; //PD3 is used for buzzer power supply control
_Bool Beep_Pre @PD_ODR:4; //PD4 for frequency control
const TONE_Def Tone5[] = // Two tigers (Two tigers two tigers run fast, run fast)
{
{FREQ_LOW_DO_1, 25.25},/ / 1
{FREQ_LOW_RE_2, 25.25},/ / 2
{FREQ_LOW_MI_3, 25.25},/ / 3
{FREQ_LOW_DO_1, 25.25},/ / 1
{FREQ_LOW_DO_1, 25.25},/ / 1
{FREQ_LOW_RE_2, 25.25},/ / 2
{FREQ_LOW_MI_3, 25.25},/ / 3
{FREQ_LOW_DO_1, 25.25},/ / 1
{FREQ_LOW_RE_2, 25.25},/ / 2
{FREQ_LOW_MI_3, 25.25},/ / 3
{FREQ_LOW_FA_4, 50.25},//4 A slight pause
{FREQ_LOW_RE_2, 25.25},/ / 2
{FREQ_LOW_MI_3, 25.25},/ / 3
{FREQ_LOW_FA_4, 100.25},//4
{FREQ_NO, 0.0} / / stop
};
// do-re-mi-fa-so-la-ti
TONE_Def T1[] = {{FREQ_2K, 25.25},{FREQ_NO, 0.0}}; //do 1
TONE_Def T2[] = {{FREQ_2K3, 25.25},{FREQ_NO, 0.0}};//re 2
TONE_Def T3[] = {{FREQ_2K6, 25.25},{FREQ_NO, 0.0}};//mi 3
TONE_Def T4[] = {{FREQ_2K9, 25.25},{FREQ_NO, 0.0}};//fa 4
// Frequency oscillation duration Power supply duration
TONE_Def Tone1[] = {{FREQ_2K6, 100.20},{FREQ_NO, 0.0}};/ / mono
TONE_Def Tone2[] = {{FREQ_2K3, 20.20},{FREQ_2K6, 20.20},{FREQ_2K9, 210.10},{FREQ_NO, 0.0}};// Start the chord
TONE_Def Tone3[] = {{FREQ_2K9, 20.20},{FREQ_2K6, 20.20},{FREQ_2K3, 210.10},{FREQ_NO, 0.0}};// Turn off the chord
TONE_Def * pTone;
unsigned char BuzzerStatus =2;
// Control pin initialization
void buzzer_gpio_init(void)
{
PD_DDR|=(1<<3); // The PD3 output controls the power supply of the buzzer
PD_CR1|=(1<<3); //PD3 push pull output
PD_DDR|=(1<<4); // The PD4 output controls the buzzer frequency
PD_CR1|=(1<<4); //PD4 push pull output
}
// Power control
void BeepPwrOn(void)
{
Beep_Power=1;
}
void BeepPwrOff(void)
{
Beep_Power=0;
}
// Frequency control
void BEEP_On(void)
{
TIM1_CR1 |=(1<<0); // Enable the timer
Beep_Pre=1; // The frequency control pin is open
}
void BEEP_Off(void)
{
TIM1_CR1 &=~(1<<0); // Disable the timer
Beep_Pre=0; // Close the frequency control pin
}
// Set the ringtone type to 0 1 2
void BuzzerStart(Tone_Type ToneType)
{
switch (ToneType)
{
case MONO: / / 0 single tone
pTone = Tone1;
break;
case POLY_ON: / / 1 boot
pTone = Tone2;
break;
case POLY_OFF: / / 2 to turn it off
pTone = Tone3;
break;
default:
pTone = Tone1; / / mono
break;
}
BuzzerStatus = 1;
}
void MusicStart(void)
{
/* char i; for(i=1; i<5; i++) { if(i==1)pTone=T1; if(i==2)pTone=T2; if(i==3)pTone=T3; if(i==4)pTone=T4; BuzzerStatus = 1; while(BuzzerStatus! =3) { BuzzerCtrl(); delay_ms(15); }} * /
pTone=Tone5;
BuzzerStatus = 1;
while(BuzzerStatus! =3)
{
BuzzerCtrl();
delay_ms(15); }}// Sound control
void BuzzerCtrl(void)
{
static TONE_Def Tone; // Tone frequency oscillation time Power supply time
switch (BuzzerStatus)
{
case 1: // Call the tone array
Tone = *pTone;
if(Tone.Freq ! = FREQ_NO)// The frequency is not zero
{
// First judge the power supply duration
if(Tone.PWRTime ! =0) // The power supply time is not 0
{
Tone.PWRTime --;
BeepPwrOn();
}
else
{
BuzzerStatus = 3;
break;
}
// Then judge the duration of the oscillation
if(Tone.OSCTime ! =0) // The oscillation time is not zero
{
Tone.OSCTime--;
BEEP_SetFreq(Tone.Freq);// Set the frequency
BEEP_On();
}
else
{
BeepPwrOff();
BuzzerStatus = 3;
break;
}
// Start the countdown
BuzzerStatus = 2;
}
else // The frequency is 0
{
BuzzerStatus = 3;
}
break;
case 2: // Delay until the time is 0 to switch the next tone
if(Tone.PWRTime ! =0)
{
Tone.PWRTime --;
}
else
{
BeepPwrOff();
}
if(Tone.OSCTime ! =0)
{
Tone.OSCTime --;
}
else
{
BEEP_Off();
pTone ++; // Take the next tone
BuzzerStatus = 1;
}
break;
default:
break; }}// Initialize timer 1
void TIM1_Init(void)
{
TIM1_CR1|=(1<<7); // Automatic preloading is allowed
TIM1_IER = 0x01; // Allow update interrupts
TIM1_PSCRH = 0x00; // Perform 3 frequency division =16M/(15+1)=1M CNTR count once 1/1m =1us
TIM1_PSCRL = 0x0e;
TIM1_ARRH = 205/255; // Set a fixed value
TIM1_ARRL = 205%255;
TIM1_CR1 |=0x01; // Enable the timer
}
// Timer 1 interrupt function
// The frequency of one cycle is 2K
@far @interrupt void TIM1_OVER_Int(void)
{
TIM1_SR1 = 0x00;
Beep_Pre=~Beep_Pre;
}
// Change the buzzer frequency
void BEEP_SetFreq(FREQ_Type Freq)
{
unsigned char prescal=0;
switch(Freq)
{
case FREQ_2K:
prescal=255; //2K 265
break;
case FREQ_2K3:
prescal=230; / / 2.3 K of 230
break;
case FREQ_2K6:
prescal=205; / / 2.6 K of 205
break;
case FREQ_2K9:
prescal=182; / / 2.9 K of 182
break;
case FREQ_LOW_DO_1:
prescal=2045;
break;
case FREQ_LOW_RE_2:
prescal=1820;
break;
case FREQ_LOW_MI_3:
prescal=1620;
break;
case FREQ_LOW_FA_4:
prescal=1525;
break;
case FREQ_LOW_SO_5:
prescal=1355;
break;
case FREQ_LOW_LA_6:
prescal=1205;
break;
case FREQ_LOW_XI_7:
prescal=1078;
break;
default:
prescal=265;
}
TIM1_CR1|=(1<<7); // Automatic preloading is allowed
TIM1_IER = 0x01; // Allow update interrupts
TIM1_PSCRH = 0x00; // Perform 3 frequency division =16M/(15+1)=1M CNTR count once 1/1m =1us
TIM1_PSCRL = 0x0e;
TIM1_ARRH = prescal/255; // Set a fixed value
TIM1_ARRL = prescal%255;
TIM1_CR1 |=0x01; // Enable the timer
}
Copy the code
SCM PD3 control buzzer power supply, PD4 output PWM waveform. By changing the timing of the timer to change the frequency of the output PWM, to make the code easier to write, only one bar of the two tigers’ song is played here.
You can play music by calling it directly from the main function.
#include "stm8s103f3p.h"
#include "delay.h"
#include "buzzer.h"
extern unsigned char BuzzerStatus;
void CLK_Init(void)
{
CLK_SWR=0xe1; //HSI 16MHz CPU clock frequency of the primary clock source
CLK_CKDIVR=0x00; // The CPU clock is 0 and the system clock is 0
}
main()
{
unsigned char i;
CLK_Init();
_asm("sim"); // Disable interrupt
delay_init(16);
buzzer_gpio_init();
_asm("rim"); // Enable interrupt
while (1)
{
MusicStart();
delay_ms(500); }}Copy the code
In the same way, you can code the music you want to play.