首先需要知道的是PC机是通过什么来发声的,8255(A)可编程序外围接口芯片(PPI)。PPI有三个八位寄存器,两个用于输入,一个用于输出,而输出寄存器的I/O端口为61h,这是会在程序中体现的,而该输出寄存器端口号的第0位和第1位是选择扬声器的驱动方式。用汇编实现发声系统程序,有两种方式,一种是位触发方式,另一种是定时器方式。

其中位触发方式直接使61h的PB1交替置1和0来实现脉冲电流,控制扬声器从而交替打开和关闭,产生不同音高和不同音长的声音。

而定时器方式需要用到定时器内部的Counter2和控制寄存器,它们分别对应的端口号是42h和43h。在该方式中需要将一个控制字送入43h中(类似于计算机组成原理中的ROM微指令),控制字为8位,由高到低,前两位选择计数器,第3、4位选择计数器读写指示位,第5、6和7位选择操作模式(输出脉冲的形状),最后一位选择计数值格式(0为二进制,1为BCD码格式),另外42h存放的是计算得到的延迟时间。当然61h的0和1位需要都置为1。

实现了输出一个简谱音符的同时响相应的音,之前将输出音符放在了扬声器输出声音的后面,出现了声音延迟于音符输出,在数据段mes存放数据的开头增加一个空格依然无法同步,原因很简单,在主程序段中,di、bx和si是同步增加的,程序会将空格字符与一个声音对应起来。

最后,不要问我为什么后面输出的低阶sol没有显示成5下有个小点~~

下面是“两只老虎”的参考代码:

;************************************************************************************
datasg segment
       mus_freq   dw 262,294,330,262,262,294,330,262      ;频率决定音高
                  dw 330,349,392,330,349,392,392,440
                  dw 392,349,330,262,392,440,392,349
                  dw 330,262,294,196,262,294,196,262

mus_time   dw 2500,2500,2500,2500,2500,2500,2500,2500,2500,2500    ;节拍决定音长
                  dw 5000,2500,2500,5000,1200,1200,1200,1200,2500,2500
                  dw 1200,1200,1200,1200,2500,2500,2500,2500,5000,2500,2500,5000

mes    db 31h,32h,33h,31h,31h,32h,33h,31h,33h,34h,35h,33h,34h,35h,35h,36h
      db 35h,34h,33h,31h,35h,36h,35h,34h,33h,31h,32h,35h,31h,32h,35h,31h,'$'
    
datasg ends
;************************************************************************************
;************************************************************************************
codesg segment
    main    proc   far
         assume cs:codesg,ds:datasg
   org    100h     ;链接器将之后的程序放在0100h的开始位置
;-----------------------------------------------------
 start:
         push ds
   sub  ax,ax
   push ax
   mov  ax,datasg
   mov  ds,ax

            lea  di,mus_freq   ;频率
            lea  bx,mus_time   ;节拍
   lea  si,mes    ;音符
            mov  cx,32d;
;-----------------------------------------------------
 new_shot:  
            push cx
      call sound
   add  di,2
      add  bx,2
   add  si,1
   mov  cx,0ffffh
;-----------------------------------------------------
 silent:
   loop silent
         pop  cx
   loop new_shot
   mov  al,48h
         out  61h,al
           
   mov  ah,4ch
   int  21h
   
      ret
 main endp
 
;-----------------------------------------------------
sound proc near

mov  ah,02h    ;利用中断21h的02功能调用,显示音符简谱
   and  si,00ffh
   mov  dx,[si]
   int  21h

in  al,61h
   and  al,11111100b
  sing:
      xor  al,2    ;将PB1置1,打开扬声器
   out  61h,al

push ax
   call widnth
   pop  ax
   mov  cx,dx
  waits:
      loop waits    ;循环延迟,由此控制开关电路所产生脉冲的频率
      dec  WORD PTR [bx]  ;实现相应节拍的声音
   jnz  sing

and  al,11111100b  ;关闭扬声器
   out  61h,al
   ret       ;一轮实现了一个音的输出
  
sound endp
;----------------------------------------------------- 
;-----------------------------------------------------
widnth proc near     ;控制脉宽的计数值
            mov  ax,2801    
   push bx     ;保存的是节拍
   mov  bx,50
            mul  bx
   div  WORD PTR [di]  ;除以了相应的频率
   mov  dx,ax
   pop  bx
   ret
widnth endp
;-----------------------------------------------------
codesg ends  
;************************************************************************************   
 end start
;************************************************************************************



