单片机音乐播放实验报告.docx
- 文档编号:26227091
- 上传时间:2023-06-17
- 格式:DOCX
- 页数:18
- 大小:109.75KB
单片机音乐播放实验报告.docx
《单片机音乐播放实验报告.docx》由会员分享,可在线阅读,更多相关《单片机音乐播放实验报告.docx(18页珍藏版)》请在冰豆网上搜索。
单片机音乐播放实验报告
课程设计
课程名称微机原理与单片机技术实践
题目名称单片机制作与音乐播放
学生学院自动化学院
专业班级电子
(2)
学号
学生
指导教师学习
2013年5月24日
单片机制作与音乐播放
一、课程设计的容
1.用面包板焊一块PIC单片机最小系统,包括晶振,复位电路,按钮,LED灯。
2.自主添加新模块。
3.写程序驱动单片机工作。
二、课程设计的要求与数据
1.焊板所需原理图:
LED灯
蜂鸣器
复位
晶振
AD转换
按钮
2.音乐播放所需资料。
摘要:
16F877A单片机原理和控制理论来设计音乐盒的硬件电路,并利用16单片机语言进行程序设计。
通过控制单片机部的定时器来产生不同频率的方波,驱动喇叭发出不同音调的音乐,再利用延迟来控制发音时间的长短。
该程序通过把乐谱转化成相应的定时常数来驱动发音设备演奏出悦耳动听的音乐。
这种控制电路结构简单,可靠性高,应用性强;软件程序适应围广,对于不同的音乐只需要改变相应的定时常数即可。
音乐产生的方法:
一首音乐是许多不同的音阶组成的,而每个音阶对应着不同的频率,这样我们就可以利用不同的频率的组合,即可构成我们所想要的音乐了,当然对于单片机来产生不同的频率非常方便,我们可以利用单片机的定时/计数器T0来产生这样方波频率信号,因此,我们只要把一首歌曲的音阶对应频率关系弄正确即可。
现在以单片机12MHZ晶振为例,例出高中低音符与单片机计数T0相关的计数值如下表4.1所示:
表4.1 高中低音符与单片机计数T0相关的计数值
音符
对应的PR2值
音符
对应的PR2值
M_1
119
M_2
105
M_3
94
M_5
79
M_6
70
H_1
59
L_5
158
L_6
141
如表4.2所示:
音乐的音拍,一个节拍为单位(C调)
表4.2 音乐的音拍
曲调值
DELAY
曲调值
DELAY
调4/4
125ms
调4/4
62ms
调3/4
187ms
调3/4
94ms
调2/4
250ms
调2/4
125ms
对于不同的曲调我们也可以用单片机的另外一个定时/计数器来完成。
发音部分代码在程序中实现,靠单片机的一个管脚输出,考虑到声音可能不够大所以我们加入了功放电路,利用LM386来对声音信号进行放大。
音频输出信号由ADUOUT引出,信号可经功放电路LM386输出到扬声器或耳机。
三、课程设计应完成的工作
1.音乐播放源程序。
#includep16f877a.inc
#DEFINEyouyi0X2100
;乐谱编号
#defineL_5.158
#defineL_6.141
#defineM_1.119
#defineM_2.105
#defineM_3.94
#defineM_5.79
#defineM_6.70
#defineH_1.59
#defineM_0.0;tone[8]={158,141,119,105,94,79,70,59};声调的高低,实际上是PWM的周期值
;计算方法是CCP的时钟1MHz除以预分频比16,再除以要产生的频率,最后再减去1。
PORTD_DEQU20H;显示缓冲器COUNT
COUNT1EQU21H
COUNT2EQU22H
COUNT3EQU23H
COUNT4EQU24H
SAVEWEQU25H;W保护寄存器
SAVESEQU26H;STATUS保护寄存器
COUNT5EQU27H;节拍数
HEQU28H;地址寄存器
HANGEQU29H;行寄存器
LIEEQU30H;列寄存器
TMP1EQU31H;TMP1缓存寄存器
ByteEQU32H;缓存
Count6EQU33H;节拍数
Count7EQU34H;节拍数
DD_RAM_ADDREQU35H;第一行显示地址寄存器
DD_RAM_ULEQU36H;第二行显示地址寄存器
COUNTEQU37H
CountEQU38H;计数寄存器
Count2EQU39H
;*定义LCD数据&控制I/O口
#defineLCD_DB7PORTB,3;占用的I/O口定义
#defineLCD_DB6PORTB,2;LCD的DB6与RB2连接,其它类推
#defineLCD_DB5PORTB,1;
#defineLCD_DB4PORTB,0;
#defineLCD_ENPORTC,0
#defineLCD_RSPORTC,1
#defineLCD_DB7_DIRTRISB,3;对应的方向寄存器定义
#defineLCD_DB6_DIRTRISB,2;
#defineLCD_DB5_DIRTRISB,1;
#defineLCD_DB4_DIRTRISB,0;
#defineLCD_EN_DIRTRISC,0;
#defineLCD_RS_DIRTRISC,1;
;*LCD模块命令
#defineDISP_ON0x00C;开显示
#defineDISP_ON_C0x00E;开显示,开指针
#defineDISP_ON_B0x00F;开显示,开指针,开闪烁
#defineDISP_OFF0x008;关显示
#defineCLR_DISP0x001;清显示的操作数
#defineENTRY_INC0x006;操作数
#defineENTRY_INC_S0x007;操作数
#defineENTRY_DEC0x004;操作数
#defineENTRY_DEC_S0x005;操作数
ORGyouyi;友谊天长地久
DEL_5,L_5,M_1,M_1,M_1,M_1,M_1,M_1,M_1,M_3,M_3,M_2,M_2,M_2,M_2
DEM_1,M_2,M_2,M_3,M_3,M_1,M_1,M_1,M_1,M_1,M_3,M_3,M_5,M_5,M_6
DEM_6,M_6,M_6,M_6,M_6,M_6,M_6,M_6,M_6,M_5,M_5,M_5,M_5,M_3,M_3
DEM_3,M_1,M_1,M_2,M_2,M_2,M_2,M_1,M_2,M_2,M_3,M_3,M_1,M_1,M_1
DEM_1,L_6,L_6,L_6,L_5,L_5,M_1,M_1,M_1,M_1,M_1,M_1,M_1,M_1,M_6
DEM_6,M_5,M_5,M_5,M_5,M_3,M_3,M_3,M_1,M_1,M_2,M_2,M_2,M_2,M_1
DEM_2,M_2,M_6,M_6,M_5,M_5,M_5,M_5,M_3,M_3,M_3,M_5,M_5,M_6,M_6
DEM_6,M_6,M_6,M_6,M_6,M_6,H_1,H_1,M_5,M_5,M_5,M_5,M_3,M_3,M_3
DEM_1,M_1,M_2,M_2,M_2,M_2,M_1,M_2,M_2,M_3,M_3,M_1,M_1,M_1,M_1
DEL_6,L_6,L_6,L_5,L_5,M_1,M_1,M_1,M_1,M_1,M_1,M_0,M_0,M_0,M_0
ORG0x000
NOP;空指令
GOTOMAIN
ORG0x004;中断入口
BANKSELSAVEW
MOVWFSAVEW
SWAPFSTATUS,W
CLRFSTATUS
MOVWFSAVES;中断保护
GOTOCCPINT
;*TABLE
TABLE1;取第一行的显示码TMR2COUNT
ADDWFPCL,1;地址偏移量加当前PC值
RETLW'I';T
RETLW'n';M
RETLW'n';R
RETLW'o';2
RETLW'v';空格
RETLW'a';空格
RETLW't';C
RETLW'o';O
RETLW'r';U
RETLW'';N
RETLW'';T
RETLW'V';N
RETLW'1';T
RETLW'.';N
RETLW'5';T
RETLW00H
;*TABLE1
TABLE;取第二行显示TIME:
ms
ADDWFPCL,1;地址偏移量加当前PC值
RETLW'H';T
RETLW'e';I
RETLW'l';M
RETLW'l';E
RETLW'o';:
RETLW'';空格
RETLW'P';空格
RETLW'I';空格
RETLW'C';空格
RETLW'!
';空格
RETLW00H
;*TABLE2
TABLE2
ADDWFPCL,1
RETLW30H;"0"
RETLW31H;"1"
RETLW32H;"2"
RETLW33H;"3"
RETLW34H;"4"
RETLW35H;"5"
RETLW36H;"6"
RETLW37H;"7"
RETLW38H;"8"
RETLW39H;"9"
;*主程序开始
MAIN
CALLLCD_DISPAY
BANKSELTRISD;选择体1
CLRFTRISD;PORTD为输出端口
MOVLW07H;
MOVWFOPTION_REG;1:
256
BANKSELT1CON
CLRFCOUNT5
MOVLW30H;分频器为1:
8,关闭TMR1
MOVWFT1CON;
BCFPIR1,TMR1IF;溢出标志位清零
CLRFTMR1H
CLRFTMR1L
MOVLW0xEE;设定TMR1低位初值
ADDWFTMR1L;
MOVLW0x85;设定TMR1高位初值
ADDWFTMR1H;
BSFT1CON,0;启动TMR1
BANKSELTRISC;跳到体1
BCFTRISC,2;CCP1为输出状态
BANKSELEEADR;跳到体2
MOVLWyouyi;将地址存到W寄存器
MOVWFEEADR;将地址送入EEPROM地址寄存器
BANKSELEECON1;选定BANK3
BCFEECON1,EEPGD;选择EEPROM作为非易失性存储器操作对象
BSFEECON1,RD;启动一次读EEPROM的操作
BANKSELEEDATA;跳到体2
MOVFEEDATA,W;由于EEPROM的读出操作花费的时间很短,此时EEPROM
BANKSELPR2;跳到体1
MOVWFPR2;将W的值存到PR2
BANKSELT2CON;跳到体0
MOVLW0x07;预分频1:
16,后预分频1:
1
MOVWFT2CON;开定时器2
MOVLW0x0C;将0x0C存到W寄存器
MOVWFCCP1CON;使用8位PWM方式
BANKSELPR2;跳到体1
MOVFPR2,0;将PR2值存到W寄存器
BANKSELCCPR1L;跳到体0
MOVWFCCPR1L;将W存到CCPR1L
MOVLWB'11111100';屏蔽低两位
ANDWFCCPR1L,1
RRFCCPR1L,1;CCPR1L右移一位
RRFCCPR1L,1;CCPR1L右移一位
RRFCCPR1L,1;CCPR1L右移一位
BANKSELPIE1;跳到体1
BSFPIE1,TMR1IE;启动TMR1中断
BSFINTCON,PEIE;开启外设中断
BSFINTCON,GIE;开启全局中断
BANKSELPORTD;选择体0
CLRFPORTD
MOVLW01H;显示缓冲器赋初值
MOVWFPORTD_D
LOOP
;CALLDELAY_500ms;延时500ms
;RLFPORTD_D;显示缓冲器循环左移
GOTOLOOP;等待中断
;*CCPINT中断子程序
CCPINT
BTFSSPIR1,TMR1IF;判断是否是TMR1中断
GOTOJMP4;否,跳出中断
BCFPIR1,TMR1IF;是,清中断标志位
MOVLW30H;分频器为1:
8,关闭TMR1
MOVWFT1CON;
CLRFTMR1H;清TMR1H
CLRFTMR1L;清TMR1L
MOVLW0xEE;设定TMR1低位初值
ADDWFTMR1L;
MOVLW0x85;设定TMR1高位初值
ADDWFTMR1H;
BSFT1CON,0;启动TMR1
BANKSELEEADR;跳到体2
MOVLWyouyi;将地址存到W寄存器
MOVWFEEADR;将地址送入EEPROM地址寄存器
BANKSELCOUNT5;跳到体0
MOVFCOUNT5,0;将COUNT存到W寄存器
BANKSELEEADR;跳到体2
ADDWFEEADR,1;EEADR=EEADR+COUNT
BANKSELEECON1;选定BANK3
BCFEECON1,EEPGD;选择EEPROM作为非易失性存储器操作对象
BSFEECON1,RD;启动一次读EEPROM的操作
BANKSELEEDATA;跳到体2
MOVFEEDATA,W;由于EEPROM的读出操作花费的时间很短,此时EEPROM
BANKSELPR2;跳到体1
MOVWFPR2;将W存到PR2
BANKSELCCPR1L;跳到体0
MOVWFCCPR1L;将W存到CCPR1L
MOVLWB'11111100';将11111100存到W寄存器
ANDWFCCPR1L,1;屏蔽低两位
RRFCCPR1L,1;CCPR1L左移一位
RRFCCPR1L,1;CCPR1L左移一位
RRFCCPR1L,1;CCPR1L右移一位
MOVLW.149;将149存到W寄存器
SUBWFCOUNT5,0;W=COUNT-149
BTFSSSTATUS,C;判断是否有借位
GOTOJMP1;有,跳到JMP1
GOTOJMP2;无,跳到JMP2
JMP1
INCFCOUNT5,1;COUNT=COUINT+1
GOTOJMP;跳到JMP
JMP2
CLRFCOUNT5;COUNT清零
JMP
MOVLWB'00000000';送.0到W寄存器
XORWFPORTD,0;判断PORTD是否为0
BTFSSSTATUS,Z
GOTOJMP3;否,跳到JMP1
MOVFPORTD_D,0;是,将PORTD_D的值
MOVWFPORTD;送到PORTD
GOTOJMP4
JMP3
CLRFPORTD;PORTD清零
BCFSTATUS,C;清楚其他操作对C的影响
RLFPORTD_D;显示缓冲器循环左移
BTFSCSTATUS,C
GOTOJMP5
GOTOJMP4
JMP5
MOVLW01H;显示缓冲器赋初值
MOVWFPORTD_D
JMP4
SWAPFSAVES,W
MOVWFSTATUS
SWAPFSAVEW,F
SWAPFSAVEW,W;恢复中断
RETFIE
;*700ms延时子程序
DELAY_500ms
MOVLW.5
MOVWFCOUNT3
LOOP1
MOVLWD'133';设置外部循环次数
MOVWFCOUNT1;
LOOP2
MOVLWD'249';设置部循环次数
MOVWFCOUNT2;
LOOP3
DECFSZCOUNT2,1;部循环变量自减1,为0则跳转
GOTOLOOP3;
DECFSZCOUNT1,1;外部循环变量自减1,为0则跳转
GOTOLOOP2;
DECFSZCOUNT3,1;外部循环变量自减1,为0则跳转
GOTOLOOP1;
RETURN;返回主程序
;*ADRESS地址转换子程序
ADRESS
BTFSSHANG,0;判断行是否为1
GOTOJ1;是,跳到J1
MOVFLIE,0;否,将列值送到W寄存器
ADDWFDD_RAM_UL,0;第二行首地址加上列值
GOTOJ2
J1
MOVFLIE,0;将列值送到W寄存器
ADDWFDD_RAM_ADDR,0;第一行首地址加上列值
J2
MOVWFH;将地址存到H寄存器
RETURN;子程序返回
;*SET_CURSOR设置光标位置子程序
SET_CURSOR
BANKSELH
MOVFH,0;设置光标位置
CALLSendCmd
MOVLWDISP_ON;开显示
CALLSendCmd
RETURN;子程序返回
;*Delay-延时子程序(773us)
Delay;call指令占用2个指令周期
CLRFCount;清Count占用1个指令周期
Dloop
DECFSZCount,f;这两行指令将延时
GOTODloop;(256*3)-1个指令周期
RETURN;return占用2个指令周期
END
四、实验总结
一开始是电路设计,因为所需要的模块不多,所以电路也不是很复杂。
但到蜂鸣器模块设计的时候,不知道要接那个引脚,有接RC2的,有接RC1的。
后来选择了CCP1。
而本身没焊ICD2调试接口,所以找别的同学下载程序。
最后验收。
感觉这次实验也没想象中难,主要是对电路不熟,有原理图还好弄,要不然真不知道要接什么引脚。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 单片机 音乐 播放 实验 报告