找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2171|回复: 3
收起左侧

51单片机之一个汇编的播放器

[复制链接]
ID:21069 发表于 2018-12-15 18:41 | 显示全部楼层 |阅读模式
一个汇编的播放器.jpg

OUT BIT P2.0                        ;定义音频输出端口,p2.0
N   EQU  3                                                ;歌曲总数
OUT_NUM EQU P1                                        ;数码管显视当前所放歌曲曲数
      ORG 0000H
      AJMP MAIN
      ORG 0003H
      AJMP LAST_SONG            ;外部中断0用于接上一曲歌按键
      ORG 000BH
      AJMP F_T0                 ;定时器0用于定时,作音符发生器用
      ORG 0013H
q4:   AJMP NEXT_SONG            ;外部中断1接下一曲歌按键
      ORG 001BH
      AJMP START_PAUSE          ;定时器1用计数,这里用作中断,接开始/暂停键,初值为0ffH,方式2
      ORG 0030H
MAIN: MOV SP,#60H        
      MOV DPTR,#TABLE                    ;DPRT指向每首歌曲的入口地址的地址。
      MOV R0,#30H                   ;R0中存入数据30H,这里在以30H开始的单元存放每首歌曲的入口地址,其中30H,31H存放
                                                    ;歌曲的节拍入口地址,32H,33H存放歌曲音符入口地址,每首歌占用四个存储存单元。
        MOV R5,#00H                                    ;R5中存放表TABLE中正在执行操作的序号
      MOV R6,#1                                    ;R6存放正在设置入口信息的歌曲数
SET_TAB: MOV A,R5                   ;设置每首歌曲的入口信息,存放在以30H开始的存储单元中。
      MOVC A,@A+DPTR
      MOV @R0,A
      INC R5
      INC R0
      MOV A,R5
      MOVC A,@A+DPTR
      MOV @R0,A
      INC R5
      INC R0
      MOV A,R5
      MOVC A,@A+DPTR
      MOV @R0,A
      INC R0
      INC R5
      MOV A,R5
      MOVC A,@A+DPTR
      MOV @R0,A
      INC R0
      INC R5
      INC R6                          ;设置完一首歌曲后,歌曲数加一
      CJNE R6,#N+1,SET_TAB                          ;是否设置完,没有便继续,否则进行下面的操作
      ;***********************************          对中断,计数器的相关参数进行设置
      MOV TMOD, #61H                                                  ;计数器0工作方式1,计数器1工作方式2
      MOV TH1,#0FFH                                                          ;给计数器1置初值0FFH,又由于是工作方式2,所以
      MOV TL1,#0FFH                                                          ;计数器计数为1,相当于一外部中断。
      SETB ET1                                                                  ;允许计数器1中断   
      SETB ET0                                      ;允许计数器具0中断
      CLR PT0                                 ;计数器0为低优先级
      SETB PT1                                                                  ;计数器1为高优先级
      SETB IT0                                ;外部中断0为跳沿触发
      SETB PX0                                ;高优先级

      SETB IT1                                ;外部中断1为跳沿触发
      SETB PX1                                ;高优先级
      SETB EX1                                ;允许外部中断1中断
      SETB EX0                                                                  ;允许外部中断定0中断
      SETB EA                                 ;开中断总开关
      SETB TR1                                      ;定时器1开始工作,作中断用
      SETB OUT                                                                  ;音频输出端口初始化
      ;***********************************          ;设置结束
      CLR F0                                      ;设置F0=0,用来作暂停/播放的标置位用
      MOV 22H,#01H                                  ;22H单元中存放正在播放的歌曲编号
      MOV DPTR,#OUT_TAB                              ;将正在播放的歌曲编号送数码管显视
      MOV A,22H
      MOVC A,@A+DPTR
      MOV  OUT_NUM,A
      MOV R7,#00H                                  ;R7中存放歌曲总信息的入口地址
START0:MOV R4,#00H                            ;R4存放当前正在播放歌曲的第几个节拍数
      MOV R0,#30H                                                           ;30H开始的单元中存放歌曲的入口信息
      MOV A,R7                                      ;将歌曲的节拍表的入口地址送到DPTR
      ADD A,R0
      MOV R0,A
      MOV DPH,@R0
      INC R0
      MOV DPL,@R0
      INC R0
      MOV A,R4
      INC R4
      MOVC A,@A+DPTR                              ;取出第一节拍数,其实第一个节拍不是歌曲的第一个节拍,而是表示几分音符               
;****************************************************
      MOV 26H,A                                                                  ;将取出的音符数+节拍数保存在职26H单元中
NEXT: MOV R0,#30H                                  ;开始取出歌曲的第一个数据
      MOV A,R7
      ADD A,R0
      MOV R0,A
      MOV DPH,@R0
      INC R0
      MOV DPL,@R0
      INC R0
      MOV A,R4
      INC R4
      MOVC A,@A+DPTR                                  ;放在A中
;****************************************************      
      JZ END0                                              ;若为0,则表示为休止符,不唱,本次音符不唱,                      
      MOV R1,A                                          ;不为0,取出节拍数
      ANL A,#0FH
      MOV R2,A
      MOV A,R1
      SWAP A
      ANL A,#0FH
      JNZ SING                                       ;音符不为0,唱
      CLR TR0                                              ;为0,不唱,关频率发生器
      SJMP SING1                                  
