300 likes | 527 Views
第12章 发声系统的程序设计. 基本内容. 可编程内部定时器8253/54 通用发声程序 乐曲程序. 12.1 可编程内部定时器8253/54. 编程结构 工作方式 控制字 IBM PC 8253/54 定时器的使用. 编程结构. 8253/54定时器内部有3个独立工作的计数器:计 数器0、计数器1和计数器2,端口地址分别为40 H、41H 和42 H。 其中计数器0用于实时钟,计数器1用于 DMA 进行寄存器刷新,计数器2用于扬声器发声。每个计数器 中包含一个以倒计数的方式计数的16位计数寄存器。
E N D
基本内容 可编程内部定时器8253/54 通用发声程序 乐曲程序
12.1 可编程内部定时器8253/54 编程结构 工作方式 控制字 IBM PC 8253/54定时器的使用
编程结构 8253/54定时器内部有3个独立工作的计数器:计 数器0、计数器1和计数器2,端口地址分别为40H、41H 和42H。其中计数器0用于实时钟,计数器1用于DMA进行寄存器刷新,计数器2用于扬声器发声。每个计数器 中包含一个以倒计数的方式计数的16位计数寄存器。 8253/54内部还有一个公用的控制寄存器,端口地址为43H。 每个计数器由CLK、GATE和OUT 3个引脚与外部通信, 如下图所示,其中CLK为时钟输入端,GATE为门控信号, OUT为信号输出端。
数据总线 缓冲器 CLK0 GATE0 OUT0 计数器0 D0–D7 内 部总线 A0 A1 WR RD CS CLK1 GATE1 OUT1 读写 逻辑 计数器1 控制 寄存 器 CLK2 GATE2 OUT2 计数器2
工作方式 8253/54有6种可编程选择的工作方式。这6种工作方式的主要区别是输出波形不同,下面分别作以介绍。 1.方式0:计数结束产生中断 在这种方式下,计数器对CLK输入信号进行减法计 数,每一个时钟周期计数器减1。当设定该方式后,计 数器的OUT变低。设置装入计数值时也使输出OUT变低。 当计数减到0—计数结束时,输出OUT变高。该输出信 号可以作为中断请求信号来使用。
2.方式1:可编程单脉冲输出 当计数器的计数值装入计数器后,要由门控信号GATE上升沿 开始启动计数。同时计数器的OUT输出为低电平。当计数结束时, OUT输出为高电平。这样就可以从计数器的OUT端得到一个由GATE 上升沿开始,直到计数结束的负脉冲。若要再次获得一个所希望 宽度的负脉冲,则需要重新装入计数值并用GATE启动来达到。 3.方式2:频率发生器 在该方式下,计数器装入初值,开始工作后,计数器的输出 OUT将连续输出一个时钟周期宽的脉冲。两负脉冲之间的时钟周 期数就是计数器装入的计数初值。这样一来,就可以利用不同的 计数值达到对时钟脉冲的分频,而分频输出就是OUT输出。
4.方式3:方波发生器 这种方式下,可以得到对称的方波由OUT输出。当装 入计数值为N时,若N为偶数,则完成N/2计数OUT为高, 完成另外N/2计数时OUT为低,一直进行下去。若N为奇数, 则(N+1)/2计数时OUT保持高电平。而(N—1)/2计数 期间OUT为低电平。 5.方式4:软件触发选通 设置此方式后,输出OUT立即变为高电平,一旦装入 计数值,计数立即开始。当计数结束时,由OUT输出一个 宽度为一个时钟周期的负脉冲。
6.方式5:硬件触发选通 在设置此方式后,OUT输出为高电平。计数由GATE 的上升沿开始进行,当计数结束时由输出端OUT送出一 宽度为一个时钟周期的负脉冲。 在此方式下,GATE的电平高低不影响计数,只是 由GATE的上升沿启动计数开始。 若在计数结束前,又出现GATE上升沿,则计数从 头开始。
SC1 SC0 RL1 RL0 M2 M1 M0 BCD 控制字 8253/54的3个计数器是分别编程的,中央处理器通过写入控制命令字对8253/54进行编程,将控制字送入控制寄存器,设定8253/54的工作方式。8253/54控制寄存器中的控制字节格式如下: D7 D6 D5 D4 D3 D2 D1 D0
D0:选择计数器格式 0:二进制计数 1:BCD码格式 D1、D2、D3:选择工作方式 000:方式0 001:方式1 x10:方式2 x11:方式3 100:方式4 101:方式5 D4、D5:选择读写方式 00:将计数器中的数据锁存于缓冲器 01:选择计数器的低8位读写 10:选择计数器的高8位读写 11:先读写低8位计数值,后读写高8位计数值 D6、D7:选择计数器 00:计数器0 01:计数器1 10:计数器2 11:非法
例:按要求写出8253的初始化程序:将计数器0设为模式3,计数初始值为2000(BCD码)。 MOV AL,00110111B ;设定控制字 OUT 43H,AL ;控制字送控制寄存器 MOV AX,2000H OUT 40H,AL MOV AL,AH OUT 40H,AL
IBM PC 8253/54定时器的使用 在PC系列微机系统中,8254/53的3个时钟输入端 (CLK0、CLK1、CLK2)的输入频率均为1.1931816MHz。 IBM公布的软件BIOS中有专门对8253初始化的程序 。 下面是计数器0的初始化程序: MOV AL,00110110H ;选择计数器0,双字节,方式3,十六进制 OUT 43H,AL ;写入控制器 MOV AL,0 ;初值为0000H(即65636) OUT 40H,AL ;写低字节 OUT 40H,AL ;写高字节
计数器1专门用做动态随机存储器刷新的定时控制,计数器1专门用做动态随机存储器刷新的定时控制, 下面是计数器1的初始化程序: MOV AL,01010100H ;选择计数器1,只写低字节,方 式2,二进制 OUT 43H,AL ;写入控制器 MOV AL,18 ;将低字节计数值18写入 OUT 41H,AL ;计数器1 门控GATE1接+5V,输出0UT1通过D型触发器产生存 储器刷新请求信号DRQ0,DRQ0是DMA控制器通道0的请 求信号。刷新分频数设为18,因此,在OUT1输出周期 为18/1.1931816 MHz(即约15μs)的脉冲序列。
计数器2产生扬声器频率信号,控制扬声器发声。计数器2产生扬声器频率信号,控制扬声器发声。 下面是计数器2的初始化程序: MOV AL,10110110H ;选择计数器2,写双字节, 方式3,二进制数 OUT 43H,AL ;写入控制器 MOV AX,533H ;初值为533H OUT 42H,AL ;送低字节 MOV AL,AH OUT 42H,AL ;送高字节 计数器2工作于方式3。门控GATE2与8255的端口PB0 相连,输出0UT2产生频率为896Hz的方波,因此将计数器 2的计数初值设为533H(1.1931816MHz/896Hz=533H)。
选择A端口来源 定时器2闸门 扬声器数据 禁止键盘时钟脉冲 允许扩展槽错误信息 选择C端口来源 允许RMA工作 开动盒带马达 12.2 通用发声程序 扬声器驱动方式 PC机可以通过两种方法产生声音,这两种方法都与并行接口芯片8255有关 , 8255有3个8位端口和一个控制寄存器,端口地址分别为60H、61H、62H和63H。60H端口和62H端口用于输入,61H端口用于输出,这3个端口分别称为PA、PC、PB,63H端口用于设置8255的工作方式。8255 PB口各位含义如下图所示。
8255PB D1 与 门 放大器 扬声器 脉冲信号 CLOCK OUT2 GATE2 8255PB D0 一种方法是通过输入/输出指令向设备寄存器的D1位交替送0和1,使与其相连的扬声器脉冲门产生连续的脉冲电流,驱动扬声器发声。 第二种方法是利用8253/54可编程定时器驱动扬声器。如下图所示,和扬声器相连的是定时器2,门控GATE2与端口61H的D0位相连,该位为1时,允许定时器2工作在方式3。输出OUT2与端口61H的D1位通过一个与门和扬声器的驱动电路相连,该位为1时,允许输出信号送到扬声器电路。
BIOS中的BEEP子程序能控制8253/54定时器,产生频率为896 Hz、持续时间为0.5秒倍数的声音。程序设计中可以对BEEP程序作以修改,使其不仅能产生任一频率的声音,而且能调整声音的持续时间。 由于计数器的输入频率为1.1931816M Hz,所以用下式: 1193100÷要求频率=12348H÷要求频率 计算出计数值,将该值作为初值送计数器2,就可以实现: MOV DX,12H MOV AX,348CH DIV DI 通用发声程序
;功能:产生任一频率的声音 ;入口参数:BX=时间延时的计数初值 DI=指定的发声频率 PUBLIC GENSOUND CODE SEGMENT PARA‘CODE’ ASSUME CS:CODE UNSOUND PROC FAR PUSH AX PUSH BX PUSH CX 例:通用发声程序GENSOUND。
PUSH DX PUSH DI MOV AL,0B6H ;初始化定时器2 OUT 43H,AL MOV DX,12H MOV AX,348CH ;设置输入频率 DIV DI OUT 42H,AL MOV AL,AH OUT 42H,AL IN AL,61H ;读8255状态 MOV AH,AL
OR AL,3 ;设置61H端口的D0和D1位 OUT 61H,AL WAIT: MOV CX,1400 ;设定延时 DELAY: LOOP DELAY DEC BX JNZ WAIT MOV AL,AH OUT 61H,AL POP DI POP DX POP CX
POP BX POP AX RET UNSOUND ENDP CODE ENDS END 说明:8088/86系统时钟频率为4.7M Hz,即时钟周期约212ns,CPU执行一条LOOP指令需要17个时钟周期,所以该程序中的延时设定值为5ms(1400*17*212ns)。
12.3 乐曲程序 音调与频率和时间的关系 为了编写能发出乐曲音调的声音,可以利用计算机 控制发声的原理,通过对8253编程来实现。下表给出了 两个音节的音符与频率之间的关系。 从表中可以看出声音频率值和脉冲频率值有如下关 系:脉冲频率=1193181/声音频率。
音符 脉冲 频率 声音 频率 音符 脉冲 频率 声音 频率 1 9104 131 2 4056 294 2 8113 147 3 3614 330 3 7228 165 4 3417 349 4 6815 175 5 3042 392 5 6085 196 6 2710 440 6 5421 220 7 2415 494 7 4828 247 1 2280 523 1 4452 262 音符与频率之间的关系
演奏乐曲的程序 明确了音调与频率和时间的关系,设计程序时, 就可以按照乐谱在数据段中定义两个存储区,将每个 音符所对应的频率和延时时间值分别放在两个存储区 中,在代码段中依次取出表中的频率值和时间值,实 现演奏。
DATA SEGMENT MUSIF DW 196,220,262,294,330,2 DUP(392) DW 440,392,2 DUP(330),294,3 DUP(262),220,220,262 DW 294,196,220,262,294,330,2 DUP(392) DW 440,392,330,330,294,3 DUP(262),220,220,196 DW 3 DUP(262),294,262,294,330,349 DW 392,392,440,392,330,392,3 DUP(440),392,330 DW 294,262,294,196,220,262,294,330,392,392 DW 440,392,2DUP(330),294,3DUP(262),220,220,196,262 DW -1 ;以上为频率表 例:《萍聚》乐曲演奏程序如下:
MUSIT DW 2 DUP(12),38,12,25,12,12 DW 38,12,25,12,12,38,5 DUP(12) DW 75,12,12,38,12,25,12,12 DW 38,12,25,12,12,38,5 DUP(12) DW 75,12,12,38,12,25,12,12 DW 38,6,6,25,12,12,38,12,25,12,12 DW 38,12,25,12,12,38,12,25,12,12 DW 38,12,25,12,12,38,5 DUP(12),100 ;以上为节拍时间表 DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA
MAIN PROC FAR START: MOV AX,DATA MOV DS,AX LEA SI,MUSIT ;频率表偏移地址 LEA BP,DS:MUSIF ;时间表偏移地址 VOIM: MOV DI,[SI] CMP DI,-1 JE ENDF MOV BX,DS:[BP] MOV AL,0B6H OUT 43H,AL MOV DX,12H MOV AX,348CH DIV DI OUT 42H,AL
MOV AL,AH OUT 42H,AL IN AL,61H MOV AH,AL OR AL,3 ;打开扬声器 OUT 61H,AL WAIT1: MOV CX,1400 LONG: LOOP LONG DEC BX JNZ WAIT1 MOV AL,AH OUT 61H,AL ;复位端口 ADD SI,2 ADD BP,2 JMP VOIM
ENDF: MOV AX,4C00H INT 21H CODE ENDS END START 从上面的程序中可以看出,编写乐曲程序分为3个步骤: (1)在数据段中为要演奏的乐曲定义一个声音频率表和一个节拍时间表。 (2)将声音频率表和节拍时间表的偏移地址送SI和BP (3)从声音频率表和节拍时间表中取出数据分别送入DI和BX