OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 20792|回复: 23

PWM控制蜂鸣器播放音乐

[复制链接]

1

主题

4

帖子

0

精华

新手入门

积分
15
金钱
15
注册时间
2016-7-20
在线时间
1 小时
发表于 2016-7-28 09:10:06 | 显示全部楼层 |阅读模式
1金钱
请各位路过的高手帮忙看下,我找了一份F1的程序,修改后放在探索者中实验,用PWM来控制蜂鸣器播放一节小音乐的,可是每次下载后,总是只响乐曲的第一个音符,往下就没有反应了。调试时程序看着也是按步骤走的,可为什么不响呢?//////////////////////////////////////////////////////

#include "pwm.h"
#include "led.h"
#include   "beep.h"
//TIM13 PWM部分初始化
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void TIM13_PWM_Init_Init(u32 arr,u32 psc)
{                                                          
        //此部分需手动修改IO口设置
       
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStruc;
        TIM_OCInitTypeDef  TIM_OCInitStruc;
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM13,ENABLE);          //TIM13时钟使能   
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);         //使能PORTF时钟       
       
        GPIO_PinAFConfig(GPIOF,GPIO_PinSource8,GPIO_AF_TIM13); //GPIOF8复用为定时器13
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;           //GPIOF8
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;        //速度100MHz
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;        //上拉
        GPIO_Init(GPIOF,&GPIO_InitStructure);              //初始化PF8
          
        TIM_TimeBaseStruc.TIM_Prescaler=psc;  //定时器分频
        TIM_TimeBaseStruc.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
        TIM_TimeBaseStruc.TIM_Period=arr;   //自动重装载值
        TIM_TimeBaseStruc.TIM_ClockDivision=TIM_CKD_DIV1;
       
        TIM_TimeBaseInit(TIM13,&TIM_TimeBaseStruc);//初始化定时器13
        //初始化TIM13 Channel1 PWM模式         
        TIM_OCInitStruc.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1
        TIM_OCInitStruc.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
        TIM_OCInitStruc.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低
        TIM_OCInitStruc.TIM_Pulse=0;
        TIM_OC1Init(TIM13, &TIM_OCInitStruc);  //根据T指定的参数初始化外设TIM13 OC1

        TIM_OC1PreloadConfig(TIM13, TIM_OCPreload_Enable);  //使能TIM13在CCR1上的预装载寄存器

       TIM_ARRPreloadConfig(TIM13,ENABLE);//ARPE使能
       
        TIM_Cmd(TIM13, ENABLE);  //使能TIM13                                                                                  
}  

//////////////////////////////////////////////////////////////
//蜂鸣器初始化
#include "beep.h"
//初始化PF8为输出口                    
//BEEP IO初始化
void BEEP_Init(void)
{   
  GPIO_InitTypeDef  GPIO_InitStructure;
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//使能GPIOF时钟
  //初始化蜂鸣器对应引脚GPIOF8
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//100MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//下拉
  GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化GPIO
       
  GPIO_ResetBits(GPIOF,GPIO_Pin_8);  //蜂鸣器对应引脚GPIOF8拉低
}


////////////////////////////////////////////////////////////////
//music.h
  //文件:music.h  
#ifndef __MUSIC_H__
#define __MUSIC_H__
#include  "sys.h"
// 定义低音音名(数值单位:Hz)  
#define L1 262 // c
#define L2 294 // d  
#define L3 330 // e  
#define L4 349 // f
#define L5 392 // g  
#define L6 440 // a1  
#define L7 494 // b1

// 定义中音音名
#define M1 523 // c1  
#define M2 587 // d1
#define M3 659 // e1  
#define M4 698 // f1
#define M5 784 // g1  
#define M6 880 // a2  
#define M7 988 // b2

// 定义高音音名
#define H1 1047 // c2
#define H2 1175 // d2
#define H3 1319 // e2  
#define H4 1397 // f2  
#define H5 1568 // g2  
#define H6 1760 // a3  
#define H7 1976 // b3   
// 定义时值单位,决定演奏速度(数值单位:ms)  
#define T 3600  
#define TT 2000

