1、按键或者串口驱动蜂鸣器播放编制音乐微机接口与应用课程设计结题报告按键或者串口驱动蜂鸣器播放编制音乐1. 项目简介本设计是在Linux系统下以ARM S3C2440芯片的电路为基础,利用开发板上的蜂鸣器,通过软件编程对蜂鸣器进行发音频率、时间等的控制,进而利用按键或者串口驱动蜂鸣器来播放音乐。本设计播放的为编制音乐,即对音乐先进行解码后再播放。2. 系统软、硬件结构设计系统通过开发板上相应的定时器,产生不同的频率信号,驱动蜂鸣器发出不同的音频信号。通过按键或键盘输入,选择播放不同的音乐。整体设计框架如图1所示。蜂鸣器播放编制音乐图1:系统整体设计2.1 系统硬件组成本设计利用KDLAB-I型微机
2、原理与接口技术实验装置ARM部分,由核心板、主板、底板共同构成。其中蜂鸣器的位置如图2所示:图2:ARM S3C2440开发板蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、阻抗匹配器及共鸣箱、外壳等组成。多谐振荡器由晶体管或集成电路构成。当接通电源后,多谐振荡器起振,输出1.5-2.5kHZ的音频信号,阻抗匹配器推动压电蜂鸣片发声。电磁式蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片及外壳等组成。接通电源后,振荡器产生的音频信号电流通过电磁线圈,使电磁线圈产生磁场。振动膜片在电磁线圈和磁铁的相互作用下,周期性的振动发声。本实验开发板使用的蜂鸣器为电磁式蜂
3、鸣器。其中主板上的蜂鸣器是通过PWM来控制的,原理图如图3所示。图3:蜂鸣器原理图蜂鸣器是通过GPB0 IO口使用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。每个定时器模块从时钟分频器接收自己的时钟信号,其分频器从相应的预分
4、频器接收时钟。预标定器是可以编程且根据装载的值来分频PCLK的。改变定时器中的分频器值即可产生不同的频率,因此PWM可利用芯片内部的定时器电路很方便产生。2.2 系统软件组成程序的开发是在Linux Fedora9系统的arm-linux-gcc-4.3.2编译环境进行的,主要包括音乐播放部分和键盘控制部分。软件整体设计思路如图4所示。图4:系统整体设计2.2.1 音乐播放软件设计要利用蜂鸣器播放出音乐,必须知道音乐构成中的音调和相应的节拍。一首乐曲是由很多音符组成的,将每个音符中包含的音调和节拍信息进行编码,作用于蜂鸣器上即可产生动听的音乐。乐曲简谱中1、2、3、4、5、6、7,即DO、RE
5、、MI、FA、SO、LA、SI,不同的低音、中音、高音对应的频率如表1所示:表1:不同音调对应的频率表低音频率中音频率高音频率Do262Do523Do1046Re294Re587Re1175Mi330Mi659Mi1318Fa349Fa698Fa1397So392So784So1568La440La880La1760Si494Si988Si1976利用数组将对应的高低频率存储下来,int freq=262,294,330,349,392,440,494, 523,587,659,698,784,880,988, 1046,1175,1318,1397,1568,1760,1976,则当使用某一
6、音调时调用相应数组中的元素即可。将一首歌的简谱中的音调和节拍信息按照一个音符三个数字进行编码,其中第一位代表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代表结束。double music=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
7、, 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;/歌曲新年好播放音乐的主要程序如下:double beats=0.5; /半拍的时间int i=0;int j=0;while(musici0) /未到歌曲结尾时循环 j=musici+(musici+1-1)*7-1; /计算音符对应频率数组中的位置 open_buzzer(); /打开蜂鸣器 set_buzzer_freq(freqj); /设置蜂鸣器工
8、作频率为对应音符的频率 delay(musici+2); /播放相应的节拍数 close_buzzer(); /关闭蜂鸣器 delay(beats); /暂停一个半拍,准备下一个音符的播放 i=i+3; /下一个音符对应开始的位置2.2.2 键盘控制软件设计键盘控制播放部分可以利用开发板上的按键进行播放控制,或者利用电脑的键盘通过串口传输驱动进行控制。利用开发板上的按键进行控制主要是利用对按下键进行判断,若条件满足则播放相应的歌曲,核心程序如下: char buttons6 = 0, 0, 0, 0, 0, 0;/初始键盘状态for (;) char current_buttons6;/当前键
9、盘状态int i;for (i = 0; i 2)exit(0);/当K5、K6、K7任意键按下时退出程序 利用串口驱动进行控制时,首先将系统和开发板进行串口连接,主要是利用条件满足时,进行串口传输控制播放相应的编曲,核心程序如下: while( 1 ) int key; key = getch();/获取键盘上输入的字符 switch(key) case 1:/当输入为1时 playmusic(music1);/播放编曲一 break; case 2:/当输入为2时 playmusic(music2);/播放编曲二 break; case 3:/当输入为3时 playmusic(music3
10、);/播放编曲三 break; case ESC_KEY: case EOF: stop_buzzer();/停止蜂鸣器 exit(0);/退出程序 default: break; 3. 系统功能及其实现本系统设计的功能主要包括利用开发板上的按键或电脑键盘进行控制开发板蜂鸣器播放相应的编制音乐。具体功能包括运行程序pwm_test后,按下开发板上按键K2播放新年好,按下开发板上按键K3播放小苹果,按下开发板上按键K3播放梁祝。运行程序pwm后,用键盘输入1将播放新年好,输入2将播放小苹果,输入3将播放梁祝。具体程序实现参见附录。4. 系统功能测试系统设计完成后,运行程序测试时,按不同的键或输入
11、不同的值将播放不同的乐曲,播放效果良好,歌曲很容易识别。5. 结语通过本次课程设计,我对于Linux系统、ARM S3C2440、蜂鸣器、键盘等的工作原理有了很多的了解,初步掌握了Linux嵌入式系统开发的方法和技巧。在实验过程中,出现过播放的音乐完全不像、按键测试没有出现预期结果、程序运行就会死机等很多问题,最终都调试解决了。但在最后对程序优化时,欲将两个程序合成一个,遇到各种各样的问题,比如考虑用多线程解决两种按键可同时工作的问题,最终测试时发现测试一些输入输出时多线程能够正常工作,但将输入输出替换为播放音乐就始终无法正常工作,最终由于时间不够,暂停了合并的想法。从中我学到了很多东西,掌握
12、了处理问题和调试的方法,熟悉了系统开发的流程,对于音乐编码等也有了一定的了解。参考文献1 KDLAB-I型 微机原理与接口技术实验装置(ARM部分)实验指导书2 基于单片机的音乐盒设计,陕西理工学院毕业设计3 谭浩强.C语言程序设计(第二版)M,北京:清华大学出版社,1991.附录:程序源代码1按键测试程序pwm_test#include #include #include #include #include #include #include #include #include #include #include #define PWM_IOCTL_SET_FREQ 1#define PWM
13、_IOCTL_STOP 0#define ESC_KEY 0x1bstatic int fd = -1;static void close_buzzer(void);static void open_buzzer(void) fd = open(/dev/pwm, 0); if (fd = 0) ioctl(fd, PWM_IOCTL_STOP); close(fd); fd = -1; #include #include #include #include #include #include #include static void set_buzzer_freq(int freq) / t
14、his IOCTL command is the key to set frequency int ret = ioctl(fd, PWM_IOCTL_SET_FREQ, freq); if(ret 0) perror(set the frequency of the buzzer); exit(1); static void stop_buzzer(void) int ret = ioctl(fd, PWM_IOCTL_STOP); if(ret 0) while(ii0) ii-; i-; void playmusic(double music)int freq=262,294,330,3
15、49,392,440,494, 523,587,659,698,784,880,988, 1046,1175,1318,1397,1568,1760,1976;double beats=0.5;int i=0;int j=0;while(musici0) j=musici+(musici+1-1)*7-1; open_buzzer(); set_buzzer_freq(freqj); delay(musici+2); close_buzzer(); delay(beats); i=i+3;int main(int argc, char *argv) double music1=1,2,1, 1
16、,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;/xinninahaodouble music2=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,
17、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,
18、 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;/xiaopingguodouble music3=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
19、,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
20、,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 int buttons_fd; char buttons6 = 0, 0, 0, 0, 0, 0; buttons_fd = open(/dev/buttons, 0); if (buttons_fd 0) perror(open device buttons); exit(1); for (;) char curre
21、nt_buttons6; int i; if (read(buttons_fd, current_buttons, sizeof current_buttons) != sizeof current_buttons) perror(read buttons:); exit(1); for (i = 0; i 2)exit(0); close(buttons_fd); return 0;exit(0);2键盘输入测试程序pwm#include #include #include #include #define PWM_IOCTL_SET_FREQ 1#define PWM_IOCTL_STOP
22、 0#define ESC_KEY 0x1bstatic int getch(void) struct termios oldt,newt; int ch; if (!isatty(STDIN_FILENO) fprintf(stderr, this problem should be run at a terminaln); exit(1); / save terminal setting if(tcgetattr(STDIN_FILENO, &oldt) 0) perror(save the terminal setting); exit(1); / set terminal as nee
23、d newt = oldt; newt.c_lflag &= ( ICANON | ECHO ); if(tcsetattr(STDIN_FILENO,TCSANOW, &newt) 0) perror(set terminal); exit(1); ch = getchar(); / restore termial setting if(tcsetattr(STDIN_FILENO,TCSANOW,&oldt) 0) perror(restore the termial setting); exit(1); return ch;static int fd = -1;static void c
24、lose_buzzer(void);static void open_buzzer(void) fd = open(/dev/pwm, 0); if (fd = 0) ioctl(fd, PWM_IOCTL_STOP); close(fd); fd = -1; static void set_buzzer_freq(int freq) / this IOCTL command is the key to set frequency int ret = ioctl(fd, PWM_IOCTL_SET_FREQ, freq); if(ret 0) perror(set the frequency of the buzzer); exit(1); static void stop_buzzer(void) int ret = ioctl(fd, PWM_IOCTL_STOP); if(ret 0) while(ii0) ii-; i-; void playmusic(double music)int freq=262,294,330,349,392,440,494, 523,587,659,698,784,880,988, 1046,1175,1318,1397
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2