前面我们测试了PWM和定时器,基于此我们可以进行一些有意思的小Demo开发了。这一篇我们使用PWM驱动蜂鸣器演奏音乐。
使用PWM控制蜂鸣器发声,
频率对应声音的音调,修改PWM的频率即改变了声音的音调;
幅度对应声音的响度,修改PWM的占空比即改变了声音的大小。
以国际标准音A-la-440HZ为准:
do的频率为261.6HZ,
re的频率为293.6HZ,
mi的频率为329.6HZ,
fa的频率为349.2HZ,
sol的频率为392HZ,
la的频率为440HZ,
si的频率为493.8HZ。
根据计算相邻音阶的比值为1.12,即高音频率是相邻低音频率的2的1/12次方倍,比如do的频率为261.6HZ,则比它高半音的re的频率为261*2^(1/12)=293.6HZ。
这样类比下来,一个八度的音,这样一直乘下来,所得的结果刚好是2倍。
根据以上原理我们就可以进行do-re-mi的演奏了,结合演奏时间的控制,声音大小的控制,以及休止时间的控制,即可实现音乐的播放。
所以我们需要将音乐乐谱转化为上面的可控元素,频率,占空比,播放时间。
先介绍下简谱
这里找首简单的音乐”两只老虎”
先看左上角的节拍说明:2/4拍子 4分音符一拍 每小节2拍
一分钟76拍。
先定义如下音阶和频率的对应关系
#define DO 523
#define RE 587
#define MI 659
#define FA 698
#define _SO 392
#define SO 784
#define LA 880
#define SI 987
#define NO 523
#define DUTY0 0
定义节拍时间
#define METERS 76ul // 拍数76 1分钟76拍 每拍60/76秒 2/4 4分音符一拍 每小节2拍
#define NOTE_4 (60000ul/METERS) // 先定一拍对应的音符 4分音符 x1000转化为单位mS
#define NOTE_8 (NOTE_4/2ul) // 8分音符 一个下划线
#define NOTE_16 (NOTE_8/2ul) // 16分音符 二个下划线
定义音阶表,对应频率
const uint16_t beepfrep[] =
{
DO,RE,MI,DO,
DO,RE,MI,DO,
MI,FA,SO,NO,
MI,FA,SO,NO,
SO,LA,SO,FA,MI,DO,
SO,LA,SO,FA,MI,DO,
DO,_SO,DO,NO,
DO,_SO,DO,NO
};
定义声音大小表,对应占空比
const uint16_t beepduty[] =
{ 40,40,40,40,
40,40,40,40,
40,40,40,DUTY0,
40,40,40,DUTY0,
40,40,40,40,40,40,
40,40,40,40,40,40,
40,40,40,DUTY0,
40,40,40,DUTY0,
};
定义节拍表,对应每个音阶的演奏时间
const uint32_t beeptime[]=
{
NOTE_8,NOTE_8,NOTE_8,NOTE_8,
NOTE_8,NOTE_8,NOTE_8,NOTE_8,
NOTE_8,NOTE_8,NOTE_8,NOTE_8,
NOTE_8,NOTE_8,NOTE_8,NOTE_8,
NOTE_16,NOTE_16,NOTE_16,NOTE_16,NOTE_8,NOTE_8,
NOTE_16,NOTE_16,NOTE_16,NOTE_16,NOTE_8,NOTE_8,
NOTE_8,NOTE_8,NOTE_8,NOTE_16,
NOTE_8,NOTE_8,NOTE_8,NOTE_16,
};
实现延时函数,这里没有考虑溢出
void mdelay(uint32_t t)
{
uint32_t ct = g_time_u32;
while((g_time_u32 - ct) < t);
}
实现演奏函数
void beep_play_music(const uint16_t* freq,const uint16_t* duty, const uint32_t* time, uint16_t len)
{
uint16_t i = 0;
for(i=0; i< len; i++)
{
pwm_setduty(freq, duty);
mdelay(time);
}
}
beep_play_music(beepfrep, beepduty, beeptime, sizeof(beepfrep)/sizeof(beepfrep[0]));
使用蜂鸣器接到P11_1,可以听到播放效果
示波器可以但看到动态变化的频率
以上介绍了PWM播放音乐的原理,进行了PWM控制蜂鸣器播放音乐的测试。后面再结合电容触摸,使用旋电容触摸作为输入,控制蜂鸣器输出不同的音乐片段,模拟”打碟器”,动次打次的Demo。