//定义音符结构
typedef struct  {  
short mName; // 音名:取值L1~L7、M1~M7、H1~H7分别表示低音、中音、高音的1234567,取值0表示休止符  
short mTime; // 时值:取值T、T/2、T/4、T/8、T/16、T/32分别表示全音符、 二分音符、四分音符、八分音符 ,取值0表示演奏结束
}tNote;

void buzzerQuiet(void);
void buzzerSound(unsigned short usFreq);
void musicPlay(void);
#endif


///////////////////////////////////////////////////////////
//music.c
#include "sys.h"  
#include "music.h"
#include  "delay.h"
#include "beep.h"   
//#include  "pwm.h"
// 定义乐曲:《化蝶》(梁祝)
const tNote MyScore[] =
{   
   {L3, T/4},

                {L5, T/8+T/16},
                //
                {L6, T/16},
                 
                {M1, T/8+T/16},  

                {M2, T/16},  

                {L6, T/16},

                {M1, T/16},

                {L5, T/8},  

                {M5, T/8+T/16},  

                {H1, T/16},

                 {M6, T/16},
                 
                 {M5, T/16},
                 
                {M3, T/16},  

                {M5, T/16},

{0, 0} // 结束
};   
// 蜂鸣器停止发声
void buzzerQuiet(void)  
{
   GPIO_InitTypeDef  GPIO_InitStructure;  
   TIM_Cmd(TIM13, DISABLE);  //停止TIM3
       
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //PB.5 端口配置
                   //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;    //推挽输出
   GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
   GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
       
   GPIO_Init(GPIOF, &GPIO_InitStructure);  //根据设定参数初始化GPIOB.5
       
   GPIO_ResetBits(GPIOF,GPIO_Pin_8); //PB.5 输出低
}
//蜂鸣器发出指定频率的声音
//usFreq是发声频率,取值 (系统时钟/65536)+1 ~ 20000,单位:Hz
void buzzerSound(unsigned short usFreq)   
{
    // GPIO_InitTypeDef  GPIO_InitStructure;  
   unsigned long  ulVal;                                                              
   if((usFreq<=8000000/65536UL)||(usFreq>20000))  
    {
     buzzerQuiet();// 蜂鸣器静音  
    }   
   else
     {  
                 GPIO_PinAFConfig(GPIOF,GPIO_PinSource8,GPIO_AF_TIM13);
                                    
                  // GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        //速度50MHz
                  // GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;           //GPIOF9
              // GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用功能
              // GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
              // GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;        //上拉
                 
                   ulVal=8000000/usFreq;
                   TIM13->ARR =ulVal;  //设置自动重装载寄存器周期的值(音调)   
                   TIM_SetCompare1(TIM13,ulVal/2);//音量   
                   TIM_Cmd(TIM13, ENABLE);  //启动TIM3  
     }   
}
// 演奏乐曲
//此为延时函数控
void musicPlay(void)  
{
  u8 i=0;  
  while(1)  

        {  
                if (MyScore[i].mTime == 0)
                break;
                buzzerSound(MyScore[i].mName);
                delay_ms(MyScore[i].mTime);
                i++;  
                buzzerQuiet(); // 蜂鸣器静音
            delay_ms(100);// 10 ms

    }  
}

