STM32输出PWM波驱动无源蜂鸣器产生音乐
1.工作原理通过调整PWM波的频率改变无源蜂鸣器的音调按乐谱编程实现旋律播放。其中输出PWM波的频率决定音调占空比决定音量大小。2.基础内容2.1乐谱其中#C指升C大调比中央C高半个音。4/4指四分音符为一拍后一节有4拍前。78bpm指每秒78拍一拍0.77s。1234567依次为do re mi fa so la si0是休止符不发声。· 在数字上下指不同音程· 在上是高八度· 在下是低八度· 在右是附点延长前面音符时值的一半。— 在右是增时线每加一条横线时值增加一个四分音符的时长— 在下是减时线每加一条横线音符时值减半。2.2 音符频率对照表3.代码文件Buzzer Drive.c//PWM接PA1TIM2_CH2 #define Signal GPIO_Pin_1 void Buzzer_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitTypeDef GPIO_InitStruction; GPIO_InitStruction.GPIO_ModeGPIO_Mode_AF_PP; GPIO_InitStruction.GPIO_PinSignal; GPIO_InitStruction.GPIO_SpeedGPIO_Speed_50MHz; GPIO_Init(GPIOA,GPIO_InitStruction); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//36MHZ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructure.TIM_ClockDivisionTIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterModeTIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period0;//ARR TIM_TimeBaseStructure.TIM_Prescaler36-1;//PSC 1MHZ TIM_TimeBaseStructure.TIM_RepetitionCounter0; TIM_TimeBaseInit(TIM2,TIM_TimeBaseStructure); TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitStructure.TIM_OCModeTIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OCPolarityTIM_OCPolarity_High; TIM_OCInitStructure.TIM_OutputStateENABLE; TIM_OCInitStructure.TIM_Pulse0; //CCR TIM_OC2Init(TIM2,TIM_OCInitStructure); TIM_ARRPreloadConfig(TIM2,DISABLE);//失能预装载即刻起效 TIM_OC2PreloadConfig(TIM2,TIM_OCPreload_Disable); TIM_Cmd(TIM2,ENABLE); }PWM输出设置,打开GPIO时钟配置时基单元和输出比较单元使预装载功能失能。Music.c#include stm32f10x.h // Device header #include Music.h #include Delay.h //月亮代表我的心,BPM78拍/min,1拍0.77s #define L1 262 //低音do #define L2 294 //低音re #define L3 330 //低mi #define L4 349 //低fa #define L5 392 //低sol #define L6 440 //低la #define L7 494 //低si #define M1 523 #define M2 587 #define M3 659 #define M4 698 #define M5 784 #define M6 880 #define M7 988 #define H1 1046 #define H2 1175 #define H3 1318 #define H4 1397 #define H5 1568 #define H6 1760 #define H7 1976 #define S 0 //休止符 #define Whol_T 3080 //全音时长ms四拍 #define Semi_T 1540 //半音时长ms两拍 #define Qua_T 770 //四分之一音时长ms一拍 #define Eig_T 385 //八分之一音时长ms半拍 #define Sixt_T 193 //十六分之一音时长ms四分之一拍 uint16_t Music_F[][2] { {S,Eig_T},{L5,Eig_T},//一小节,除第一节外每小节都占4拍 {M1,Qua_T},{M1,Eig_T},{M3,Eig_T},{M5,Qua_T},{M5,Eig_T},{M1,Eig_T}, {L7,Qua_T},{L7,Eig_T},{M3,Eig_T},{M5,Qua_T},{M5,Qua_T},//延音半音合并用于简化 {M6,Qua_T},{M6,Eig_T},{M7,Eig_T},{H1,Qua_T},{H1,Eig_T},{M6,Eig_T}, {M5,Semi_T},{M5,Qua_T},{M3,Eig_T},{M2,Eig_T}, {M1,Semi_T},{M1,Qua_T},{M3,Eig_T},{M2,Eig_T}, {M1,Semi_T},{M1,Qua_T},{M3,Eig_T},{M2,Eig_T}, {M2,Qua_T},{M2,Eig_T},{M1,Eig_T},{L6,Qua_T},{M3,Eig_T},{M2,Eig_T}, {M2,Semi_T},{M2,Qua_T},{S,Eig_T},{L5,Eig_T}, {M1,Qua_T},{M1,Eig_T},{M3,Eig_T},{M5,Qua_T},{M5,Eig_T},{M1,Eig_T}, {L7,Qua_T},{L7,Eig_T},{M3,Eig_T},{M5,Semi_T}, {M6,Qua_T},{M6,Eig_T},{M7,Eig_T},{H1,Qua_T},{H1,Eig_T},{M6,Eig_T}, {M5,Semi_T},{M5,Qua_T},{M3,Eig_T},{M2,Eig_T}, {M1,Semi_T},{M1,Qua_T},{M3,Eig_T},{M2,Eig_T}, {M1,Semi_T},{M1,Qua_T},{M3,Eig_T},{M2,Eig_T}, {M2,Qua_T},{M2,Eig_T},{L6,Eig_T},{L7,Qua_T},{M1,Eig_T},{M2,Eig_T}, {M1,Semi_T},{M1,Qua_T},{M5,Qua_T}, {M3,Qua_T},{M3,Eig_T},{M2,Eig_T},{M1,Qua_T},{M5,Qua_T}, {L7,Semi_T},{L7,Qua_T},{L6,Eig_T},{L7,Eig_T}, {L6,Qua_T},{L6,Eig_T},{L7,Eig_T},{L6,Qua_T},{L5,Qua_T}, {M3,Semi_T},{M3,Qua_T},{M5,Qua_T}, {M3,Qua_T},{M3,Eig_T},{M2,Eig_T},{M1,Qua_T},{M5,Qua_T}, {L7,Semi_T},{L7,Qua_T},{L6,Eig_T},{L7,Eig_T}, {M1,Semi_T},{M1,Qua_T},{M1,Eig_T},{M2,Sixt_T},{M3,Sixt_T}, {M2,Whol_T} }; void Tone_Change(void) { for(uint16_t i0;isizeof(Music_F)/sizeof(Music_F[0]);i) { if(Music_F[i][0]0) { TIM_SetAutoreload(TIM2,65535);//ARR TIM_SetCompare2(TIM2,0);//CCR } else { uint16_t ARR1000000/Music_F[i][0]/1.0595-1; TIM_SetAutoreload(TIM2,ARR);//FpwmFclk/(psc1)/(ARR1),/1.0595升半音 TIM_SetCompare2(TIM2,0.5*(ARR1));//占空比50%CCR/(ARR1) } Delay_ms(Music_F[i][1]); } }将音符存入二维数组音调时值按顺序依次读取设置相应ARR值和CCR值。输出PWM波形频率FpwmFclk/(PSC1)/(ARR1)乐曲升C大调提高半个音整体乘≈1.0595十二平均律则ARRFclk/(PSC1)/Fpwm/1.0595-1。输出PWM波占空比CCR/(ARR1)将它设置为50%CCR50%*(ARR1)。Main.c#include stm32f10x.h // Device header #include Music.h #include Buzzer Drive.h int main(void) { Buzzer_Init(); while(1) { Tone_Change(); } }