按键或者串口驱动蜂鸣器播放编制音乐.docx

上传人:b****6 文档编号:7448944 上传时间:2023-05-11 格式:DOCX 页数:16 大小:302.71KB
下载 相关 举报
按键或者串口驱动蜂鸣器播放编制音乐.docx_第1页
第1页 / 共16页
按键或者串口驱动蜂鸣器播放编制音乐.docx_第2页
第2页 / 共16页
按键或者串口驱动蜂鸣器播放编制音乐.docx_第3页
第3页 / 共16页
按键或者串口驱动蜂鸣器播放编制音乐.docx_第4页
第4页 / 共16页
按键或者串口驱动蜂鸣器播放编制音乐.docx_第5页
第5页 / 共16页
按键或者串口驱动蜂鸣器播放编制音乐.docx_第6页
第6页 / 共16页
按键或者串口驱动蜂鸣器播放编制音乐.docx_第7页
第7页 / 共16页
按键或者串口驱动蜂鸣器播放编制音乐.docx_第8页
第8页 / 共16页
按键或者串口驱动蜂鸣器播放编制音乐.docx_第9页
第9页 / 共16页
按键或者串口驱动蜂鸣器播放编制音乐.docx_第10页
第10页 / 共16页
按键或者串口驱动蜂鸣器播放编制音乐.docx_第11页
第11页 / 共16页
按键或者串口驱动蜂鸣器播放编制音乐.docx_第12页
第12页 / 共16页
按键或者串口驱动蜂鸣器播放编制音乐.docx_第13页
第13页 / 共16页
按键或者串口驱动蜂鸣器播放编制音乐.docx_第14页
第14页 / 共16页
按键或者串口驱动蜂鸣器播放编制音乐.docx_第15页
第15页 / 共16页
按键或者串口驱动蜂鸣器播放编制音乐.docx_第16页
第16页 / 共16页
亲,该文档总共16页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

按键或者串口驱动蜂鸣器播放编制音乐.docx

《按键或者串口驱动蜂鸣器播放编制音乐.docx》由会员分享,可在线阅读,更多相关《按键或者串口驱动蜂鸣器播放编制音乐.docx(16页珍藏版)》请在冰点文库上搜索。

按键或者串口驱动蜂鸣器播放编制音乐.docx

按键或者串口驱动蜂鸣器播放编制音乐

《微机接口与应用课程设计》

结题报告

按键或者串口驱动蜂鸣器播放编制音乐

1.项目简介

本设计是在Linux系统下以ARMS3C2440芯片的电路为基础,利用开发板上的蜂鸣器,通过软件编程对蜂鸣器进行发音频率、时间等的控制,进而利用按键或者串口驱动蜂鸣器来播放音乐。

本设计播放的为编制音乐,即对音乐先进行解码后再播放。

2.系统软、硬件结构设计

系统通过开发板上相应的定时器,产生不同的频率信号,驱动蜂鸣器发出不同的音频信号。

通过按键或键盘输入,选择播放不同的音乐。

整体设计框架如图1所示。

蜂鸣器播放编制音乐

图1:

系统整体设计

2.1系统硬件组成

本设计利用KDLAB-I型微机原理与接口技术实验装置ARM部分,由核心板、主板、底板共同构成。

其中蜂鸣器的位置如图2所示:

图2:

ARMS3C2440开发板

蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。

压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、阻抗匹配器及共鸣箱、外壳等组成。

多谐振荡器由晶体管或集成电路构成。

当接通电源后,多谐振荡器起振,输出1.5-2.5kHZ的音频信号,阻抗匹配器推动压电蜂鸣片发声。

电磁式蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片及外壳等组成。

接通电源后,振荡器产生的音频信号电流通过电磁线圈,使电磁线圈产生磁场。

振动膜片在电磁线圈和磁铁的相互作用下,周期性的振动发声。

本实验开发板使用的蜂鸣器为电磁式蜂鸣器。