SING: DEC A                                           ;开始唱,进行相应的数据处理
      MOV R3,A
      RL A
      MOV DPH,@R0
      INC R0
      MOV DPL,@R0
      INC R0
      MOVC  A,@A+DPTR
      MOV 21H,A
      MOV TH0,A
      MOV A,R3
      RL A
      INC A
      MOVC A,@A+DPTR
      MOV 20H,A
      MOV TL0,A
      SETB TR0                                           ;开唱
SING1:LCALL DELAY                              ;每个音符唱多久
      JB F0,FOR                                                                   ;是否暂停,
      AJMP NEXT                                                                   ;没有暂停,继续
FOR:  CLR TR0                                                       ;暂停,不唱
      JB F0,$                                                                   ;等待播放
      AJMP NEXT                                       ;开始播放
END0: CLR TR0                                  ;不唱     
          MOV A,22H                                       ;唱完处理
          CJNE A,#N,WW                                                           ;是不是全部歌曲都唱完
          MOV 22H,#01H                                   ;全部唱完,则从第一首开始再唱
          MOV R7,#00H
          MOV OUT_NUM,#06H                               ;数码管显视第一首歌曲编号                    
          AJMP WWW
WW:          MOV A,R7                                           ;没有全部唱完,唱下一首,歌曲的入口信息调整
      ADD A,#4
      MOV R7,A
      INC 22H
          CLR  EA
          PUSH DPH
          PUSH DPL         
          MOV A,22H
          MOV DPTR,#OUT_TAB
          MOVC A,@A+DPTR
          MOV OUT_NUM,A                                   ;数码管显视相应的歌曲编号
          POP DPL
          POP DPH
WWW:  SETB EA
      AJMP START0                                   ;开始下一首的演唱
F_T0: MOV TH0,21H                                   ;定时器0置初值
      MOV TL0,20H
      CPL OUT                                                 ;频率产生
      RETI
NEXT_SONG: PUSH ACC                                       ;下一曲中断程序处理,保护现场                                
       PUSH DPH
           PUSH DPL          
       CLR EA                                           ;关中断
       MOV  A,22H
           CJNE A,#N,Q                                    ;是最后一首吗?
           MOV R7,#00H                                    ;是最后一首,则R7指向第一首,演唱第一首
           MOV 22H,#01H
           AJMP BACK                                    
Q:     INC 22H                                        ;不是最后一首,唱下一首,R7内容加4,歌曲数加1
       MOV A,R7
           ADD A,#4
           MOV R7,A
BACK:  MOV R4,#00H                                        ;数码管显视相应的歌曲编号
       MOV A,22H
           MOV DPTR,#OUT_TAB
           MOVC A,@A+DPTR
           MOV OUT_NUM,A
;********************************************
      MOV B,R0                                                   ;对下首要演唱的歌曲的几分拍进行调整,同时对R0中的内容进行保护
      MOV R4,#00H
      MOV R0,#30H
      MOV A,R7
      ADD A,R0
      MOV R0,A
      MOV DPH,@R0
      INC R0
      MOV DPL,@R0
      INC R0
      MOV A,R4
      INC R4
      MOVC A,@A+DPTR
          MOV  26H,A                                  ;结果存入26H单元中
          DEC R4
          MOV R0,B                                                                  ;恢复R0中的内容
;********************************************          
           POP DPL                                                                  ;恢复现场
           POP DPH
           POP ACC
           SETB EA
           RETI                                       ;中断返回
LAST_SONG: PUSH ACC                            ;上一曲中断程序处理开始,保护现场                                                
           PUSH DPH
           PUSH DPL               
           CLR EA                ;关中断
           MOV A,22H             ;曲目数送A
               CJNE A,#1,QQ                 ;是否是第一首
           MOV 22H,#N            ;是第一首歌曲
           MOV B,#4              ;将R7指向最后一首歌曲
               MOV A,#N-1
               MUL AB
               MOV R7,A
               AJMP BACK2            ;处理结束
QQ:        DEC 22H
           MOV A,R7                             ;R7减4
               SUBB A,#4
               MOV R7,A
BACK2:     MOV R4,#00H
           MOV A,22H
               MOV DPTR,#OUT_TAB
               MOVC A,@A+DPTR
               MOV OUT_NUM,A             ;数码管显视相应歌曲的编号
;********************************************
      MOV B,R0                                                ;对下首要演唱的歌曲的几分拍进行调整,同时对R0中的内容进行保护
      MOV R4,#00H
      MOV R0,#30H
      MOV A,R7
      ADD A,R0
      MOV R0,A
      MOV DPH,@R0
      INC R0
      MOV DPL,@R0
      INC R0
      MOV A,R4
      INC R4
      MOVC A,@A+DPTR
          MOV  26H,A                       ;结果存入26H单元中
          DEC R4
          MOV R0,B                                                ;R0中的内容恢复



END;
完整版见附件

一个汇编的播放器.zip (19.48 KB, 下载次数: 11)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:102963 发表于 2018-12-16 18:02 | 显示全部楼层
附件不完整,缺少程序!
回复

使用道具 举报

ID:678235 发表于 2019-12-31 11:04 | 显示全部楼层
可以联系下你吗
回复

使用道具 举报

ID:678235 发表于 2020-1-1 14:04 | 显示全部楼层
我可以联系下你吗我这里学习遇到个问题
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表