STM32F103通用定时器PWM应用例程蜂鸣器演奏乐曲解析.docx
- 文档编号:12304510
- 上传时间:2023-04-18
- 格式:DOCX
- 页数:24
- 大小:39.27KB
STM32F103通用定时器PWM应用例程蜂鸣器演奏乐曲解析.docx
《STM32F103通用定时器PWM应用例程蜂鸣器演奏乐曲解析.docx》由会员分享,可在线阅读,更多相关《STM32F103通用定时器PWM应用例程蜂鸣器演奏乐曲解析.docx(24页珍藏版)》请在冰豆网上搜索。
STM32F103通用定时器PWM应用例程蜂鸣器演奏乐曲解析
STM32F103通用定时器PWM应用例程:
蜂鸣器演奏乐曲
一.说明:
本例程是将流明LM3SLib_Timer.pdf文档中的例程9及例程10(PWM应用:
蜂鸣器演奏乐曲),移植到STM32F103上。
二.流明LM3SLib_Timer.pdf例程9及例程10的拷贝:
例程9.TimerPWM应用:
蜂鸣器发声
如图1.1所示,为EasyARM1138开发板上的蜂鸣器驱动电路。
蜂鸣器类型是交流蜂鸣器,也称无源蜂鸣器,需要输入一列方波才能鸣响,发声频率等于驱动方波的频率。
图1.1蜂鸣器驱动电路
程序清单1.9是Timer模块16位PWM模式的一个应用,可以驱动交流蜂鸣器发声,运行后蜂鸣器以不同的频率叫两声。
其中"buzzer.h"和"buzzer.c"是蜂鸣器的驱动程序,仅有3个驱动函数,用起来很简捷。
程序清单1.9TimerPWM应用:
蜂鸣器发声
文件:
main.c
#include"systemInit.h"
#include"buzzer.h"
//主函数(程序入口)
intmain(void)
{
jtagWait();//防止JTAG失效,重要!
clockInit();//时钟初始化:
晶振,6MHz
buzzerInit();//蜂鸣器初始化
buzzerSound(1500);//蜂鸣器发出1500Hz声音
SysCtlDelay(400*(TheSysClock/3000));//延时约400ms
buzzerSound(2000);//蜂鸣器发出2000Hz声音
SysCtlDelay(800*(TheSysClock/3000));//延时约800ms
buzzerQuiet();//蜂鸣器静音
for(;;)
{
}
}
文件:
buzzer.h
#ifndef__BUZZER_H__
#define__BUZZER_H__
//蜂鸣器初始化
externvoidbuzzerInit(void);
//蜂鸣器发出指定频率的声音
externvoidbuzzerSound(unsignedshortusFreq);
//蜂鸣器停止发声
externvoidbuzzerQuiet(void);
#endif//__BUZZER_H__
文件:
buzzer.c
#include"buzzer.h"
#include
#include
#include
#include
#include
#definePART_LM3S1138
#include
#defineSysCtlPeriEnableSysCtlPeripheralEnable
#defineGPIOPinTypeOutGPIOPinTypeGPIOOutput
//声明全局的系统时钟变量
externunsignedlongTheSysClock;
//蜂鸣器初始化
voidbuzzerInit(void)
{
SysCtlPeriEnable(SYSCTL_PERIPH_TIMER1);//使能TIMER1模块
SysCtlPeriEnable(CCP3_PERIPH);//使能CCP3所在的GPIO端口
GPIOPinTypeTimer(CCP3_PORT,CCP3_PIN);//设置相关管脚为Timer功能
TimerConfigure(TIMER1_BASE,TIMER_CFG_16_BIT_PAIR|//配置TimerB为16位PWM
TIMER_CFG_B_PWM);
}
//蜂鸣器发出指定频率的声音
//usFreq是发声频率,取值(系统时钟/65536)+1~20000,单位:
Hz
voidbuzzerSound(unsignedshortusFreq)
{
unsignedlongulVal;
if((usFreq<=TheSysClock/65536UL)||(usFreq>20000))
{
buzzerQuiet();
}
else
{
GPIOPinTypeTimer(CCP3_PORT,CCP3_PIN);//设置相关管脚为Timer功能
ulVal=TheSysClock/usFreq;
TimerLoadSet(TIMER1_BASE,TIMER_B,ulVal);//设置TimerB初值
TimerMatchSet(TIMER1_BASE,TIMER_B,ulVal/2);//设置TimerB匹配值
TimerEnable(TIMER1_BASE,TIMER_B);//使能TimerB计数
}
}
//蜂鸣器停止发声
voidbuzzerQuiet(void)
{
TimerDisable(TIMER1_BASE,TIMER_B);//禁止TimerB计数
GPIOPinTypeOut(CCP3_PORT,CCP3_PIN);//配置CCP3管脚为GPIO输出
GPIOPinWrite(CCP3_PORT,CCP3_PIN,0x00);//使CCP3管脚输出低电平
}
例程10.TimerPWM应用:
蜂鸣器演奏乐曲
程序清单1.10是Timer模块16位PWM模式的一个应用,能驱动交流蜂鸣器演奏一首动听的乐曲《化蝶》(乐谱参见图1.2)。
"music.h"和"music.c"是演奏乐曲的驱动程序。
图1.2乐谱《化蝶》
简谱是大众化的音乐记谱方式,比较容易理解和掌握。
我们可以把一首乐谱(score)看成是由若干个基本的音符(note)单元组成。
一个音符由音名和时值组成。
音名就是低音、中音、高音的1234567(唱作doremifasollasi),其本质是音符的发声频率。
在头文件"music.h"里,用L1~L7、M1~M7、H1~H7定义了低音、中音、高音所对应的发声频率。
时值是音符的发声时间长短,有全音符、二分音符、四分音符⋯⋯等等。
音符可以后缀一个“符点”,表示时值增加1/2,特殊地,二分音符加符点时用“-”代替圆点。
参见表1.26的描述。
表1.26常见简谱音符示例
音符
名称
相对时值
5―――
全音符
T
5-
二分音符
T/2
5
四分音符
T/4
5
八分音符
T/8
5
十六分音符
T/16
5――
符点二分音符
T/2+T/4
5.
符点四分音符
T/4+T/8
5.
符点八分音符
T/8+T/16
在头文件"music.h"里定义有一个音符结构体tNote,有两个数据成员:
音名mName和时值mTime。
在C文件"music.c"里定义有一个tNote型常量数表MyScore[],用来保存实际乐谱转换成tNote格式的数据。
有了上述一点点乐谱基础知识,我们就可以很方便地编辑这个数表了。
比如音符“3”转换为“{M3,T/4}”,音符“3.”转换为“{M3,T/4+T/8}”,等等。
在"music.c"里,已经在数表MyScore[]里给出了乐谱《化蝶》开头一部分音符转换结果,其余部分请感兴趣的读者补充完整。
程序清单1.10TimerPWM应用:
蜂鸣器演奏乐曲
文件:
main.c
#include"systemInit.h"
#include"buzzer.h"
#include"music.h"
//主函数(程序入口)
intmain(void)
{
jtagWait();//防止JTAG失效,重要!
clockInit();//时钟初始化:
晶振,6MHz
buzzerInit();//蜂鸣器初始化
for(;;)
{
musicPlay();
SysCtlDelay(4000*(TheSysClock/3000));
}
}
文件:
music.h
#ifndef__MUSIC_H__
#define__MUSIC_H__
//定义低音音名(数值单位:
Hz)
#defineL1262//c
#defineL2294//d
#defineL3330//e
#defineL4349//f
#defineL5392//g
#defineL6440//a1
#defineL7494//b1
//定义中音音名
#defineM1523//c1
#defineM2587//d1
#defineM3659//e1
#defineM4698//f1
#defineM5784//g1
#defineM6880//a2
#defineM7988//b2
//定义高音音名
#defineH11047//c2
#defineH21175//d2
#defineH31319//e2
#defineH41397//f2
#defineH51568//g2
#defineH61760//a3
#defineH71976//b3
//定义时值单位,决定演奏速度(数值单位:
ms)
#defineT3600
//定义音符结构
typedefstruct
{
shortmName;//音名:
取值L1~L7、M1~M7、H1~H7分别表示低音、中音、高音的
//1234567,取值0表示休止符
shortmTime;//时值:
取值T、T/2、T/4、T/8、T/16、T/32分别表示全音符、
//二分音符、四分音符、八分音符⋯,取值0表示演奏结束
}tNote;
//演奏乐曲
externvoidmusicPlay(void);
#endif//__MUSIC_H__
文件:
music.c
#include"music.h"
#include"buzzer.h"
#include"systemInit.h"
//定义乐曲:
《化蝶》(梁祝)
consttNoteMyScore[]=
{
{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},
{M2,T/2},
//省略后续乐曲数据,请感兴趣的读者补充完整
{0,0}//结束
};
//演奏乐曲
voidmusicPlay(void)
{
shorti=0;
for(;;)
{
if(MyScore[i].mTime==0)break;
buzzerSound(MyScore[i].mName);
SysCtlDelay(MyScore[i].mTime*(TheSysClock/3000));
i++;
buzzerQuiet();
SysCtlDelay(10*(TheSysClock/3000));
}
}
三.移植到STM32F103上:
Timer3部分重映射TIM3_CH2->PB5:
PB5作为PWM输出。
//定义低音音名(数值单位:
Hz)
#defineL1262
#defineL2294
#defineL3330
#defineL4349
#defineL5392
#defineL6440
#defineL7494
//定义中音音名
#defineM1523
#defineM2587
#defineM3659
#defineM4698
#defineM5784
#defineM6880
#defineM7988
//定义高音音名
#defineH11047
#defineH21175
#defineH31319
#defineH41397
#defineH51568
#defineH61760
#defineH71976
//定义时值单位,决定演奏速度(数值单位:
ms)
#defineTT2000
typedefstruct
{
shortmName;//音名:
取值L1~L7、M1~M7、H1~H7分别表示低音、中音、高音的1234567,取值0表示休止符
shortmTime;//时值:
取值T、T/2、T/4、T/8、T/16、T/32分别表示全音符、二分音符、四分音符、八分音符.,取值0表示演奏结束
}tNote;
intmain(void)
{
delay_init();//延时函数初始化
NVIC_Configuration();//设置NVIC中断分组2:
2位抢占优先级,2位响应优先级
TIM3_PWM_Init(14399,10);//分频。
PWM频率=72000/14400/11(Khz)
for(;;)
{
musicPlay();
delay_ms(1500);
delay_ms(1500);
}
}
//PWM输出初始化
//arr:
自动重装值
//psc:
时钟预分频数
voidTIM3_PWM_Init(u16arr,u16psc)
{
GPIO_InitTypeDefGPIO_InitStructure;
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
TIM_OCInitTypeDefTIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);//使能GPIO外设和AFIO复用功能模块时钟使能
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);//Timer3部分重映射TIM3_CH2->PB5
//设置该引脚为复用输出功能,输出TIM3CH2的PWM脉冲波形
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;//TIM_CH2
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Period=arr;//设置在下一个更新事件装入活动的自动重装载寄存器周期的值80K
TIM_TimeBaseStructure.TIM_Prescaler=psc;//设置用来作为TIMx时钟频率除数的预分频值不分频
TIM_TimeBaseStructure.TIM_ClockDivision=0;//设置时钟分割:
TDTS=Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//TIM向上计数模式
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);//根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM2;//选择定时器模式:
TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//比较输出使能
TIM_OCInitStructure.TIM_Pulse=0;//设置待装入捕获比较寄存器的脉冲值
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;//输出极性:
TIM输出比较极性低
TIM_OC2Init(TIM3,&TIM_OCInitStructure);//根据TIM_OCInitStruct中指定的参数初始化外设TIMx
TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);//使能TIMx在CCR2上的预装载寄存器
TIM_ARRPreloadConfig(TIM3,ENABLE);//使能TIMx在ARR上的预装载寄存器
TIM_Cmd(TIM3,ENABLE);//使能TIMx外设
}
//蜂鸣器停止发声
voidbuzzerQuiet(void)
{
GPIO_InitTypeDefGPIO_InitStructure;
TIM_Cmd(TIM3,DISABLE);//停止TIM3
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;//PB.5端口配置
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//IO口速度为50MHz
GPIO_Init(GPIOB,&GPIO_InitStructure);//根据设定参数初始化GPIOB.5
GPIO_ResetBits(GPIOB,GPIO_Pin_5);//PB.5输出低
}
/////////////////////////////////////////////////////////
//蜂鸣器发出指定频率的声音
//usFreq是发声频率,取值(系统时钟/65536)+1~20000,单位:
Hz
voidbuzzerSound(unsignedshortusFreq)
{
GPIO_InitTypeDefGPIO_InitStructure;
unsignedlongulVal;
if((usFreq<=8000000/65536UL)||(usFreq>20000))
{
buzzerQuiet();//蜂鸣器静音
}
else
{
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);//Timer3部分重映射TIM3_CH2->PB5
//设置该引脚为复用输出功能,输出TIM3CH2的PWM脉冲波形GPIOB.5
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;//TIM_CH2
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);//初始化GPIO
ulVal=8000000/usFreq;
TIM3->ARR=ulVal;//设置自动重装载寄存器周期的值(音调)
TIM_SetCompare2(TIM3,ulVal/2);//音量
TIM_Cmd(TIM3,ENABLE);//启动TIM3
}
}
//演奏乐曲
voidmusicPlay(void)
{
u8i=0;
while
(1)
{
if(MyScore[i].mTime==0)break;
buzzerSound(MyScore[i].mName);
delay_ms(MyScore[i].mTime);
i++;
buzzerQuiet();//蜂鸣器静音
delay_ms(10);//10ms
}
}
//定义乐曲:
刘德华《恭喜发财》
consttNoteMyScore[]=
{
{L3,TT/8},{M6,TT/4},{M5,TT/4},{M6,TT/4},{M5,TT/8},{M3,TT/8},{M3,TT/4},{L3,TT/8},{M6,TT/4},{M5,TT/4},{M6,TT/4},{M5,TT/8},{M6,TT/8},{M6,TT/2},{M3,TT/8},{M2,TT/8+TT/16},{M3,TT/16},{M2,TT/8},
{M1,TT/8},{L6,TT/4},{M3,TT/8},{M2,TT/8+TT/16},{M3,TT/16},{M2,TT/8},{M1,TT/8},{M2,TT/4},{M2,TT/8+TT/16},{M1,TT/8},{M1,TT/4},{M2,TT/4},{M3,TT/4},{M5,TT/4},{M6,TT},{M6,TT/8+TT/16},{M5,TT/16},
{M3,TT/8},{M5,TT/8},{M6,TT/4},//恭喜你发财。
。
。
礼多人不怪
{L3,TT/8},{L6,TT/4},{L6,TT/8},{L5,TT/8},{L6,TT/8},{L3,TT/8},{L3,TT/8},{L5,TT/8},{L6,TT/8},{M1,TT/8},{L6,TT/8},{L5,TT/8},{L6,TT/4},{L3,TT/8},{L5,TT/8},{M1,TT/4},{M1,TT/8},{M1,TT/8},{M2,TT/8},
{M2,TT/8},{M1,TT/8},{M2,TT/8},{M3,TT/2},{L3,TT/8},{M2,TT/4},{M2,TT/8},{M1,TT/8},{M2,TT/8},{L6,TT/8},{L6,TT/8},{M1,TT/8},{M2,TT/8},{M3,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- STM32F103 通用 定时器 PWM 应用 例程 蜂鸣器 演奏 乐曲 解析