- u8 music[]={ 5,5,6,8,7,6,5,6,13,13,
- 5,5,6,8,7,6,5,3,13,13,
- 2,2,3,5,3,5,6,3,2,1,
- 6,6,5,6,5,3,6,5,13,13,
- 5,5,6,8,7,6,5,6,13,13,
- 5,5,6,8,7,6,5,3,13,13,
- 2,2,3,5,3,5,6,3,2,1,
- 6,6,5,6,5,3,6,1,
- 13,8,9,10,10,9,8,10,9,8,6,
- 13,6,8,9,9,8,6,9,8,6,5,
- 13,2,3,5,5,3,5,5,6,8,7,6,
- 6,10,9,9,8,6,5,6,8};
-
- u8 time[] = { 2,4,2,2,2,2,2,8,4,4,
- 2,4,2,2,2,2,2,8,4,4,
- 2,4,2,4,2,2,4,2,2,8,
- 2,4,2,2,2,2,2,8,4,4,
- 2,4,2,2,2,2,2,8,4,4,
- 2,4,2,2,2,2,2,8,4,4,
- 2,4,2,4,2,2,4,2,2,8,
- 2,4,2,2,2,2,2,8,
- 4,2,2,2,4,2,2,2,2,2,8,
- 4,2,2,2,4,2,2,2,2,2,8,
- 4,2,2,2,4,2,2,5,2,6,2,4,
- 2,2,2,4,2,4,2,2,12};
- const uint16_t tone[] = {247,262,294,330,349,392,440,494,523,587,659,698,784,1000};
- const uint16_t tonetime[] = {8097,7633,6802,6060,5076,5102,4545,4048,3824,3407,3034,2865,2550,2000}; //0.5us
tone中为对应的频率,为了简单我将频率转变为tonetime中的时间,单位0.5us
3、由于蜂鸣器连接了A8 pin 为TIM1的复用输出pin,所以这里配置TIM1
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
-
- GPIO_PinAFConfig(GPIOA, GPIO_Pin_8, GPIO_AF_2);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //PA8
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
上面RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);这个刚开始忘了,结果 哈哈。。。
定时器部分直接贴code,和STM32差不多,没啥好说的
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- TIM_OCInitTypeDef TIM_OCInitStructInit;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
-
- TIM_TimeBaseStructure.TIM_Period = Period;
- TIM_TimeBaseStructure.TIM_Prescaler =Prescaler;
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
- TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
- TIM_ClearFlag(TIM1, TIM_FLAG_Update);
- TIM_OCStructInit(&TIM_OCInitStructInit);
- // TIM_OCInitStructInit.TIM_OCMode = TIM_OCMode_Toggle;
- TIM_OCInitStructInit.TIM_OCMode = TIM_OCMode_PWM2;
- TIM_OCInitStructInit.TIM_OutputState = TIM_OutputState_Enable;
- TIM_OCInitStructInit.TIM_Pulse = 0;
- // TIM_OCInitStructInit.TIM_OCPolarity = TIM_OCPolarity_High;
- TIM_OCInitStructInit.TIM_OCPolarity = TIM_OCPolarity_Low;
- TIM_OC1Init(TIM1, &TIM_OCInitStructInit);
- TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
下面实现调频率
- void Buzzer_Set_Freq(u16 Period)
- {
- TIM_SetAutoreload(TIM1,Period);
- TIM_SetCompare1(TIM1,Period/2);
- }
下面开启关闭定时器,实现蜂鸣器发声
- void Buzzer_Set_En(FunctionalState NewState)
- {
- TIM_Cmd(TIM1, NewState);
- }
准备工作结束,下面就是播放控制,先看下控制结构体
- typedef struct
- {
- unsigned char PlayFlag;
- unsigned char CurrentPlayFlag;
- unsigned char PlayStep;
- unsigned char MusicNum;
- unsigned char ToneCount;
- unsigned char ToneNumCount;
- }_sPlayMusic;
蜂鸣在函数PlayMusic函数中实现,次函数由定时调度器调用,我这里是100ms调用一次,code如下
- void PlayMusic(void)
- {
- unsigned int tonetemp;
- switch(sPlayMusic.PlayStep)
- {
- case PLAYSTEP1:
- if(TRUE == sPlayMusic.PlayFlag)
- {
- //Buzzer_Set_Freq(tone[14-music[sPlayMusic.ToneNumCount]]);
- Buzzer_Set_Freq(tonetime[music[sPlayMusic.ToneNumCount]]);
- Buzzer_Set_En(ENABLE);
- sPlayMusic.PlayStep = PLAYSTEP2;
- }
- break;
-
- case PLAYSTEP2:
- if(sPlayMusic.ToneNumCount < sizeof(music)/sizeof(u8))
- {
- sPlayMusic.ToneCount++;
- if(sPlayMusic.ToneCount >= time[sPlayMusic.ToneNumCount])
- {
- sPlayMusic.ToneCount =0;
- sPlayMusic.ToneNumCount++;
- //Buzzer_Set_Freq(tone[14-music[sPlayMusic.ToneNumCount]]);
- tonetemp = tonetime[music[sPlayMusic.ToneNumCount]];
- if(tonetemp <= 2000) Buzzer_Set_En(DISABLE);
- else {
- Buzzer_Set_Freq(tonetemp);
- Buzzer_Set_En(ENABLE);
- }
- }
- }
- else{
- sPlayMusic.PlayStep = PLAYSTEP3;
- Buzzer_Set_En(DISABLE);
- }
- break;
-
- case PLAYSTEP3:
- sPlayMusic.PlayFlag = FALSE;
- sPlayMusic.CurrentPlayFlag = FALSE;
- sPlayMusic.MusicNum = 0;
- sPlayMusic.ToneCount = 0;
- sPlayMusic.ToneNumCount = 0;
- sPlayMusic.PlayStep = PLAYSTEP1;
- break;
- }
- }
然后在主函数中,当检测到Key2按下时,设置sPlayMusic.PlayFlag = TRUE; 即可,蜂鸣器开始演奏,目前程序没有实现演奏过程中停止演奏,演奏结束后,重新按键可以二次演奏。
截止目前,LED和蜂鸣器部分测试基本结束。附件有烧写的Hex文件,按Key2即可演奏红尘情歌,频率没有认真调试,也不是正式产品,效果还行,该有的功能基本都实现了。