单片机音乐播放实验报告.doc

上传人:jian****018 文档编号:9611501 上传时间:2020-04-06 格式:DOC 页数:11 大小:309KB
返回 下载 相关 举报
单片机音乐播放实验报告.doc_第1页
第1页 / 共11页
单片机音乐播放实验报告.doc_第2页
第2页 / 共11页
单片机音乐播放实验报告.doc_第3页
第3页 / 共11页
点击查看更多>>
资源描述
课 程 设 计课程名称 微机原理与单片机技术实践题目名称 单片机制作与音乐播放 学生学院 自动化学院 专业班级 电子(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_1119M_2105M_394M_579M_670H_159L_5158L_6141如表4.2所示:音乐的音拍,一个节拍为单位(C调)表4.2音乐的音拍曲调值DELAY曲调值DELAY调4/4125ms调4/462ms调3/4187ms调3/494ms调2/4250ms调2/4125ms对于不同的曲调我们也可以用单片机的另外一个定时/计数器来完成。发音部分代码在程序中实现,靠单片机的一个管脚输出,考虑到声音可能不够大所以我们加入了功放电路,利用LM386来对声音信号进行放大。音频输出信号由ADU OUT引出,信号可经功放电路LM386输出到扬声器或耳机。三、课程设计应完成的工作1.音乐播放源程序。#include p16f877a.inc #DEFINE youyi 0X2100;乐谱编号#define L_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 ; tone8=158,141,119,105,94,79,70,59;声调的高低,实际上是PWM的周期值;计算方法是CCP的时钟1MHz除以预分频比16,再除以要产生的频率,最后再减去1。PORTD_D EQU 20H ;显示缓冲器COUNTCOUNT1 EQU 21HCOUNT2 EQU 22HCOUNT3 EQU 23HCOUNT4 EQU 24HSAVEW EQU 25H ;W保护寄存器SAVES EQU 26H ;STATUS保护寄存器COUNT5 EQU 27H ;节拍数H EQU 28H ;地址寄存器HANG EQU 29H ;行寄存器LIE EQU 30H ;列寄存器TMP1 EQU 31H ;TMP1缓存寄存器Byte EQU 32H ;缓存Count6 EQU 33H ;节拍数Count7 EQU 34H ;节拍数DD_RAM_ADDREQU 35H ; 第一行显示地址寄存器DD_RAM_UL EQU 36H ; 第二行显示地址寄存器COUNT EQU 37HCount EQU 38H ;计数寄存器Count2 EQU 39H;* 定义 LCD数据& 控制I/O口 #defineLCD_DB7 PORTB,3 ;占用的I/O口定义 #defineLCD_DB6 PORTB,2 ;LCD的DB6与RB2连接,其它类推#defineLCD_DB5 PORTB,1 ;#defineLCD_DB4 PORTB,0 ;#define LCD_EN PORTC,0#define LCD_RS PORTC,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 ; 操作数 ORG youyi ;友谊天长地久 DE L_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_2DE M_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_6DE M_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_3DE M_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_1DE M_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_6DE M_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_1DE M_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_6DE M_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_3DE 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,M_1DE L_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 ORG 0x000 NOP ;空指令 GOTO MAIN ORG 0x004 ;中断入口 BANKSEL SAVEW MOVWF SAVEW SWAPF STATUS,W CLRF STATUS MOVWF SAVES ;中断保护 GOTO CCPINT ;*TABLETABLE1 ;取第一行的显示码TMR2 COUNT ADDWF PCL,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 RETLW 00H;* TABLE1TABLE ;取第二行显示TIME: ms ADDWF PCL,1 ;地址偏移量加当前PC值 RETLW H ;T RETLW e ;I RETLW l ;M RETLW l ;E RETLW o ;: RETLW ;空格 RETLW P ;空格 RETLW I ;空格 RETLW C ;空格 RETLW ! ;空格 RETLW 00H;* TABLE2TABLE2 ADDWF PCL,1 RETLW 30H ;0 RETLW 31H ;1 RETLW 32H ;2 RETLW 33H ;3 RETLW 34H ;4 RETLW 35H ;5 RETLW 36H ;6 RETLW 37H ;7 RETLW 38H ;8 RETLW 39H ;9;*主程序开始MAIN CALL LCD_DISPAY BANKSEL TRISD ;选择体1 CLRF TRISD ;PORTD为输出端口 MOVLW 07H ; MOVWF OPTION_REG ;1:256 BANKSEL T1CON CLRF COUNT5 MOVLW 30H ;分频器为1:8,关闭TMR1 MOVWF T1CON ; BCF PIR1,TMR1IF ;溢出标志位清零 CLRF TMR1H CLRF TMR1L MOVLW 0xEE ;设定TMR1低位初值 ADDWF TMR1L ; MOVLW 0x85 ;设定TMR1高位初值 ADDWF TMR1H ; BSF T1CON,0 ;启动TMR1 BANKSEL TRISC ;跳到体1 BCF TRISC,2 ;CCP1为输出状态 BANKSEL EEADR ;跳到体2 MOVLW youyi ;将地址存到W寄存器 MOVWF EEADR ;将地址送入EEPROM地址寄存器 BANKSEL EECON1 ;选定BANK3 BCF EECON1,EEPGD ;选择EEPROM作为非易失性存储器操作对象 BSF EECON1,RD ;启动一次读EEPROM的操作 BANKSEL EEDATA ;跳到体2 MOVF EEDATA,W ;由于EEPROM的读出操作花费的时间很短,此时EEPROM BANKSEL PR2 ;跳到体1 MOVWF PR2 ;将W的值存到PR2 BANKSEL T2CON ;跳到体0 MOVLW 0x07 ;预分频1:16,后预分频1:1 MOVWF T2CON ;开定时器2 MOVLW 0x0C ;将0x0C存到W寄存器 MOVWF CCP1CON ;使用8位PWM方式 BANKSEL PR2 ;跳到体1 MOVF PR2,0 ;将PR2值存到W寄存器 BANKSEL CCPR1L ;跳到体0 MOVWF CCPR1L ;将W存到CCPR1L MOVLW B11111100 ;屏蔽低两位 ANDWF CCPR1L,1 RRF CCPR1L,1 ;CCPR1L右移一位 RRF CCPR1L,1 ;CCPR1L右移一位 RRF CCPR1L,1 ;CCPR1L右移一位 BANKSEL PIE1 ;跳到体1 BSF PIE1,TMR1IE ;启动TMR1中断 BSF INTCON,PEIE ;开启外设中断 BSF INTCON,GIE ;开启全局中断 BANKSEL PORTD ;选择体0 CLRF PORTD MOVLW 01H ;显示缓冲器赋初值 MOVWF PORTD_D LOOP ;CALL DELAY_500ms ;延时500ms ;RLF PORTD_D ;显示缓冲器循环左移 GOTO LOOP ;等待中断;* CCPINT中断子程序CCPINT BTFSS PIR1,TMR1IF ;判断是否是TMR1中断 GOTO JMP4 ;否,跳出中断 BCF PIR1,TMR1IF ;是,清中断标志位 MOVLW 30H ;分频器为1:8,关闭TMR1 MOVWF T1CON ; CLRF TMR1H ;清TMR1H CLRF TMR1L ;清TMR1L MOVLW 0xEE ;设定TMR1低位初值 ADDWF TMR1L ; MOVLW 0x85 ;设定TMR1高位初值 ADDWF TMR1H ; BSF T1CON,0 ;启动TMR1 BANKSEL EEADR ;跳到体2 MOVLW youyi ;将地址存到W寄存器 MOVWF EEADR ;将地址送入EEPROM地址寄存器 BANKSEL COUNT5 ;跳到体0 MOVF COUNT5,0 ;将COUNT存到W寄存器 BANKSEL EEADR ;跳到体2 ADDWF EEADR,1 ;EEADR=EEADR+COUNT BANKSEL EECON1 ;选定BANK3 BCF EECON1,EEPGD ;选择EEPROM作为非易失性存储器操作对象 BSF EECON1,RD ;启动一次读EEPROM的操作 BANKSEL EEDATA ;跳到体2 MOVF EEDATA,W ;由于EEPROM的读出操作花费的时间很短,此时EEPROM BANKSEL PR2 ;跳到体1 MOVWF PR2 ;将W存到PR2 BANKSEL CCPR1L ;跳到体0 MOVWF CCPR1L ;将W存到CCPR1L MOVLW B11111100 ;将11111100存到W寄存器 ANDWF CCPR1L,1 ;屏蔽低两位 RRF CCPR1L,1 ;CCPR1L左移一位 RRF CCPR1L,1 ;CCPR1L左移一位 RRF CCPR1L,1 ;CCPR1L右移一位 MOVLW .149 ;将149存到W寄存器 SUBWF COUNT5,0 ;W=COUNT-149 BTFSS STATUS,C ;判断是否有借位 GOTO JMP1 ;有,跳到JMP1 GOTO JMP2 ;无,跳到JMP2JMP1 INCF COUNT5,1 ;COUNT=COUINT+1 GOTO JMP ;跳到JMPJMP2 CLRF COUNT5 ;COUNT清零JMP MOVLW B00000000 ;送.0到W寄存器 XORWF PORTD,0 ;判断PORTD是否为0 BTFSS STATUS,Z GOTO JMP3 ;否,跳到JMP1 MOVF PORTD_D,0 ;是,将PORTD_D的值 MOVWF PORTD ;送到PORTD GOTO JMP4JMP3 CLRF PORTD ;PORTD清零 BCF STATUS,C ;清楚其他操作对C的影响 RLF PORTD_D ;显示缓冲器循环左移 BTFSC STATUS,C GOTO JMP5 GOTO JMP4 JMP5 MOVLW 01H ;显示缓冲器赋初值 MOVWF PORTD_D JMP4 SWAPF SAVES,W MOVWF STATUS SWAPF SAVEW,F SWAPF SAVEW,W ;恢复中断 RETFIE;* 700ms延时子程序DELAY_500ms MOVLW .5 MOVWF COUNT3LOOP1 MOVLW D133 ;设置外部循环次数 MOVWF COUNT1 ;LOOP2 MOVLW D249 ;设置内部循环次数 MOVWF COUNT2 ;LOOP3 DECFSZ COUNT2 ,1 ;内部循环变量自减1,为0则跳转 GOTO LOOP3 ; DECFSZ COUNT1,1 ;外部循环变量自减1,为0则跳转 GOTO LOOP2 ; DECFSZ COUNT3,1 ;外部循环变量自减1,为0则跳转 GOTO LOOP1 ; RETURN ;返回主程序;* ADRESS地址转换子程序ADRESS BTFSS HANG,0 ;判断行是否为1 GOTO J1 ;是,跳到J1 MOVF LIE,0 ;否,将列值送到W寄存器 ADDWF DD_RAM_UL,0 ;第二行首地址加上列值 GOTO J2J1 MOVF LIE,0 ;将列值送到W寄存器 ADDWF DD_RAM_ADDR,0 ;第一行首地址加上列值 J2 MOVWF H ;将地址存到H寄存器 RETURN ;子程序返回;* SET_CURSOR设置光标位置子程序 SET_CURSOR BANKSEL H MOVF H,0 ;设置光标位置 CALL SendCmd MOVLW DISP_ON ; 开显示 CALL SendCmd RETURN ;子程序返回;* Delay - 延时子程序(773us) Delay ; call指令占用2个指令周期 CLRF Count ; 清 Count占用1个指令周期Dloop DECFSZCount,f ; 这两行指令将延时 GOTODloop ; (256 * 3) -1 个指令周期 RETURN ; return占用2个指令周期END四、实验总结一开始是电路设计,因为所需要的模块不多,所以电路也不是很复杂。但到蜂鸣器模块设计的时候,不知道要接那个引脚,有接RC2的,有接RC1的。后来选择了CCP1。而本身没焊ICD2调试接口,所以找别的同学下载程序。最后验收。感觉这次实验也没想象中难,主要是对电路不熟,有原理图还好弄,要不然真不知道要接什么引脚。
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 管理文书 > 工作总结


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!