//////////////////////////////////////////////////////////////////

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "pwm.h"
#include   "beep.h"
#include   "music.h"
//延时函数控制时间
int main(void)  
{  
   delay_init(168);       //延时函数初始化   
   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
   TIM13_PWM_Init_Init(14399,10);  //分频。PWM频率=72000/14400/11(Khz)
   for (;;)
     {  
        musicPlay();
        delay_ms(1500);  
        delay_ms(1500);
      }
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

4

帖子

0

精华

新手入门

积分
15
金钱
15
注册时间
2016-7-20
在线时间
1 小时
 楼主| 发表于 2016-7-28 09:10:07 | 显示全部楼层
回复

使用道具 举报

307

主题

1427

帖子

12

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
7876
金钱
7876
注册时间
2015-10-15
在线时间
2875 小时
发表于 2016-7-28 18:58:45 | 显示全部楼层
这个看起来还真有点复杂。。。。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

1

主题

18

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2016-7-28
在线时间
7 小时
发表于 2016-7-29 17:54:26 | 显示全部楼层
用无源蜂鸣器,理论上是可行的。我做过消防警号的模拟。
如果误用了有源蜂鸣器,永远也搞不出来。
回复

使用道具 举报

2

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
63
金钱
63
注册时间
2016-9-23
在线时间
15 小时
发表于 2017-1-2 18:18:37 | 显示全部楼层

楼主你的蜂鸣器是有源的吗?
我听说有源的无法播放音乐,你是怎么搞定的
回复

使用道具 举报

0

主题

4

帖子

0

精华

新手上路

积分
23
金钱
23
注册时间
2016-4-12
在线时间
4 小时
发表于 2017-3-27 17:31:26 | 显示全部楼层
什么问题  导致不能发出声音
回复

使用道具 举报

0

主题

0

帖子

0

精华

新手入门

积分
2
金钱
2
注册时间
2021-11-1
在线时间
2 小时
发表于 2017-4-12 02:58:11 | 显示全部楼层
void musicPlay(void)里的        buzzerQuiet(); // 蜂鸣器静音 屏蔽掉就好了
回复

使用道具 举报

53

主题

567

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2099
金钱
2099
注册时间
2017-2-11
在线时间
306 小时
发表于 2017-7-8 00:47:08 | 显示全部楼层
回复

使用道具 举报

5

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
170
金钱
170
注册时间
2015-8-10
在线时间
49 小时
发表于 2017-7-8 10:38:25 | 显示全部楼层
不说明搞定原因是最骚的
回复

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2017-10-11
在线时间
1 小时
发表于 2017-10-11 14:44:20 | 显示全部楼层
是怎么将梁祝的曲子转化为const tNote MyScore[] 的  因为我要播放其他歌曲
回复

使用道具 举报

2

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
116
金钱
116
注册时间
2018-1-30
在线时间
20 小时
发表于 2018-2-5 17:37:59 | 显示全部楼层
JD123 发表于 2017-7-8 10:38
不说明搞定原因是最骚的

说得对
回复

使用道具 举报

0

主题

7

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2016-11-20
在线时间
78 小时
发表于 2018-3-4 22:48:07 | 显示全部楼层
本帖最后由 林海原 于 2018-3-4 22:51 编辑

战舰的蜂鸣器播放生日快乐歌源码参考下!
蜂鸣器谱曲生日快乐源码.rar (2.57 MB, 下载次数: 3279)
淘宝店铺--字节智控
回复

使用道具 举报

2

主题

12

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2018-5-17
在线时间
10 小时
发表于 2018-5-19 17:11:33 | 显示全部楼层
本帖最后由 FayeYeh 于 2018-5-20 20:40 编辑
林海原 发表于 2018-3-4 22:48
战舰的蜂鸣器播放生日快乐歌源码参考下!

看明白了,昨天没注意看,实在打扰了
回复

使用道具 举报

3

主题

28

帖子

0

精华

初级会员

Rank: 2

积分
99
金钱
99
注册时间
2017-12-14
在线时间
32 小时
发表于 2019-2-22 13:23:40 | 显示全部楼层
好好学习,天天向上!
回复

使用道具 举报

14

主题

65

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
205
金钱
205
注册时间
2019-3-31
在线时间
31 小时
发表于 2019-5-7 19:39:56 | 显示全部楼层
林海原 发表于 2018-3-4 22:48
战舰的蜂鸣器播放生日快乐歌源码参考下!

感谢分享
回复

使用道具 举报

0

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2019-5-7
在线时间
25 小时
发表于 2019-5-16 14:43:31 | 显示全部楼层
JD123 发表于 2017-7-8 10:38
不说明搞定原因是最骚的

删掉几句代码就OK
回复

使用道具 举报

0

主题

7

帖子

0

精华

新手上路

积分
28
金钱
28
注册时间
2019-6-5
在线时间
9 小时
发表于 2019-6-5 13:37:54 | 显示全部楼层
林海原 发表于 2018-3-4 22:48
战舰的蜂鸣器播放生日快乐歌源码参考下!

你好,我下了你这个文件,在51上打开,但是程序不能下载,蜂鸣器也没有响,代码里好像没有beep,这个怎么解决?
回复

使用道具 举报

5

主题

26

帖子

0

精华

初级会员

Rank: 2

积分
71
金钱
71
注册时间
2019-4-29
在线时间
15 小时
发表于 2019-6-5 19:44:58 | 显示全部楼层
林海原 发表于 2018-3-4 22:48
战舰的蜂鸣器播放生日快乐歌源码参考下!

感谢感谢,非常棒
回复

使用道具 举报

0

主题

5

帖子

0

精华

新手上路

积分
38
金钱
38
注册时间
2019-8-2
在线时间
10 小时
发表于 2019-8-3 11:48:22 | 显示全部楼层
void TIM2_PWM_Init(u16 arr,u16 psc)
{  
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        TIM_OCInitTypeDef  TIM_OCInitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);        //使能定时器2时钟
//         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA  | RCC_APB2Periph_AFIO, ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOF时钟       
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_TIM2);  //GPIOA7复用为定时器1

   //设置该引脚为复用输出功能,输出TIM3 CH1的PWM脉冲波形        GPIOC.6
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //TIM_CH2
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;  //复用推挽输出
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;     //推挽复用输出
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;  
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO

   //初始化TIM3
        TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
        TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
       