汇编实验——乐曲程序(两只老虎)相关推荐

  1. 音乐程序——两只老虎

    对照音符和发音频率(Hz)的对应关系,将曲谱翻译作程序中需要的数据,演奏出音乐来 低音符  频率 中音符  频率 高音符  频率 1         138 1           262 1    ...

  2. 51单片机两只老虎 c语言,基于51单片机做音乐盒(两只老虎)

    /********************************************************************************* 项目:音频音乐盒 设计时间:201 ...

  3. 51单片机两只老虎c语言程序,51单片机两只老虎仿真加代码

    /*************************************************************************** 程序名称:program4-1.c 程序功能: ...

  4. FPGA实现蜂鸣器播放音乐实验,以儿歌《两只老虎》为例

    ** FPGA实现蜂鸣器播放音乐 ** 实现功能: 开发板上电后,通过蜂鸣器播放<两只老虎>. 设计思路 原理:想要让蜂鸣器播放音乐,就需要知道每个音符的频率,再通过换算将频率转换为周期, ...

  5. python 常量_大疆机甲大师Python开发: 两只老虎

    大疆机甲大师演奏<两只老虎>https://www.zhihu.com/video/1168271599123320832 之前大疆机甲大师Python开发: 中文命名变量初尝试说到跳过了 ...

  6. 蜂鸣器播放《两只老虎》

    文章目录 前言 一.回顾蜂鸣器 二.乐谱知识 2.1 音符音频 2.2 两只老虎乐谱 三.系统框图 四.模块调用 五.模块原理图 六.工程源码 6.1 音符选择模块代码 6.2 pwm产生模块代码 6 ...

  7. 大疆机甲大师Python开发: 两只老虎

    大疆机甲大师教育机器人Python开发: 演奏<两只老虎> 之前大疆机甲大师Python开发: 中文命名变量初尝试说到跳过了"固件更新",今天打算试试,看到固件更新说明 ...

  8. 三元运算符案例(两只老虎、三个和尚)问题、分析、代码

    三元运算符 案例1:两只老虎 需求:动物园里有两只老虎,已知两只老虎的体重分别是180kg.200kg,请用程序实现判断两只老虎的体重是否相同. 分析: (1)定义两个变量用于保存老虎的体重,单位为k ...

  9. 计算机打音乐两只老虎,两只老虎(音乐、汇编程序)

    /* 程序效果:蜂鸣器发出两只老虎的音律 */ ORG 0000H AJMP START ORG 000BH AJMP TIM0 ORG 0030H START:     MOV TMOD,#01H ...

  10. 用鸿蒙OS在蜂鸣器上播放一曲《两只老虎》

    本文介绍如何在HiSpark Wi-Fi IoT套件上,使用Harmony OS IoT硬件子系统的PWM接口 驱动蜂鸣器 播放音乐. 用PWM输出方波的API 鸿蒙系统IoT硬件子系统提供了PWM相 ...

最新文章

  1. 高手过招, 为什么 Redis Cluster 是16384个槽位?
  2. 持续集成之jenkins基础
  3. python爬取岗位数据并分析_区块链岗位薪资高,Python爬取300个区块链岗位分析,龙虎榜出炉...
  4. shell中的$()、${}、$(())、(())
  5. 大量小文件存储提高效率要点详解
  6. WebRTC/Chromium在2020年的更新
  7. C#开源资源大汇总(2)
  8. Jedis连接Redis读写基本操作
  9. 【leetcode】数组建树
  10. 软件发明专利实例_软件系统专利申请案例
  11. uc看视频显示服务器有点忙,uc浏览器常见问题集锦(一)
  12. 使用scipy来进行曲线拟合
  13. 高效实现斐波那契数列(Fibonacci数列)
  14. vue中图片解析失败
  15. 获得《软件方法》代金券的同学列表-漏了麻烦告知
  16. 电脑可以使用QQ,但是无法上网的解决方案
  17. 组合数问题(NOIP2016提高组Day2T1)
  18. livp后缀文件图片怎么打开,在电脑怎么打开live照片批量转换?
  19. 从无到有:七步教你做数值(1)
  20. Web MIDI简介

热门文章

  1. 书单丨压箱底儿的10本传世计算机经典著作
  2. 摩尔庄园不同服务器账号互通吗,《摩尔庄园手游》数据互通情况说明 游戏服务器数据互通吗...
  3. 计算机硬件配件怎么查,如何查看计算机主板型号?主板型号在哪里[方法]
  4. [活动]2009年Linux内核开发者大会参与记录
  5. 【Altium Designer 19使用教程】Part1 工程及原理图的创建
  6. Python 爬虫之 Beautifulsoup4,爬网站图片
  7. c语言 srand was not,c语言srand生成随机数的问题
  8. python二维码_Python 二维码制作
  9. Java、储物柜难题
  10. Excel 文字转拼音