51单片机实用的汇编音乐程序

本人在网上看了很多关于汇编语言写的音乐程序,发现不容易理解,经过一天的尝试终于完成了汇编语言写的音乐程序,以两只老虎为例,方便大家学习,希望大神们提出宝贵的建议,第一次发代码,挺紧张的,希望大家喜欢。

/**********输出p2.4********/
org 0000h
ajmp main
org 000bh
ajmp timer0
org 001bh
ajmp timer1
org 0030h
main: 
mov tmod,#11h
mov th1,#3ch
mov tl1,#0b0h
mov  IE,#8ah 
mov r0,#0       //音阶和节拍的初始地址
mov r7,#0     //保存节拍初值
mov 20h,r0     //用20h保存音阶地址避免和节拍地址冲突
setb tr1
setb tf0

sjmp $

timer0:    
        mov dptr,#time
        mov a,20h           //送音阶地址
        movc a,@a+dptr
        rl a               //地址*2确定音阶定时初值
        mov b,a               //暂存
        mov dptr,#freq         //查频率表给T0赋值
        movc a,@a+dptr           //取高8位初值    
        mov th0,a
        mov a,b
        inc a                 //地址加一,取低8位初值    
        movc a,@a+dptr
        mov tl0,a
        setb tr0
        cpl p2.4          //输出脉冲
        reti
timer1:
       mov th1,#3ch          //定时50ms
       mov tl1,#0b0h
       cjne r7,#0,nequ       //r7用于中断次数,决定每个音节的长短
       mov dptr,#time
       inc r0               //取节拍时地址加一
       mov a,r0
       movc a,@a+dptr
       rl a                //节拍加倍,决定歌曲播放的快慢
       mov r7,a
       ajmp exit
nequ: djnz r7,exit        //判断一个音阶是否结束
      inc r0            //取下一个音阶地址加一
      mov 20h,r0       //暂存20h中
      mov a,r0           //判断是否为歌曲结束标志
      mov dptr,#time
      movc a,@a+dptr
      cjne a,#0ffh,exit
      clr tr0
      clr tr1
      clr ea
exit:
reti

/****音阶对应初始值*****/
freq:dw 0,63628,63835,64021,64103,64260,64399,64523    //低音1,2,3,4,5,6,7
      dw  64579,64684,64777,64819,64898,64968,65030    //中音
       dw    65058,65110,65157,65178,65217,65252,65282    //高音
/*************************/

/****音阶和节拍值*****/
time: db 8,4,9,4,10,4,8,4
    db     8,4,9,4,10,4,8,4
    db     10,4,11,4,12,8
    db     10,4,11,4,12,8
    db    12,3,13,1,12,3,11,1,10,4,8,4
    db    12,3,13,1,12,3,11,1,10,4,8,4
    db    9,4,5,4,8,8
    db    9,4,5,4,8,8,0xff
end

  • 28
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
抢答器是一种常见的电子竞赛设备,可以测试参赛者的反应速度和知识水平。下面是一个简单的51单片机抢答器汇编程序实现的示例: ``` ; 定义常量 TIMER_COUNT equ 10000 ; 定时器计数值 BUTTON1 equ P3.0 ; 按钮1输入 BUTTON2 equ P3.1 ; 按钮2输入 LED1 equ P2.0 ; LED1输出 LED2 equ P2.1 ; LED2输出 ; 定义变量 org 0x0000 MOV SP, #0x2F ; 初始化栈指针 MOV IE, #0x82 ; 开启定时器中断和总中断 MOV TMOD, #0x01 ; 定时器0工作在模式1 MOV TH0, #0x3C ; 初始化定时器高位计数值 MOV TL0, #0xB0 ; 初始化定时器低位计数值 SETB TR0 ; 启动定时器0 CLR LED1 ; 关闭LED1 CLR LED2 ; 关闭LED2 MOV A, #0x00 ; 清空抢答标志 MOV R7, A ; 把抢答标志保存在R7寄存器中 ; 定时器中断处理程序 TIMER_ISR: CLR TR0 ; 停止定时器0 MOV TH0, #0x3C ; 重新初始化定时器高位计数值 MOV TL0, #0xB0 ; 重新初始化定时器低位计数值 SETB TR0 ; 启动定时器0 INC A ; 定时器计数器加1 RETI ; 中断返回 ; 按钮1中断处理程序 BUTTON1_ISR: JB BUTTON1, $ ; 等待按钮1松开 CJNE A, #TIMER_COUNT, FAIL ; 判断是否抢答成功 SETB LED1 ; 点亮LED1 SETB R7.0 ; 抢答标志置1 JMP SUCCESS ; 跳转到抢答成功处理程序 FAIL: SETB LED2 ; 点亮LED2 SUCCESS: RETI ; 按钮2中断处理程序 BUTTON2_ISR: JB BUTTON2, $ ; 等待按钮2松开 CJNE A, #TIMER_COUNT, FAIL ; 判断是否抢答成功 SETB LED1 ; 点亮LED1 SETB R7.0 ; 抢答标志置1 JMP SUCCESS ; 跳转到抢答成功处理程序 FAIL: SETB LED2 ; 点亮LED2 SUCCESS: RETI ``` 以上程序的实现过程如下: 1. 设置定时器计数值为10000,即定时器中断周期为100ms; 2. 定义两个按钮输入引脚和两个LED输出引脚; 3. 初始化栈指针和中断控制寄存器; 4. 设置定时器0为模式1,初始化计数器值为0x3CB0,启动定时器0; 5. 在定时器中断处理程序中,重新初始化定时器计数值,并将计数器加1; 6. 在按钮1和按钮2的中断处理程序中,等待按钮松开,并判断是否在规定时间内按下按钮,如果成功则点亮LED1和抢答标志,否则点亮LED2; 7. 抢答完成后,程序返回中断处理程序,等待下一次抢答。 以上是一个简单的51单片机抢答器汇编程序实现示例,仅供参考。具体实现需要根据具体的硬件和应用场景进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值