其中主板上的蜂鸣器是通过PWM来控制的,原理图如图3所示。

图3:

蜂鸣器原理图

蜂鸣器是通过GPB0IO口使用PWM信号来驱动工作的,其中GPB0可通过软件设置为PWM输出。

PWM即脉冲宽度调制,是靠改变脉冲宽度来控制输出电压,通过改变周期来控制其输出频率。

由S3C2440手册可知,S3C2440内部有5个16位定时器,定时器0、1、2、3都带有脉冲宽度调制功能,定时器0、1共享一个时钟分频器,定时器2、3、4共享一个时钟分频器,这两个时钟分频器都能产生5种不同的分频信号值,即1/2、1/4、1/8、1/16和TCLK。

每个定时器模块从时钟分频器接收自己的时钟信号,其分频器从相应的预分频器接收时钟。

预标定器是可以编程且根据装载的值来分频PCLK的。

改变定时器中的分频器值即可产生不同的频率,因此PWM可利用芯片内部的定时器电路很方便产生。

2.2系统软件组成

程序的开发是在LinuxFedora9系统的arm-linux-gcc-4.3.2编译环境进行的,主要包括音乐播放部分和键盘控制部分。

软件整体设计思路如图4所示。

图4:

系统整体设计

2.2.1音乐播放软件设计

要利用蜂鸣器播放出音乐,必须知道音乐构成中的音调和相应的节拍。

一首乐曲是由很多音符组成的,将每个音符中包含的音调和节拍信息进行编码,作用于蜂鸣器上即可产生动听的音乐。

乐曲简谱中1、2、3、4、5、6、7,即DO、RE、MI、FA、SO、LA、SI,不同的低音、中音、高音对应的频率如表1所示:

表1:

不同音调对应的频率表

低音

频率

中音

频率

高音

频率

Do

262

Do

523

Do

1046

Re

294

Re

587

Re

1175

Mi

330

Mi

659

Mi

1318

Fa

349

Fa

698

Fa

1397

So

392

So

784

So

1568

La

440

La

880

La

1760

Si

494

Si

988

Si

1976

利用数组将对应的高低频率存储下来,

intfreq[]={262,294,330,349,392,440,494,523,587,659,698,784,880,988,1046,1175,1318,1397,1568,1760,1976},则当使用某一音调时调用相应数组中的元素即可。

将一首歌的简谱中的音调和节拍信息按照一个音符三个数字进行编码,其中第一位代表DO、RE、MI、FA、SO、LA、SI不同的音调,第二位代表低、中、高音,第三位代表半拍数。

如1,1,2代表2个半拍的低音Do,3,2,3代表3个半拍的中音Mi,7,3,4代表4个半拍的高音Si。

则利用该编码方式则可将一首歌如《新年好》编码如下,歌曲以音符0,0,0代表结束。

doublemusic[]={1,2,1,1,2,1,1,2,2,5,1,5,3,2,1,3,2,1,3,2,2,1,2,5,1,2,1,3,2,1,5,2,2,5,2,5,4,2,1,3,2,1,2,2,6,2,2,1,3,2,1,4,2,2,4,2,5,3,2,1,2,2,1,3,2,2,1,2,5,1,2,1,3,2,1,2,2,2,5,1,5,7,1,1,2,2,1,1,2,6,0,0,0};//歌曲《新年好》

播放音乐的主要程序如下:

doublebeats=0.5;//半拍的时间

inti=0;

intj=0;

while(music[i]>0)//未到歌曲结尾时循环

{

j=music[i]+(music[i+1]-1)*7-1;//计算音符对应频率数组中的位置

open_buzzer();//打开蜂鸣器

set_buzzer_freq(freq[j]);//设置蜂鸣器工作频率为对应音符的频率

delay(music[i+2]);//播放相应的节拍数

close_buzzer();//关闭蜂鸣器

delay(beats);//暂停一个半拍,准备下一个音符的播放

i=i+3;//下一个音符对应开始的位置

}