//        TIM_PrescalerConfig(TIM4,1000,TIM_PSCReloadMode_Immediate);   //PrescalerValue
       
        //初始化TIM4 Channel2 PWM模式         
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
        TIM_OC4Init(TIM2, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2

        TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);  //使能TIM3在CCR2上的预装载寄存器
   
         TIM_ARRPreloadConfig(TIM2,ENABLE);//ARPE使能
        TIM_Cmd(TIM2, ENABLE);  //使能TIM3
       
//        TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断
                //中断优先级NVIC设置
        NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  //TIM3中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
        NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器
}


这一句很关键,         TIM_ARRPreloadConfig(TIM2,ENABLE);//ARPE使能 ,加上就能连续播放了。不加会出现楼主反映的故障。
回复

使用道具 举报

0

主题

7

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
476
金钱
476
注册时间
2016-11-20
在线时间
78 小时
发表于 2019-10-24 19:29:43 | 显示全部楼层
本帖最后由 林海原 于 2020-11-2 22:43 编辑
wqc1341131003 发表于 2019-6-5 13:37
你好,我下了你这个文件,在51上打开,但是程序不能下载,蜂鸣器也没有响,代码里好像没有beep,这个怎么 ...

正常安装了MDK5.23打开程序,编译之后,下载进去战舰的板子里就可以了,你说的beep是蜂鸣器引脚的配置吗?这个配置在Hardware文件夹下的timer.c文件里。我这个是在自己的战舰板子上验证过的。
淘宝店铺--字节智控
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
8
金钱
8
注册时间
2019-12-30
在线时间
2 小时
发表于 2020-1-5 23:27:58 | 显示全部楼层
割风少年 发表于 2016-7-28 09:10
**** 作者被禁止或删除 内容自动屏蔽 ****

怎么做的啊
回复

使用道具 举报

1

主题

8

帖子

0

精华

初级会员

Rank: 2

积分
71
金钱
71
注册时间
2019-12-26
在线时间
21 小时
发表于 2020-1-18 22:38:05 | 显示全部楼层
wqc1341131003 发表于 2019-6-5 13:37
你好,我下了你这个文件,在51上打开,但是程序不能下载,蜂鸣器也没有响,代码里好像没有beep,这个怎么 ...

要下载到stm32战舰板或者精英版才行
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
2
金钱
2
注册时间
2020-7-2
在线时间
0 小时
发表于 2020-7-2 16:11:36 | 显示全部楼层
wqc1341131003 发表于 2019-6-5 13:37
你好,我下了你这个文件,在51上打开,但是程序不能下载,蜂鸣器也没有响,代码里好像没有beep,这个怎么 ...

我也是
回复

使用道具 举报

1

主题

9

帖子

0

精华

新手上路

积分
35
金钱
35
注册时间
2021-3-17
在线时间
8 小时
发表于 2021-3-30 16:18:00 | 显示全部楼层
pwm.h的头文件能分享一下么
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-28 07:23

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表