找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3633|回复: 0
打印 上一主题 下一主题
收起左侧

单片机电子琴播放音乐带倒计时功能的proteus仿真(汇编)

[复制链接]
跳转到指定楼层
楼主

电子琴与倒计时播放音乐全部资料下载: 电子琴和倒计时播放音乐.rar (30.5 KB, 下载次数: 46)
功能:
一、能通过按键,自行弹奏电子琴类的音乐;
二、能写好音乐代码后,自动播放音乐。 已通过测试。

带有proteus仿真,用汇编语言编写,内有详细注解
电子琴的基本原理是产生各个音符对应的频率,将频率放大后驱动喇叭发出音响。该电子琴包括手动弹奏与自动演奏两种功能,其中手动弹奏时还可录音回放


汇编源码如下:
  1. ORG 0000H
  2. SL      EQU   30H              ; SL存放秒的个位数
  3. SH  EQU   31H              ; SH存放秒的十位数
  4. ML      EQU   32H              ; ML存放分的个位数
  5. MH      EQU   33H              ; MH存放分的十位数
  6. HL      EQU   34H              ; HL存放时的个位数
  7. HH  EQU   35H             ; HH存放时的十位数
  8. ;
  9. L0      EQU   36H              ; L0~L3:显示数据存储器
  10. L1  EQU   37H
  11. L2      EQU   38H
  12. L3  EQU   39H
  13. DSPLYP  EQU   3AH              ; 显示数据指针(DISPLAY-POINT)
  14. PLYTS   EQU   3BH              ; 显示次数计数器(DISPLAY-TIMES)
  15. ;
  16. LPLMOD  BIT   39H              ; 低两位显示方式(LOW-PLAY-MOD)
  17. HPLMOD  BIT   3AH              ; 高两位显示方式(HIGH-PLAY-MOD)
  18. BRIGHT  BIT   3BH              ; DISPLAY子程序参数:亮灭指示位
  19. ;
  20. TCOUNT  EQU   3CH              ; 时间计数器(TIME-COUNT)
  21. ;
  22. ADDRES  EQU   3DH              ; 加1子程序参数
  23. MAX     EQU   3EH              ; 加1子程序参数
  24. IFDEC   BIT   20H              ; BCD加法子程序参数
  25. ;
  26. R_MOD   EQU   3FH              ; 响铃方式参数
  27. ;
  28. LED4    BIT   30H              ; 发光管状态位
  29. BELL    BIT   P1.7             ; 蜂鸣器
  30. SWITCH  BIT   P3.7             ; 继电器
  31. FKEY    BIT   P3.0             ; 功能键 (S1)
  32. MKEY    BIT   P3.1             ; 修改键 (S2)
  33. ;
  34. WORKIN  BIT   38H              ; 工作状态指示位
  35. ;

  36.                          SJMP START
  37.                          ORG 000BH

  38.                          LJMP LOOP1
  39.                          ;ORG 001BH
  40.     ;LJMP INT_1

  41. ORG 001BH

  42. JNB P0.6,YINYUE1  ;低音乐
  43. LJMP DIANZIQIN1

  44. ORG 0030H

  45.               DIANZIQIN1:
  46.                ;JB P0.1,ZIJIDE
  47.                JnB P3.6,HUAN   ;高主
  48.                 ;YINYUE1:ljmp YINYUE11
  49.               ZIJIDE:;CLR P2.0
  50.               LJMP INT_1
  51.               HUAN:LJMP DIANZIQIN
  52.                YINYUE1:INC 20H ;中断服务,中断计数器加1
  53.                        MOV TH1,#0D8H
  54.                       MOV TL1,#0EFH ;12M晶振,形成10毫秒中断
  55.                         RETI

  56.                         START: LJMP  MAIN             ; 0000H  引向主程序
  57.     LJMP  ERR              ; 0003H
  58.     NOP
  59.     NOP
  60.     LJMP  ERR              ; 引向出错处理程序
  61.    LOOP1: LJMP  PGT0             ; 000BH  引向中断处理程序PGT0
  62.     NOP
  63.     NOP
  64.     LJMP  ERR              ; 引向出错处理程序
  65.    LOOP2: LJMP  ERR              ; 0013H  INT1
  66.     NOP
  67.     NOP
  68.     LJMP  ERR
  69.    LOOP3:LJMP  ERR              ; 001BH  T1
  70.     NOP
  71.     NOP
  72.     LJMP  ERR
  73.    LOOP4:LJMP  ERR              ; 0023H
  74.     NOP
  75.     NOP
  76.     LJMP  ERR
  77.     LJMP  ERR              ; 002BH
  78.     NOP
  79.     NOP
  80. ;
  81. ;************
  82. ;   主程序  ;
  83. ;************
  84. MAIN: JNB P0.6,CCC
  85.   LJMP DIANZIQIN
  86. ;CCC:LJMP YINYUE

  87. CCC:MOV   IE,#00H          ; 关中断
  88.     MOV   SP,#57H          ; 设置堆栈指针
  89.     MOV   PSW,#00H         ; 选用寄存器组0
  90.     MOV   TMOD,#11H        ; 设定中断工作方式为T0和T1
  91.     ;
  92.     MOV   A,56H
  93.     CJNE  A,#0AAH,CSTART   ; 判上电复位标志,无标志转冷启动
  94.     MOV   A,57H
  95.     CJNE  A,#55H,CSTART    ; 无标志转冷启动
  96.     AJMP  HSTART           ; 有上电复位标志转热启动
  97.     NOP
  98.     NOP
  99.     LJMP  ERR              ; 软件陷阱,引向出错处理程序
  100. CSTART: MOV   P1,#0FFH         ; 冷启动,全面初始化
  101.     MOV   P3,#0FFH
  102.     MOV   TCON,#00H        ; 计时停止
  103.     MOV   TL0,#0B0H        ; 赋中断T0初值
  104.     MOV   TH0,#3CH
  105.     MOV   TCOUNT,#0AH      ; 赋定时器初值
  106.     MOV   R5,#00H          ; R5为一空单元(备用)
  107.     MOV   R4,#00H          ; R4 为工作模式选择寄存器
  108.     MOV   SL,#00H          ; 定时单元清零
  109.     MOV   SH,#00H          ; 秒
  110.     MOV   ML,#00H          ;
  111.     MOV   MH,#00H          ; 分
  112.     MOV   HL,#00H          ;
  113.     MOV   HH,#00H          ; 时
  114.     MOV   PLYTS,#64H       ; 赋显示次数初值为100次
  115.     MOV   DSPLYP,#L0       ; 显示指针指向显存单元
  116.     MOV   L0,#0AH          ; 送显示数据"-----"
  117.     MOV   L1,#0AH
  118.     MOV   L2,#0AH
  119.     MOV   L3,#04H
  120.     SETB  LED4             ; LED4为数码管之间的发光二极管
  121.     SETB  LPLMOD           ; 设定显示方式为闪烁
  122.     SETB  HPLMOD           ;
  123.     SETB  BRIGHT           ; 允许显示
  124.     CLR   WORKIN          ; 清工作标志 , 待命
  125.     AJMP  SETUP            ; 转开始工作
  126.     NOP
  127.     NOP
  128.     LJMP  ERR              ; 软件陷阱
  129. HSTART: MOV   SCON,#00H        ; 有上电标志,热启动,清串行口控制寄存器
  130.     MOV   IP,#00H          ; 清中断优先控制寄存器
  131.     SETB  FKEY             ; 重设按键
  132.     SETB  MKEY
  133.     SETB  EA               ; 开中断
  134.     AJMP  BEGIN            ; 转向继续工作
  135.     NOP
  136.     NOP
  137.     LJMP  ERR              ; 软件陷阱
  138. SETUP:  SETB  EA               ; 开中断
  139. ;
  140. MAIN1:  ACALL DISPLY           ; 调用显示
  141.     JB    FKEY,JUDGE       ; 按键扫描
  142.     ACALL KEYDLY           ; 延时消抖动
  143.     JB    FKEY,JUDGE       ; 无键按下转向判断是否到点
  144.     CLR   ET0              ; 功能键被按下,则
  145.     CLR   TR0          ; 暂停计时
  146.     ACALL MENU             ; 调用菜单设置程序
  147. BEGIN:  SETB  WORKIN           ; 置工作标志位,开始工作
  148.     SETB  ET0              ; 开中断
  149.     SETB  TR0              ; 开始计时
  150.     MOV   A,R4             ; 移入工作模式选择
  151.     RL    A         ; 指针放大
  152.     MOV   DPTR,#M_TAB
  153.     JMP   @A+DPTR          ; 根据工作模式跳转到相应程序段
  154. M_TAB:  AJMP  WORK1
  155.     AJMP  WORK2
  156.     AJMP  WORK3
  157.     AJMP  WORK4
  158.     NOP
  159.     NOP
  160.     LJMP  ERR              ; 软件陷阱
  161. WORK1:  ;
  162. WORK2:  CLR   SWITCH           ; 工作方式1和2:开继电器
  163.     AJMP  MAIN2
  164.     NOP
  165.     NOP
  166.     LJMP  ERR              ; 软件陷阱
  167. WORK3:  ;
  168. WORK4:  SETB  SWITCH           ; 工作方式3和4:不开继电器
  169. MAIN2:  CLR   BELL             ; 蜂鸣器短鸣一声,以示开始工作
  170.     ACALL DL05S
  171.     SETB  BELL
  172. JUDGE:  JNB   WORKIN,MAIN1     ; 判断是否在定时之中
  173.     MOV   A,SL             ; 判断秒是否为零
  174.     JNZ   MAIN1
  175.     MOV   A,SH             ; 判断秒是否为零
  176.     JNZ   MAIN1
  177.     MOV   A,ML             ; 判断分是否为零
  178.     JNZ   MAIN1
  179.     MOV   A,MH             ; 判断分是否为零
  180.     JNZ   MAIN1
  181.     MOV   A,HL             ; 判断时是否为零
  182.     JNZ   MAIN1
  183.     MOV   A,HH             ; 判断时是否为零
  184.     JNZ   MAIN1            ; 若时分秒全为零则
  185.     CLR   ET0              ; 停止计时
  186.     CLR   TR0              ;


  187.     ACALL ACTION          ; 调用到点工作子程序

  188.     AJMP  MAIN             ; 返回
  189.     NOP
  190.     NOP
  191.     LJMP  ERR              ; 软件陷阱
  192.     ;
  193. ;******************
  194. ;    倒计时程序   ;
  195. ;******************
  196. PGT0:   CLR   EA               ; 关中断
  197.     PUSH  ACC          ; 保护现场
  198.     PUSH  PSW
  199.     PUSH  DPL
  200.     PUSH  DPH
  201.     MOV   PSW,#08H        ; 选用寄存器组1
  202.     CLR   TR0              ; 暂停计时
  203.     MOV   A,#0B7H          ; 中断同步修正
  204.     ADD   A,TL0
  205.     MOV   TL0,A
  206.     MOV   A,#3CH
  207.     ADD   A,TH0
  208.     MOV   TH0,A
  209.     SETB  TR0              ; 恢复计时
  210.     DEC   TCOUNT           ; 定时器T0每50 000毫秒溢出一次,则
  211.     MOV   A,TCOUNT         ; 溢出10次为0.5秒
  212.     JNZ   OUTT0        ; 判断是否到半秒
  213.     MOV   TCOUNT,#0AH      ;
  214.     CPL   LED4         ; 若到半秒LED取反
  215.     JNB   LED4,OUTT0       ; LED每闪烁一次是一秒
  216.     MOV   R0,#SH           ; 移入秒位的地址
  217.     SETB  IFDEC            ; BCD子程序参数,使其做减法
  218.     ACALL ADDBCD           ; 调用BCD子程序, 秒减1
  219.     CJNE  R3,#99H,OUTT0    ; 判断秒要否借位
  220.     MOV   SH,#05H          ; 要借位则
  221.     MOV   SL,#09H          ; 送数据59(否则显示99)
  222.     MOV   R0,#MH           ; 移入分位的地址
  223.     ACALL ADDBCD          ; 分减1
  224.     CJNE  R3,#99H,OUTT0    ; 判断分要否借位
  225.     MOV   MH,#05H
  226.     MOV   ML,#09H
  227.     MOV   R0,#HH
  228.     ACALL ADDBCD
  229. OUTT0:  POP   DPH         ; 恢复现场
  230.     POP   DPL
  231.     POP   PSW
  232.     POP   ACC
  233.     SETB  EA

  234.     RETI                   ; 中断返回
  235.     NOP
  236.     NOP
  237.     LJMP ERR               ; 软件陷阱
  238.     ;
  239. ;
  240. ;**************************
  241. ;   BCD子程序(加1或减1 )  ;
  242. ;**************************
  243. ADDBCD: MOV   A,@R0            ; 移入被操作数的高位
  244.     DEC   R0               ; 指针减一
  245.     SWAP  A
  246.     ORL   A,@R0            ; 移入被操作数的低位
  247.     MOV   B,#01H           ; B寄存器送立即数#01H
  248.     MOV   C,IFDEC          ; 若减法标志位为1,则
  249.     MOV   B.3,C            ;
  250.     MOV   B.4,C            ; B寄存器的值被改为#99H
  251.     MOV   B.7,C            ;
  252.     ADD   A,B              ; 对一个压缩的BCD码加#99H等于对其减一
  253.     DA    A                ; BCD码调整
  254.     MOV   R3,A             ; 暂存结果
  255.     ANL   A,#0FH           ; 取低位码
  256.     MOV   @R0,A            ; 存数
  257.     MOV   A,R3             ; 取回结果
  258.     INC   R0               ; 指针加一
  259.     SWAP  A                ; 交换
  260.     ANL   A,#0FH           ; 取结果数的高位
  261.     MOV   @R0,A            ; 存数
  262.     RET
  263.     NOP
  264.     NOP
  265.     LJMP  ERR              ; 软件陷阱
  266. ;
  267. ;**************
  268. ;   加1程序   ;
  269. ;**************
  270. ADDONE: MOV   R0,ADDRES        ; 移入被加数单元的地址
  271.     CLR   IFDEC            ; 设定BCD子程序做加法
  272.     ACALL ADDBCD           ; 调用BCD子程序
  273.     CLR   C                ; 判断被加数是否大于
  274.     MOV   A,R3             ; 最大值"MAX"
  275.     CJNE  A,MAX,JGOVER
  276. JGOVER: JC    ENDADO
  277.     CLR   A                ; 若大于"MAX",则清零
  278.     MOV   @R0,A
  279.     DEC   R0
  280.     MOV   @R0,A
  281. ENDADO: RET
  282.     NOP
  283.     NOP
  284.     LJMP  ERR              ; 软件陷阱
  285. ;
  286. ;******************
  287. ;   调时快进程序  ;
  288. ;******************
  289. QUICK:  CLR   LPLMOD         ; 设定显示方式不闪烁
  290.     CLR   HPLMOD
  291.     ACALL ADDONE           ; 调用加1子程序
  292.     MOV   L0,R4            ; 将工作模式选择数移入显存
  293.     INC   L0               ; 加1转化成显示值
  294.     ACALL KEYDLY           ; 延时
  295.     ACALL DL100
  296.     JNB   MKEY,QUICK       ; 判断键是否松开
  297.     SETB  LPLMOD           ; 若松开则恢复闪烁显示方式
  298.     CJNE  R6,#02H,ENDQUK
  299.     SETB  HPLMOD
  300.     CLR   LPLMOD
  301. ENDQUK: RET
  302.     NOP
  303.     NOP
  304.     LJMP  ERR              ; 软件陷阱
  305. ;
  306. ;
  307. ;******************
  308. ;   功能菜单程序  ;
  309. ;******************
  310. MENU:   MOV   R6,#00H        ; 初始化;  R6 计功能键按键次数
  311.     MOV   ADDRES,#05H      ; 将 R5 的地址送入,以便于改变 R4 的值
  312.     MOV   MAX, #04H        ; 定义工作模式选择寄存器R4 的最大值
  313.     MOV   DSPLYP,#L0       ; 定义显示指针指向显存
  314.     SETB  LPLMOD          ; 设定低两位数闪烁
  315.     CLR   HPLMOD
  316.     MOV   L0,R4            ; 送显示数据"F-0X"
  317.     INC   L0
  318.     MOV   L1,#00H
  319.     MOV   L2,#0BH
  320.     MOV   L3,#00H
  321.     SETB  LED4
  322. ;
  323. WAITFK: ACALL DISPLY           ; 等待F键释放
  324.         JNB   FKEY,WAITFK
  325. MENU1:  ACALL DISPLY
  326.     JB    MKEY,JGFKEY      ; M键扫描
  327.     ACALL KEYDLY           ; 延时消抖动
  328.     JB    MKEY,JGFKEY      ; 未按下则转F键扫描
  329.     CJNE  R6,#00H,NEXT1    ;
  330.     MOV   SL,#00H          ; 若中途改变定时方式,则清除原计时数据
  331.     MOV   SH,#00H
  332.     MOV   ML,#00H
  333.     MOV   MH,#00H
  334.     MOV   HL,#00H
  335.     MOV   HH,#00H
  336. NEXT1:  MOV   R2,#00H          ; R2用于判断按键时间是否超过0.5秒
  337. NEXT2:  ACALL ADDONE           ; 调用加1程序
  338.     MOV   L0,R4            ; 移入工作方式选择数
  339.     INC    L0
  340.     ;
  341. WAITMK: ACALL DISPLY         ; 等待M键释放
  342.     INC   R2               ; R2自增一
  343.     CLR   C
  344.     CJNE  R2,#0C8H,JGQUIC  ; 若R2大于等于200则调用快进子程序
  345. JGQUIC: JC    WATMK1
  346.         ACALL QUICK
  347. WATMK1: JNB   MKEY,WAITMK      ; R2小于200则等待M键释放
  348. ;
  349. JGFKEY: JB    FKEY,MENU1       ; 功能(F)键扫描
  350.     ACALL KEYDLY           ; 延时消抖动
  351.     JB    FKEY,MENU1       ; 键未按下则转修改(M)键扫描
  352.     INC   R6               ; F键按键次数加1
  353.     MOV   A,R6             ; 移入按键次数
  354.     RL    A            ; 指针放大
  355.     MOV   DPTR,#FUNTAB
  356.     JMP   @A+DPTR          ; 根据按键次数跳转到相应的程序段
  357. FUNTAB: AJMP  WAITFK
  358.     AJMP  SETLOW
  359.     AJMP  SETHI
  360.     AJMP  ENDMEN
  361.     NOP
  362.     NOP
  363.     AJMP  ENDMEN
  364. ;STWKMD:                       ; 工作模式设定,不需另外改变菜单
  365. ;
  366. SETLOW: MOV   MAX,#60H         ; 设置低位(秒位或分位)
  367.     MOV   A,R4             ; 移入工作模式选择数
  368.     RL    A            ; 指针放大
  369.     MOV   DPTR,#FTAB1
  370.     JMP   @A+DPTR          ; 根据工作模式选择数跳转到相应的程序段
  371. FTAB1:  AJMP  SETSS
  372.     AJMP  SETM60
  373.     AJMP  SETSS
  374.     AJMP  SETM60
  375.     NOP
  376.     NOP
  377.     AJMP  WAITFK
  378. SETSS:    MOV   DSPLYP,#SL       ; 设定显示区域为MM:SS
  379.     MOV   ADDRES,#SH
  380.     AJMP  WAITFK
  381. SETM60:   MOV   DSPLYP,#ML       ; 设定显示区域为HH:MM
  382.     MOV   ADDRES,#MH
  383.     AJMP  WAITFK
  384. ;
  385. SETHI:    CLR   LPLMOD           ; 设置高位(分位或时位)
  386.     SETB  HPLMOD           ; 高两位数码管闪烁
  387.     MOV   MAX,#31H         ; 最大数为30
  388.     MOV   A,R4             ; 移入工作模式选择数
  389.     RL    A                ; 指针放大
  390.     MOV   DPTR,#FTAB2      ; 移入表首地址
  391.     JMP   @A+DPTR          ; 根据工作模式选择数跳转到相应的程序段
  392. FTAB2:  AJMP  SETM30
  393.     AJMP  SETHH
  394.     AJMP  SETM30
  395.     AJMP  SETHH
  396.     NOP
  397.     NOP
  398.     AJMP  WAITFK           ; 返回等待键释放
  399. SETM30: MOV   ADDRES,#MH       ; 移入分位的地址
  400.         AJMP  WAITFK           ; 转向等待键释放
  401. SETHH:  MOV   ADDRES,#HH       ; 移入时位的地址
  402.     AJMP  WAITFK           ; 转向等待键释放
  403. ;
  404. ENDMEN: CLR   HPLMOD           ; 恢复不闪烁显示方式
  405.     RET
  406.     NOP
  407.     NOP
  408.     LJMP  ERR              ; 软件陷阱
  409. ;
  410. ;****************
  411. ;  到点工作程序 ;
  412. ;****************
  413. ACTION: MOV   L0,R4            ; 移入工作模式选择数
  414.     INC   L0               ; 送显示数"F-0X"
  415.     MOV   L1,#00H
  416.     MOV   L2,#0BH
  417.     MOV   L3,#00H
  418.     SETB  LED4
  419.     MOV   DSPLYP,#L0       ; 指针指向显存
  420.     SETB  LPLMOD           ; 设定显示方式不闪烁
  421.     SETB  HPLMOD
  422.     MOV   A,R4             ; 移入工作模式选择数
  423.     RL    A                ;
  424.     MOV   DPTR,#A_TAB
  425.     JMP   @A+DPTR          ; 根据工作模式选择数跳转
  426. A_TAB:  AJMP  ACTF1            ; 工作模式一
  427.     AJMP  ACTF1            ; 工作模式二
  428.     AJMP  ACTF3            ; 工作模式三
  429.     AJMP  ACTF3            ; 工作模式四
  430.     NOP
  431.     NOP
  432.     LJMP  ERR              ; 软件陷阱
  433. ACTF1:  SETB  SWITCH           ; 工作模式一(或二): 开继电器
  434. LJMP AAA
  435.     BBB: MOV   R_MOD,#82H       ; 响铃模式参数#82H
  436.     MOV   R2,#96H          ; 响铃次数参数#96H
  437. ACTF11: ACALL RING           ; 调用响铃子程序
  438.     JNB   MKEY,ENDACT      ; 等待键按下
  439.     JNB   FKEY,ENDACT      ; 有键按下则结束响铃
  440.     DJNZ  R2, ACTF11       ; 次数未满继续响铃
  441.     MOV   R_MOD,#0FFH      ; 参数#0FF使响铃无效
  442.     AJMP  ACTF11           ; 无键按下返回
  443.     NOP
  444.     NOP
  445.     LJMP  ERR              ; 软件陷阱
  446. ACTF3:  CLR   SWITCH           ; 工作模式三(或四): 开继电器
  447.     CLR   BELL             ; 蜂鸣器短鸣一声
  448.     ACALL DL1S
  449.     SETB  BELL
  450.     MOV   R_MOD,#0FFH      ; 响铃模式参数#0FFH
  451.     MOV   R2,#96H          ; 响铃时间参数#96H
  452. ACTF31: ACALL RING        ; 调用响铃子程序
  453.     JNB   MKEY,ENDACT      ; 等待键按下
  454.     JNB   FKEY,ENDACT      ; 有键按下则结束
  455.     DJNZ  R2,ACTF31        ; 次数未满继续
  456.     MOV   R2,#96H          ; 重新赋值
  457.     CLR   BELL             ; 短鸣一声(说明: 响铃模式参数#0FFH使
  458.     ACALL DL100            ; 响铃程序无效,仅起延时作用,
  459.     SETB  BELL             ; 每延时一段时间短鸣一声,以
  460.     AJMP  ACTF31           ; 提醒使用者继电器仍在工作)
  461.     NOP
  462.     NOP
  463.     LJMP  ERR              ; 软件陷阱
  464. ENDACT: SETB  SWITCH           ; 关继电器
  465. AWAITF: ACALL DISPLY           ; 调用显示
  466.         JNB   FKEY,AWAITF      ; 等待键释放
  467. AWAITM: ACALL DISPLY           ; 调用显示
  468.     JNB   MKEY,AWAITM      ; 等待键释放
  469.     RET
  470.     NOP
  471.     NOP
  472.     LJMP  ERR              ; 软件陷阱
  473.     ;
  474. ;**************
  475. ;   响铃程序  ;
  476. ;**************
  477. RING:   MOV   R5,#18H          ; R5为循环控制变量
  478. RING1:  JNB   MKEY,R_EXIT      ; 键扫描
  479.     JNB   FKEY,R_EXIT      ; 有键按下则退出
  480.     MOV   A,R_MOD          ; 移入响铃模式参数
  481.     MOV   C,ACC.7          ; 根据响铃模式参数改变响铃
  482.     MOV   BELL,C
  483.     RL    A
  484.     MOV   R_MOD,A
  485.     ACALL DL100            ; 延时
  486.     DJNZ  R5,RING1         ; 循环次数控制
  487. R_EXIT: SETB  BELL             ; 关闭响铃
  488.     RET
  489.     NOP
  490.     NOP
  491.     LJMP ERR               ; 软件陷阱
  492. ;
  493. ;**************
  494. ;   显示程序  ;
  495. ;**************
  496. DISPLY: PUSH  ACC              ; 数据压栈保护
  497.     PUSH  PSW
  498.     MOV   PSW,#10H         ; 选用寄存器组2
  499.     MOV   R0,DSPLYP        ; 移入显示指针
  500.     MOV   R2,#0FDH         ; R2寄存的是数码管选通数
  501.     MOV   A,PLYTS          ; 移入显示循环控制量
  502.     JNZ   PLAY             ; 不为0则转PLAY
  503.     MOV   PLYTS,#64H       ; 否则从新赋值
  504.     CPL   BRIGHT           ; 亮灭指示位取反
  505. PLAY:   DEC   PLYTS            ; 显示循环控制量减1
  506.     JNB   LPLMOD,PLAYL     ; 低两位数码管不闪则"PLAYL"
  507.     JB    BRIGHT,PLAYL     ; 亮灭指示为1也"PLAYL"
  508.     ACALL NOPLAY           ; 否则灭灯延时
  509.     AJMP  PLAY1            ; 转显示高位数码管
  510.     NOP
  511.     NOP
  512.     LJMP ERR               ; 软件陷阱
  513. ;用来显示低位
  514. PLAYL:  ORL   P1,#7FH          ; 清原显示数据
  515.     ORL   P3,#3CH          ; 清原选通数据
  516.     MOV   A,R2             ; 移入数码管位选数
  517.     RL    A                ; 换一位
  518.     ANL   P3,A             ; 选通低位的个位数码管
  519.     MOV   R2,A             ; 暂存位选数
  520.     MOV   A,@R0            ; 移入显示数值
  521.     MOV   DPTR,#TABLE1     ; 移入表首地址
  522.     MOVC  A,@A+DPTR        ; 查表
  523.     ANL   P1,A             ; 送显示数据
  524.     ACALL DL1MS            ; 延时
  525.     INC   R0               ; 指向低位的十位数
  526.     JB    P3.3,PLAYL       ; 显示低位的十位数
  527. ;
  528. PLAY1:  JNB   HPLMOD,PLAYH     ; 高两位数码管不闪则"PLAYH"
  529.     JB    BRIGHT,PLAYH     ; 亮灭指示为1也"PLAYH"
  530.     ACALL NOPLAY           ; 否则灭灯延时
  531.     AJMP  OUTPLY           ; 转结束
  532.     NOP
  533.     NOP
  534.     LJMP ERR               ; 软件陷阱
  535. ;
  536. ;用来显示高位
  537. PLAYH:  ORL   P1,#7FH          ; 清原显示数据
  538.     ORL   P3,#3CH          ; 清原选通数据
  539.     ANL   P3,#0EFH         ; 选通高位的个位数数码管
  540.     MOV   A,@R0            ; 移入显示数值
  541.     MOV   DPTR,#TABLE1     ; 移入表首地址
  542.     MOVC  A,@A+DPTR        ; 查表
  543.     ANL   P1,A             ; 送显示数据
  544.     ACALL DL1MS            ; 延时
  545.     INC   R0               ; 指向高位的十位数
  546.     ;                      ; 显示高位的十位数
  547.     ORL   P1,#7FH          ; 清原显示数据
  548.     ORL   P3,#3CH          ; 清原选通数据
  549.     ANL   P3,#0DFH         ; 选通高位的十位数
  550.     MOV   A,@R0            ; 移入显示数值
  551.     MOV   C,LED4          ; 指针放大+小灯状态
  552.     RLC   A                ;
  553.     MOV   DPTR,#TABLE2     ; 移入表首地址
  554.     MOVC  A,@A+DPTR        ; 查表
  555.     ANL   P1,A             ; 送显示数据
  556.     ACALL DL1MS            ; 延时
  557. ;
  558. OUTPLY: POP   PSW              ; 恢复数据
  559.     POP   ACC
  560.     RET
  561.     NOP
  562.     NOP
  563.     LJMP ERR               ; 软件陷阱
  564. ;
  565. TABLE1: DB  0C0H,0F9H,0A4H,0B0H, 99H, 92H, 82H,0F8H, 80H, 90H,0BFH, 8EH,0FFH
  566. ;           "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "-", "F", " "
  567. ;
  568. TABLE2: DB  0FFH, 0DFH, 0F9H, 0D9H, 0A4H,  84H, 0B0H,  90H, 0BFH, 09FH
  569. ;    "  ",  " :",   "1 ",  "1:",  "2 ",    "2:",  "3 ",  "3:",  "- ",  "-:"
  570. ;
  571. ;
  572. ;
  573. ;**********************
  574. ;    无显示(灭灯)程序   ;
  575. ;**********************
  576. NOPLAY: ORL   P1,#7FH          ; 清显示数据
  577.     ORL   P3,#3CH          ; 清选通数据
  578.     INC   R0               ; 指针自增2
  579.     INC   R0
  580.     ACALL DL1MS            ; 延时
  581.     RET
  582.     NOP
  583.     NOP
  584.     LJMP  ERR              ; 软件陷阱
  585.     ;
  586. ;******************
  587. ;     延时程序    ;
  588. ;******************
  589. DL1MS:  MOV   R3,#0F9H         ; 延时 1250US  只为DISPLY所调用
  590. DL1MS1: NOP
  591.     NOP
  592.     NOP
  593.     DJNZ  R3,DL1MS1
  594.     RET
  595.     NOP
  596.     NOP
  597.     LJMP  ERR              ; 软件陷阱
  598.     ;
  599. KEYDLY: CLR   BELL        ; 按键消抖动专用延时程序,
  600.     ACALL DISPLY           ; 在消除抖动的同时发出按键提示音
  601.     SETB  BELL
  602.     RET
  603.     NOP
  604.     NOP
  605.     LJMP ERR               ; 软件陷阱
  606. ;
  607. DL50MS: MOV   R7,#0AH          ; 50毫秒延时程序
  608. DL50M1: ACALL DISPLY         ; 每调用一次显示程序5MS
  609.     DJNZ  R7,DL50M1        ; 调用10次
  610.     RET
  611.     NOP
  612.     NOP
  613.     LJMP  ERR              ; 软件陷阱
  614. ;
  615. DL100:  ACALL DL50MS           ; 延时100毫秒
  616.     ACALL DL50MS
  617.     RET
  618.     NOP
  619.     NOP
  620.     LJMP  ERR              ; 软件陷阱
  621. ;
  622. DL05S:  ACALL DL100            ; 延时0.5秒
  623.     ACALL DL100
  624.     ACALL DL100
  625.     ACALL DL100
  626.     ACALL DL100
  627.     RET
  628.     NOP
  629.     NOP
  630.     LJMP  ERR              ; 软件陷阱
  631.     ;
  632. DL1S:   ACALL DL05S            ; 延时1秒
  633.     ACALL DL05S
  634.     RET
  635.     NOP
  636.     NOP
  637.     LJMP  ERR              ; 软件陷阱
  638.     ;
  639. ;****************************
  640. ;     ERR(出错处理) 程序    ;
  641. ;****************************
  642. ERR:    CLR   EA               ; 关中断
  643.     MOV   DPTR,#ERR1       ; 准备返回地址
  644.     PUSH  DPL              ; 压栈
  645.     PUSH  DPH              ;
  646.     RETI                   ; 中断返回
  647. ERR1:   MOV   56H,#0AAH        ; 建立上电标志(出错标志)
  648.     MOV   57H,#55H
  649.     MOV   A,#00H           ; 准备返回地址
  650.     PUSH  ACC              ; 压栈
  651.     PUSH  ACC
  652.     RETI                   ; 中断返回
  653.     NOP
  654.     NOP
  655.     LJMP  ERR              ; 软件陷阱
  656. ;
  657.     ORG   07FAH
  658.     NOP
  659.     NOP
  660.     NOP
  661.     LJMP  ERR              ; 软件陷阱
  662.     ;AAA:JNB P0.6,CCC
  663.     ;CCC:LJMP YINYUE

  664.                           ;LJMP DIANZIQIN
  665.                   DIANZIQIN:;MOV P0,#00H
  666.                          ;clr p3.6
  667.                         ;setb P0.1
  668.                          SETB EA
  669.                          SETB ET1                       ;计数器0
  670.                          MOV TMOD,#20H
  671.                          MOV TH1,#09CH
  672.                          MOV TL1,#09CH                 ;定时器初植
  673.                          CLR TR1                        ;定时器不允许
  674.                   SCAN:                                 ;键盘扫描
  675.                          MOV A,P2                   ;判断键盘按下,跳到SCAN_1,若未按,继续扫描
  676.                          CJNE A,#0FFH,SCAN_1
  677.                          NOP

  678.                          SJMP SCAN
  679.                   SCAN_1:
  680.                          ACALL DELAY ;是不是真的要按下?如果是,则跳转SU_KEY查询是哪个按下?
  681.                          MOV A,P2
  682.                          CJNE A,#0FFH,SU_KEY
  683.                          NOP
  684.                          SJMP SCAN
  685.                   SU_KEY:JNB P0.6,LOOP11
  686.                          ;SJMP LOOP2
  687.                    ;LOOP11:LJMP AAA
  688.                          JNB P2.1,MU_1                  ;判断是哪个键按下?
  689.                          JNB P2.2,MU_2
  690.                          JNB P2.3,MU_3
  691.                          JNB P2.4,MU_4
  692.                          JNB P2.5,MU_5
  693.                          JNB P2.6,MU_6
  694.                          JNB P2.7,MU_7
  695.                          SJMP SCAN
  696.                   LOOP11:LJMP AAA
  697.                                                            ;R1信号周期
  698.                   MU_1:  MOV R1,#19                ;如果第一个按键按下,则R1=19,同时程序转NEXT
  699.                          SJMP NEXT
  700.                   MU_2:  MOV R1,#17
  701.                          SJMP NEXT
  702.                   MU_3:  MOV R1,#15
  703.                          SJMP NEXT
  704.                   MU_4:  MOV R1,#14
  705.                          SJMP NEXT
  706.                   MU_5:  MOV R1,#13
  707.                          SJMP NEXT
  708.                   MU_6:  MOV R1,#11
  709.                          SJMP NEXT
  710.                   MU_7:  MOV R1,#10
  711.                          SJMP NEXT
  712.                   NEXT:  MOV A,R1
  713.                          MOV R0,A
  714.                          SETB TR1                      ;启动定时器0

  715.                   NEXT_1:MOV A,P2                     ; 没键按下继续执行,有键按下,返回读引脚
  716.                          CJNE A,#0FFH,NEXT_1
  717.                          ACALL DELAY
  718.                          MOV A,P2                       ;真的没键按下?
  719.                          CJNE A,#0FFH,NEXT_1
  720.                          CLR TR1                        ;不响
  721.                          AJMP SCAN                     ;扫描键盘去
  722.                   INT_1:                                 ;中断程序
  723.                         DJNZ R0,RE                      ;R0不等于0时,返回
  724.                         CPL P0.0
  725.                         MOV A,R1
  726.                         MOV R0,A
  727.                   RE:   RETI
  728.                   DELAY:MOV R7,#100                    ;延长时间等待,键盘消抖
  729.                   D1:   MOV R6,#10
  730.                   D2:   DJNZ R6,D2
  731.                         DJNZ R7,D1
  732.                         ;LJMP BBB
  733.                         RET


  734.      AAA:
  735.      SETB P3.6
  736. ;CLR P0.6
  737. MOV SP,#50H
  738. MOV TH1,#0D8H
  739. MOV TL1,#0EFH
  740. MOV TMOD,#10H
  741. MOV IE,#88H
  742. LJMP TIAO
  743. MUSIC0:;JB P0.6,QIN


  744. ;LJMP BBB
  745. TIAO:
  746. NOP
  747. MOV DPTR,#DAT ;表头地址送DPTR
  748. MOV 20H,#00H ;中断计数器清0
  749. MOV B,#00H ;表序号清0
  750. MUSIC1:
  751. ;JnB P0.1,duan
  752. NOP
  753. CLR A
  754. MOVC A,@A+DPTR ;查表取代码
  755. JZ END0 ;是00H,则结束
  756. CJNE A,#0FFH,MUSIC5
  757. LJMP MUSIC3
  758. duan:ljmp BBB
  759. MUSIC5:
  760. NOP
  761. MOV R6,A
  762. INC DPTR
  763. MOV A,B
  764. MOVC A,@A+DPTR ;取节拍代码送R7
  765. MOV R7,A
  766. SETB TR1 ;启动计数
  767. MUSIC2:

  768. ;clr P3.6
  769. NOP
  770. CPL P0.0
  771. MOV A,R6
  772. MOV R3,A
  773. LCALL DEL
  774. MOV A,R7
  775. CJNE A,20H,MUSIC2 ;中断计数器(20H)=R7否?
  776. ;不等,则继续循环
  777. ;JB P0.6,QIN
  778. ;jb p0.6,QIN
  779. ;jnb p0.4,ting
  780. MOV 20H,#00H ;等于,则取下一代码
  781. INC DPTR
  782.   ;JB P0.6,QIN
  783. ; INC B
  784. LJMP MUSIC1
  785. ;ting:ljmp BBB
  786. ;QIN:CLR TR1
  787. ;QIN:LJMP DIANZIQIN
  788. ;DIANZIQIN
  789. MUSIC3:
  790. NOP
  791. CLR TR1 ;休止100毫秒
  792. MOV R2,#0DH
  793. MUSIC4:
  794. NOP
  795. MOV R3,#0FFH
  796. LCALL DEL
  797. DJNZ R2,MUSIC4
  798. INC DPTR
  799. LJMP MUSIC1
  800. END0:
  801. NOP
  802. MOV R2,#64H ;歌曲结束,延时1秒后继续
  803. MUSIC6:
  804. MOV R3,#00H
  805. LCALL DEL
  806. DJNZ R2,MUSIC6
  807. LJMP MUSIC0
  808. DEL:
  809. NOP
  810. DEL3:
  811. MOV R4,#02H
  812. DEL4:
  813. NOP
  814. DJNZ R4,DEL4
  815. NOP
  816. DJNZ R3,DEL3
  817. RET
  818. NOP
  819. DAT:
  820. db 26h,20h,20h,20h,20h,20h,26h,10h,20h,10h,20h,80h,26h,20h,30h,20h
  821. db 30h,20h,39h,10h,30h,10h,30h,80h,26h,20h,20h,20h,20h,20h,1ch,20h
  822. db 20h,80h,2bh,20h,26h,20h,20h,20h,2bh,10h,26h,10h,2bh,80h,26h,20h
  823. db 30h,20h,30h,20h,39h,10h,26h,10h,26h,60h,40h,10h,39h,10h,26h,20h
  824. db 30h,20h,30h,20h,39h,10h,26h,10h,26h,80h,26h,20h,2bh,10h,2bh,10h
  825. db 2bh,20h,30h,10h,39h,10h,26h,10h,2bh,10h,2bh,20h,2bh,40h,40h,20h
  826. db 20h,10h,20h,10h,2bh,10h,26h,30h,30h,80h,18h,20h,18h,20h,26h,20h
  827. db 20h,20h,20h,40h,26h,20h,2bh,20h,30h,20h,30h,20h,1ch,20h,20h,20h
  828. db 20h,80h,1ch,20h,1ch,20h,1ch,20h,30h,20h,30h,60h,39h,10h,30h,10h
  829. db 20h,20h,2bh,10h,26h,10h,2bh,10h,26h,10h,26h,10h,2bh,10h,2bh,80h
  830. db 18h,20h,18h,20h,26h,20h,20h,20h,20h,60h,26h,10h,2bh,20h,30h,20h
  831. db 30h,20h,1ch,20h,20h,20h,20h,80h,26h,20h,30h,10h,30h,10h,30h,20h
  832. db 39h,20h,26h,10h,2bh,10h,2bh,20h,2bh,40h,40h,10h,40h,10h,20h,10h
  833. db 20h,10h,2bh,10h,26h,30h,30h,80h,00H

  834. END
复制代码





分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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