2.2.2键盘控制软件设计

键盘控制播放部分可以利用开发板上的按键进行播放控制,或者利用电脑的键盘通过串口传输驱动进行控制。

利用开发板上的按键进行控制主要是利用对按下键进行判断,若条件满足则播放相应的歌曲,核心程序如下:

charbuttons[6]={'0','0','0','0','0','0'};//初始键盘状态

for(;;){

charcurrent_buttons[6];//当前键盘状态

inti;

for(i=0;i

//循环判断哪个键被按下

{

if(buttons[i]!

=current_buttons[i])//某键状态变化时

{

buttons[i]=current_buttons[i];//改变键盘的状态值

if(i==0&&buttons[i]=='1')//当K2键按下时

{playmusic(music1);}//播放编曲一if(i==1&&buttons[i]=='1')//当K3键按下时

{playmusic(music2);}//播放编曲二if(i==2&&buttons[i]=='1')//当K4键按下时

{playmusic(music3);}//播放编曲三if(i>2){exit(0);}//当K5、K6、K7任意键按下时退出程序

}

}

利用串口驱动进行控制时,首先将系统和开发板进行串口连接,主要是利用条件满足时,进行串口传输控制播放相应的编曲,核心程序如下:

while

(1)

{

intkey;

key=getch();//获取键盘上输入的字符

switch(key){

case'1':

//当输入为‘1’时

playmusic(music1);//播放编曲一

break;

case'2':

//当输入为‘2’时

playmusic(music2);//播放编曲二

break;

case'3':

//当输入为‘3’时

playmusic(music3);//播放编曲三

break;

caseESC_KEY:

caseEOF:

stop_buzzer();//停止蜂鸣器

exit(0);//退出程序

default:

break;

}

3.系统功能及其实现

本系统设计的功能主要包括利用开发板上的按键或电脑键盘进行控制开发板蜂鸣器播放相应的编制音乐。

具体功能包括运行程序pwm_test后,按下开发板上按键K2播放《新年好》,按下开发板上按键K3播放《小苹果》,按下开发板上按键K3播放《梁祝》。

运行程序pwm后,用键盘输入1将播放《新年好》,输入2将播放《小苹果》,输入3将播放《梁祝》。

具体程序实现参见附录。

4.系统功能测试

系统设计完成后,运行程序测试时,按不同的键或输入不同的值将播放不同的乐曲,播放效果良好,歌曲很容易识别。

5.结语

通过本次课程设计,我对于Linux系统、ARMS3C2440、蜂鸣器、键盘等的工作原理有了很多的了解,初步掌握了Linux嵌入式系统开发的方法和技巧。

在实验过程中,出现过播放的音乐完全不像、按键测试没有出现预期结果、程序运行就会死机等很多问题,最终都调试解决了。

但在最后对程序优化时,欲将两个程序合成一个,遇到各种各样的问题,比如考虑用多线程解决两种按键可同时工作的问题,最终测试时发现测试一些输入输出时多线程能够正常工作,但将输入输出替换为播放音乐就始终无法正常工作,最终由于时间不够,暂停了合并的想法。

从中我学到了很多东西,掌握了处理问题和调试的方法,熟悉了系统开发的流程,对于音乐编码等也有了一定的了解。

参考文献

[1]KDLAB-I型微机原理与接口技术实验装置(ARM部分)实验指导书

[2]基于单片机的音乐盒设计,陕西理工学院毕业设计

[3]谭浩强.C语言程序设计(第二版)[M],北京:

清华大学出版社,1991.

 

附录:

程序源代码

1.按键测试程序pwm_test

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#definePWM_IOCTL_SET_FREQ1

#definePWM_IOCTL_STOP0

#defineESC_KEY0x1b

staticintfd=-1;

staticvoidclose_buzzer(void);

staticvoidopen_buzzer(void)

{

fd=open("/dev/pwm",0);

if(fd<0){

perror("openpwm_buzzerdevice");

exit

(1);

}

//anyfunctionexitcallwillstopthebuzzer

atexit(close_buzzer);

}

staticvoidclose_buzzer(void)//juhk

{

if(fd>=0){

ioctl(fd,PWM_IOCTL_STOP);

close(fd);

fd=-1;

}

}

#include

#include

#include

#include

#include

#include

#include

staticvoidset_buzzer_freq(intfreq)

{

//thisIOCTLcommandisthekeytosetfrequency

intret=ioctl(fd,PWM_IOCTL_SET_FREQ,freq);

if(ret<0){

perror("setthefrequencyofthebuzzer");

exit

(1);

}

}

staticvoidstop_buzzer(void)

{

intret=ioctl(fd,PWM_IOCTL_STOP);

if(ret<0){

perror("stopthebuzzer");

exit

(1);

}

}

voiddelay(doublen)

{

longi=2000000;

longii=1000000*n;

while(i>0)

{

while(ii>0)

{

ii--;

}

i--;

}

}

voidplaymusic(doublemusic[])

{

intfreq[]={262,294,330,349,392,440,494,523,587,659,698,784,880,988,1046,1175,1318,1397,1568,1760,1976};

doublebeats=0.5;

inti=0;

intj=0;

while(music[i]>0)

{

j=music[i]+(music[i+1]-1)*7-1;

open_buzzer();

set_buzzer_freq(freq[j]);

delay(music[i+2]);

close_buzzer();

delay(beats);

i=i+3;

}

}

intmain(intargc,char**argv)

{

doublemusic1[]={1,2,1,1,2,1,1,2,2,5,1,5,3,2,1,3,2,1,3,2,2,1,2,5,1,2,1,3,2,1,5,2,2,5,2,5,4,2,1,3,2,1,2,2,6,2,2,1,3,2,1,4,2,2,4,2,5,3,2,1,2,2,1,3,2,2,1,2,5,1,2,1,3,2,1,2,2,2,5,1,5,7,1,1,2,2,1,1,2,6,0,0,0};//xinninahao

doublemusic2[]={3,2,2,1,2,2,2,2,2,6,1,4,3,2,1,2,2,1,1,2,1,2,2,1,6,1,6,3,2,2,1,2,2,2,2,2,2,2,4,5,2,1,3,2,1,7,1,2,1,2,4,1,2,1,7,1,5,6,1,2,7,1,1,1,2,1,2,2,2,5,1,4,6,2,1,5,2,1,3,2,2,3,2,3,2,2,4,1,2,2,2,2,1,3,2,1,2,2,1,3,2,1,2,2,1,3,2,0.5,5,2,4.5,5,2,2,5,2,1,5,2,1,5,2,1,5,2,1,5,2,6,3,2,2,1,2,2,2,2,2,6,1,4,3,2,1,2,2,1,1,2,1,2,2,1,6,1,6,3,2,2,1,2,2,2,2,2,2,2,4,5,2,1,3,2,1,7,1,4,1,2,2,1,2,1,7,1,5,6,1,2,7,1,1,1,2,1,2,2,2,5,1,4,6,2,1,5,2,1,3,2,2,3,2,3,2,2,4,1,2,2,2,2,1,3,2,1,2,2,1,5,1,4,6,1,2,6,1,1,1,2,1,6,1,6,0,0,0};//xiaopingguo

doublemusic3[]={7,1,8,2,2,6,3,2,2,5,2,6,6,2,2,3,2,2,5,2,2,2,2,8,2,3,6,5,3,2,3,3,2,2,3,2,7,2,2,2,3,2,6,2,12,6,2,4,6,2,2,7,2,2,4,2,4,3,2,4,2,2,6,3,2,2,5,2,4,6,2,4,7,1,5,5,2,4,3,2,2,2,2,2,3,2,2,5,2,2,2,2,12,7,2,6,2,3,2,4,2,2,6,2,4,3,2,2,5,2,2,2,2,10,7,1,3,2,2,1,7,1,4,2,2,3,3,2,1,4,2,2,6,2,2,3,2,10,2,2,2,3,2,2,5,2,6,6,2,2,2,3,4,7,2,4,6,2,4,7,2,2,6,2,2,5,2,4,3,2,2,2,2,2,7,1,9,5,2,9,3,2,3,5,2,3,3,2,2,2,2,2,7,1,2,2,2,2,3,2,2,5,2,2,2,2,16,0,0,0};//liangzhu

intbuttons_fd;

charbuttons[6]={'0','0','0','0','0','0'};

buttons_fd=open("/dev/buttons",0);

if(buttons_fd<0){

perror("opendevicebuttons");

exit

(1);

}

for(;;){

charcurrent_buttons[6];

inti;

if(read(buttons_fd,current_buttons,sizeofcurrent_buttons)!

=sizeofcurrent_buttons)

{

perror("readbuttons:

");

exit

(1);

}

for(i=0;i

if(buttons[i]!

=current_buttons[i]){

buttons[i]=current_buttons[i];

if(i==0&&buttons[i]=='1')

{playmusic(music1);}

if(i==1&&buttons[i]=='1')

{playmusic(music2);}

if(i==2&&buttons[i]=='1')

{playmusic(music3);}

if(i>2){exit(0);}

}

}

}

close(buttons_fd);

return0;

exit(0);

}

2.键盘输入测试程序pwm

#include

#include

#include

#include

#definePWM_IOCTL_SET_FREQ1

#definePWM_IOCTL_STOP0

#defineESC_KEY0x1b

staticintgetch(void)

{

structtermiosoldt,newt;

intch;

if(!

isatty(STDIN_FILENO)){

fprintf(stderr,"thisproblemshouldberunataterminal\n");

exit

(1);

}

//saveterminalsetting

if(tcgetattr(STDIN_FILENO,&oldt)<0){

perror("savetheterminalsetting");

exit

(1);

}

//setterminalasneed

newt=oldt;

newt.c_lflag&=~(ICANON|ECHO);

if(tcsetattr(STDIN_FILENO,TCSANOW,&newt)<0){

perror("setterminal");

exit

(1);

}

ch=getchar();

//restoretermialsetting

if(tcsetattr(STDIN_FILENO,TCSANOW,&oldt)<0){

perror("restorethetermialsetting");

exit

(1);

}

returnch;

}

staticintfd=-1;

staticvoidclose_buzzer(void);

staticvoidopen_buzzer(void)

{

fd=open("/dev/pwm",0);

if(fd<0){

perror("openpwm_buzzerdevice");

exit

(1);

}

//anyfunctionexitcallwillstopthebuzzer

atexit(close_buzzer);

}

staticvoidclose_buzzer(void)

{

if(fd>=0){

ioctl(fd,PWM_IOCTL_STOP);

close(fd);

fd=-1;

}

}

staticvoidset_buzzer_freq(intfreq)

{

//thisIOCTLcommandisthekeytosetfrequency

intret=ioctl(fd,PWM_IOCTL_SET_FREQ,freq);

if(ret<0){

perror("setthefrequencyofthebuzzer");

exit

(1);

}

}

staticvoidstop_buzzer(void)

{

intret=ioctl(fd,PWM_IOCTL_STOP);

if(ret<0){

perror("stopthebuzzer");

exit

(1);

}

}

voiddelay(doublen)

{

longi=2000000;

longii=1000000*n;

while(i>0)

{

while(ii>0)

{

ii--;

}

i--;

}

}

voidplaymusic(doublemusic[])

{

intfreq[]={262,294,330,349,392,440,494,523,587,659,698,784,880,988,1046,1175,1318,1397

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 人文社科 > 法律资料

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2