ORG 0000H
LJMP START
ORG 000BH
INC 20H 中断服务,中断计数器加1
MOV TH0,#0D8H
MOV TL0,#0EFH 12M晶振,形成首昌早10毫秒中断
RETI
START:
MOV SP,#50H
MOV TH0,#0D8H
MOV TL0,#0EFH
MOV TMOD,#01H
MOV IE,#82H
MUSIC0:
NOP
MOV DPTR,#DAT 表头地址送DPTR
MOV 20H,#00H 中断计数器清0
MOV B,#00H 表序号清0
MUSIC1:
NOP
CLR A
MOVC A,@A+DPTR 查表取代码
JZ END0 是00H,则结束
CJNE A,#0FFH,MUSIC5
LJMP MUSIC3
MUSIC5:
NOP
MOV R6,A
INC DPTR
MOV A,B
MOVC A,@A+DPTR 取节拍代码送R7
MOV R7,A
SETB TR0 启动计数
MUSIC2:
NOP
CPL OUT
MOV A,R6
MOV R3,A
LCALL DEL
MOV A,R7
CJNE A,20H,MUSIC2 中断计数器(20H)=R7否?
不等,则继续者雀循环
MOV 20H,#00H 等于,则取下一代码
INC DPTR
INC B
LJMP MUSIC1
MUSIC3:
NOP
CLR TR0 休止100毫秒
MOV R2,#0DH
MUSIC4:
NOP
MOV R3,#0FFH
LCALL DEL
DJNZ R2,MUSIC4
INC DPTR
LJMP MUSIC1
END0:
NOP
MOV R2,#64H 歌曲迅弯结束,延时1秒后继续
MUSIC6:
MOV R3,#00H
LCALL DEL
DJNZ R2,MUSIC6
LJMP MUSIC0
DEL:
NOP
DEL3:
MOV R4,#02H
DEL4:
NOP
DJNZ R4,DEL4
NOP
DJNZ R3,DEL3
RET
NOP
DAT:
db 26h,20h,20h,20h,20h,20h,26h,10h,20h,10h,20h,80h,26h,20h,30h,20h
db 30h,20h,39h,10h,30h,10h,30h,80h,26h,20h,20h,20h,20h,20h,1ch,20h
db 20h,80h,2bh,20h,26h,20h,20h,20h,2bh,10h,26h,10h,2bh,80h,26h,20h
db 30h,20h,30h,20h,39h,10h,26h,10h,26h,60h,40h,10h,39h,10h,26h,20h
db 30h,20h,30h,20h,39h,10h,26h,10h,26h,80h,26h,20h,2bh,10h,2bh,10h
db 2bh,20h,30h,10h,39h,10h,26h,10h,2bh,10h,2bh,20h,2bh,40h,40h,20h
db 20h,10h,20h,10h,2bh,10h,26h,30h,30h,80h,18h,20h,18h,20h,26h,20h
db 20h,20h,20h,40h,26h,20h,2bh,20h,30h,20h,30h,20h,1ch,20h,20h,20h
db 20h,80h,1ch,20h,1ch,20h,1ch,20h,30h,20h,30h,60h,39h,10h,30h,10h
db 20h,20h,2bh,10h,26h,10h,2bh,10h,26h,10h,26h,10h,2bh,10h,2bh,80h
db 18h,20h,18h,20h,26h,20h,20h,20h,20h,60h,26h,10h,2bh,20h,30h,20h
db 30h,20h,1ch,20h,20h,20h,20h,80h,26h,20h,30h,10h,30h,10h,30h,20h
db 39h,20h,26h,10h,2bh,10h,2bh,20h,2bh,40h,40h,10h,40h,10h,20h,10h
db 20h,10h,2bh,10h,26h,30h,30h,80h,00H
END
NUM EQU 30HUP EQU P3.6
DN EQU P3.7
ORG 0000H
AJMP START Fosc=12MHz
ORG 000BH T0 中断入口地址
AJMP INT_T0
ORG 001BH T1 中断入口地址
AJMP INT_T1
START:
MOV SP, #60H
MOV TMOD, #11H
MOV IE, #8AH
MOV IP, #08H T1中断优先于T0中断
MOV TH1, #3CH
MOV TL1, #0BH 以上为系统初始化,T=60ms
W1: MOV P2, #01110001B 等待提示"F" ,01110001
LCALL GETKEY
CJNE A, #0FFH, W1
MOV A, B
CJNE A, #0AH, W2
LCALL KEY_A 输入键是'A',转KEY_A
SJMP W1
W2: CJNE A, #0BH, W3
LCALL KEY_B 输入键是'B',转KEY_B
W3: CJNE A, #0CH, W4
LCALL KEY_C 段芦族 输入键是'C',转KEY_C
W4: CJNE A, #0DH, W5
LCALL KEY_D
SJMP W1 输入键是'D',转KEY_D
W5: CJNE A,#0EH,W6 下一首
INC NUM
MOV A,NUM
CJNE A,#4,W51
W51:
JC W52
MOV NUM,#0
W52:
MOV A,NUM
SJMP D0
W6: CJNE A,#0FH,W7 上一首
MOV A,NUM
JNZ W61
MOV NUM,#4
W61:
DEC NUM
MOV A,NUM
SJMP D0
W7:
SJMP W1
KEY_A: 从1~4按顺序播放
LCALL MUSIC1 乐曲《我和你》
LCALL MUSIC2 乐曲《万水千山总是情》
LCALL MUSIC3 乐曲《送别》
LCALL MUSIC4 乐曲《北京欢迎您》
RET
KEY_B: 从1~4循环播放
T11: LCALL KEY_A
SJMP T11
RET
KEY_C: 循环播放某一乐曲
T3: LCALL GETWORD
CJNE A, #0FFH, T3
MOV A, B
D0:
JNZ D1
SJMP E0
D1: DEC A
JNZ D2
SJMP E1
D2: DEC A
JNZ E3
SJMP E2
E0: LCALL MUSIC1 乐曲《我和你》
SJMP E0
E1: LCALL MUSIC2 乐曲《万水千山总是情》
SJMP E1
E2: LCALL MUSIC3 握弊 乐曲《送别》
SJMP E2
E3: LCALL MUSIC4 乐曲《北京欢迎您》
SJMP E3
RET
KEY_D: 从某一乐曲开始播放,播放完后停止
T2: LCALL GETWORD
CJNE A, #0FFH, T2
MOV A, 哗迹B
CJNE A, #00H, B1
SJMP C0
B1: CJNE A, #01H, B2
SJMP C1
B2: CJNE A, #02H, C3
SJMP C2
C0: LCALL MUSIC1 乐曲《我和你》
C1: LCALL MUSIC2 乐曲 《万水千山总是情》
C2: LCALL MUSIC3 乐曲《送别》
C3: LCALL MUSIC4 乐曲《北京欢迎您》
RET
MUSIC1: 第一首《我和你》
MOV P2, #00000110B 显示1,00000110
MOV R5, #11111001B
MOV 52H, #HIGH TABLE10
MOV 53H, #LOW TABLE10
MOV NUM,#0
LCALL music
RET
MUSIC2: 第二首《万水千山总是情》
MOV P2, #01011011B 显示2,01011011
MOV R5, #10100100B
MOV 52H, #HIGH TABLE20
MOV 53H, #LOW TABLE20
MOV NUM,#1
LCALL music
RET
MUSIC3: 第三首《送别》
MOV P2, #01001111B 显示3,01001111
MOV R5, #10110000B
MOV 52H, #HIGH TABLE30
MOV 53H, #LOW TABLE30
MOV NUM,#2
LCALL music
RET
MUSIC4: 第四首《北京欢迎您》
MOV P2, #01100110B 显示4,01100110
MOV R5, #10011001B
MOV 52H, #HIGH TABLE40
MOV 53H, #LOW TABLE40
MOV NUM,#3
LCALL music
RET
music: MOV R3,#00H 音乐解码器
NEXT20:
MOV A,P3
ORL A,#0C0H
MOV P3,A
MOV A,P3
CPL A
ANL A,#0C0H
JZ NEXT21
POP ACC
POP ACC
LJMP W1
RET
NEXT21:
MOV A, R3
MOV DPH, 52H
MOV DPL, 53H
MOVC A, @A+DPTR
MOV R2, A
JZ STOP
ANL A, #0FH
MOV R1, A
MOV A, R2
SWAP A
ANL A, #0FH
JNZ SING
CLR TR0
JMP W11
----------------------------------------------------------
SING:
DEC A
MOV 22H, A
RL A
MOV DPTR, #TABLE00
MOVC A, @A+DPTR
MOV TH0, A
MOV 21H, A
MOV A, 22H
RL A
INC A
MOVC A, @A+DPTR
MOV TL0, A
MOV 20H, A
SETB TR0
SETB TR1
W11:
LCALL DELAY3
INC R3
LJMP NEXT20
-----------------------------------------------------------
STOP:
CLR TR0
CLR TR1
RET
***************************************************
定时器0中断子程序
***************************************************
INT_T0:
CLR TR0
MOV TL0, 20H
MOV TH0, 21H
CPL P3.0
SETB TR0
RETI
***************************************************
定时器1中断子程序
***************************************************
INT_T1:
CLR TR1
CLR TR0
LCALL KEY_E
MOV TH1, #3CH
MOV TL1, #0BH
DJNZ 60H, OUT
MOV 60H, #20
OUT:
SETB TR1
RETI
KEY_E:
JB P3.1, L2 中断键盘检测
LCALL DELAY2 消除抖动
JB P3.1, L2 如果是高电平就跳到L2
JNB P3.1, $ 如果仍然是低电平就执行中断程序
MOV P2, #0111100B 让LED显示E,01111001
L3: JB P3.1, $ 检测低电平,直到低电平时才跳出该指令
LCALL DELAY2
JB P3.1, L3
JNB P3.1, $ 如果再来一个高电平才跳出中断
MOV P2,R5
L2: SETB TR0
RET
GETKEY: 读A B C D键盘子程序
SA: JB P1.0, SB 读A,是高电平表示没有按键,跳转到SB
LCALL DELAY2
JB P1.0, SA
JNB P1.0, $
MOV P2, #01110111B 显示A,01110111
MOV R5, #10001000B
MOV A, #0FFH
MOV B, #0AH
RET
SB: JB P1.1, C11 读B,是高电平表示没有按键按下,跳转到C11
LCALL DELAY2
JB P1.1, SB
JNB P1.1, $
MOV P2, #01111100B 显示B,01111100
MOV R5, #10000011B
MOV A, #0FFH
MOV B, #0BH
RET
C11:JB P1.2, ED1 读C
LCALL DELAY2
JB P1.2, C11
JNB P1.2, $
MOV P2, #00111001B 显示C,00111001
MOV R5, #11000110B
MOV A, #0FFH
MOV B, #0CH
RET
ED1:
JB P1.3, L0 读D
LCALL DELAY2
JB P1.3, ED1
JNB P1.3, $
MOV P2, #01011110B 显示D,01011110
MOV R5, #10100001B
MOV A, #0FFH
MOV B, #0DH
L0: JB UP,L01
LCALL DELAY2
JB UP,L01
JNB UP,$
MOV A,#0FFH
MOV B,#0EH
RET
L01:
JB DN,L02
LCALL DELAY2
JB DN,L02
JNB DN,$
MOV A,#0FFH
MOV B,#0FH
L02:
RET
GETWORD: 读音乐序号子程序
S1: JB P1.4, S2 读1键
LCALL DELAY2
JB P1.4, S1
JNB P1.4, $
MOV P2, #00000110B 显示1
MOV R5, #11111001B
MOV A, #0FFH
MOV B, #00H
RET
S2: JB P1.5, S3 读2键
LCALL DELAY2
JB P1.5, S2
JNB P1.5, $
MOV P2, #01011011B 显示2
MOV R5, #10100100B
MOV A, #0FFH
MOV B, #01H
RET
S3: JB P1.6,S4 读3键
LCALL DELAY2
JB P1.6,S3
JNB P1.6,$
MOV P2,#01001111B 显示3
MOV R5,#10110000B
MOV A,#0FFH
MOV B,#02H
RET
S4: JB P1.7, L1 读4键
LCALL DELAY2
JB P1.7, S1
JNB P1.7, $
MOV P2, #01100110B 显示4
MOV R5, #10011001B
MOV A, #0FFH
MOV B, #03H
L1: RET
DELAY: 延时子程序
PUSH 0 保存现场
PUSH 1
MOV 0, #0H
DELAY1: MOV 1, #0H
DJNZ 1, $
DJNZ 0, DELAY1
POP 1 恢复现场
POP 0
RET
DELAY2: MOV 41H, #100 延时子程序2
F1: MOV 42H, #250
DJNZ 42H, $
DJNZ 41H, F1
RET
DELAY3: 延时子程序3
MOV R7, #2
W22: MOV R4, #125
W33: MOV R0, 248
DJNZ R0, $
DJNZ R4, W33
DJNZ R7, W22
DJNZ R1, DELAY3
RET
TABLE00: 频率表
DW 64260,64400,64524,64580 简码值 低音5, 低音6, 低音7,1
DW 64684,64777,64820,64898 简码值 2,3,4,5
DW 64968,65030,65058,65110 简码值 6,7,高音1,高音
DW 65157,65178,65217 简码值 高音3,高音4,高音5
--------------------------------------------------------------------
第一首《我和你》
--------------------------------------------------------------------
TABLE10: DB 64H,82H,42H,48H
DB 54H,64H,18H
DB 44H,54H,64H,84H
DB 5CH
DB 64H,84H,44H,04H,42H
DB 54H,64H,28H
DB 54H,14H,54H,64H
DB 4CH
DB 98H,88H
DB 98H,48H
DB 64H,24H,64H,84H
DB 5CH
DB 64H,82H,42H,48H
DB 54H,64H, 28H
DB 54H,14H,54H,34H
DB 4CH
DB 00H
--------------------------------------------------------------------
第二首《万水千山总是情》
--------------------------------------------------------------------
TABLE20: DB 64H,74H,84H,04H,82H,94H,84H,6CH
DB 54H,44H,04H,62H,54H,44H,2CH
DB 24H,18H, 44H,54H,64H,84H,94H,64H,5CH
DB 64H,74H,84H,04H,82H,94H,84H,6CH
DB 54H,44H,04H,62H,54H,44H,2CH
DB 24H,18H, 44H,64H,54H,04H,42H,24H,44H,4CH
DB 64H,84H,9CH,0A4H,94H,74H,84H,04H,92H,8CH,64H,88H
DB 64H,84H,9CH,0A4H,0A4H,94H,84H,64H,5CH
DB 64H,74H, 84H,04H,82H,94H,84H,6CH
DB 54H,44H,04H,62H,54H,44H,2CH
DB 24H,18H,44H,64H,54H,42H,24,44H,4CH
DB 00H
--------------------------------------------------------------------
第三首《送别》
--------------------------------------------------------------------
TABLE30: DB 84H,62H,82H,0B8H
DB 94H,0B2H,92H,88H
DB 84H,42H,52H,64H,52H,44H
DB 5CH
DB 84H,62H,82H,0B4H,04H,82H
DB 94H,0B4H, 88H
DB 84H,52H,62H,74H,04H,32H
DB 4CH
DB 94H,0B4H,0B8H
DB 0A4H,92H,0A2H,0B8H
DB 92H,0A2H,0B2H,92H,92H,82H,62H,42H
DB 5CH
DB 84H,62H,82H,0B4H,04H,0A2H
DB 94H,0B4H,88H
DB 84H,52H,62H,74H,04H,32H
DB 4CH
DB 00H
--------------------------------------------------------------------
第四首《北京欢迎您》
--------------------------------------------------------------------
TABLE40: DB 62H,82H,62H,52H,12H
DB 62H,52H,12H,64H
DB 62H,52H,22H,42H
DB 62H,54H
DB 52H,42H,22H,42H
DB 52H,62H,82H,52H
DB 62H,92H,82H,12H
DB 52H,44H
DB 52H,42H,22H,42H
DB 52H,62H,82H,52H
DB 62H,92H,82H,82H
DB 68H
DB 52H,62H,52H,42H
DB 82H,92H,64H
DB 22H,62H,64H
DB 54H,64H
DB 64H,84H
DB 0B2H,82H,94H
DB 02H,92H,82H,62H
DB 62H, 82H,88H
DB 00H
END
有图,Q我1352282
一. 设计任务及要求
1. 以8255接八个开关K1~K8,做电子琴按键输入。
2. 以8253控制扬声器,拨动不同的开关,发出相应的音阶。
要求: K1—静音
K2—发si的音493Hz
K3—发la的音440Hz
K4—发sol的音392Hz
K5—发fa的音349Hz
K6—发mi的音329Hz
K7—发re的音293Hz
K8—发do的音261Hz
二. 方案比较和认证
通过8255和8253来实现电子琴模拟,主要可以分成两部分,分别为输入部分和发音部分。输入部分主要是由8255和8个常开型开关来完成。常开型开关如右图。8个常开型开关K1~K8与8255的A口PA0~PA7相接,不触动开关时,为高电平输入,当按下开关时,就接地,为低电平输入枝纳。例如当K1键按下时,从8255中A口输入的数为11111110B,十六进制为0FEH。每一个开关按下时,都对应一个ASCII码,如下表所示:
开 关 K1 K2 K3 K4 K5 K6 K7 K8
对应数据 0FEH 0FDH 0FBH 0F7H 0EFH 0DFH 0BFH 7FH
对应频率 静音 493 Hz 440 Hz 392 Hz 349 Hz 329 Hz 293 Hz 261 Hz
输入部分的硬件实现比较简单,所以说主要还是在发音部分。在设计中驱动扬声器地声的主要有两种方式,分别是以位触发和定时器控制。下面就这两种不同的方式确定两个不同的设计方案。
方案1:
发声采用位猛氏没触发方式。电路原理图如下所示。程序直接控制PPI(8255可编程序外围接口芯片)的输出控制寄存器(I/O端口为61H)的第一位,使该位按所需的频率进行1和0的交替变化,从而产生一串脉冲控制波形,这些脉冲经过放大后驱动扬声器发出声音。
可以利用软件延时来控制所产生的脉冲波形的长度和脉宽,就可以实现产生不同频率和不同音长的声音。软件实现的程序如下:
IN AL,61H
MOV AH,AL
AND AL,0FCH ;关断定时器通道2的门控
SOUND:XOR AL,2 ;触发61H端口第1位
OUT 61H,AL
MOV CX,DX;(DX)=控制脉冲的计数值
WAIT: LOOP WAIT ;延时循环
DEC BX;(BX)=脉冲持续的时间
JNZSOUND
MOV AL,AH
OUT61H,AL ;恢复61H端口
在本方案中,通过程序的方法来控制PB1,使其在1和0之间按一定的频率变,从而产生一串脉冲。控制脉冲宽度的计数值的算法如下:
计数值=2801*100/音频
如果音频为f,则脉冲周期1/f一个半波的时间为1/2f秒,而1/2f秒的延时可简单地通过LOOP指令的循环来取得,由于2801次LOOP指令循环执行所需时间是10MS,所以一秒钟时间约执行2801*100次LOOP指令。控制脉冲宽度的计数值的实现程序如下:
MOV AX,2801
MOV BX,50 ;频率不同该值就不同
MULBX
DIV DI ;(DI)= f
MOVDX,AX ;(DX)=1/2f
算出了脉冲宽度,再通过高低电平的不断变换,就可实现不同频率的脉冲方波。把此方波经滤波放大即可驱动扬声器发声了。
方案2:
利用定时器发声。这里是通过硬件即8253定时器产生声音。
CUP通过对定时器的通道2进行编程,使其I/O寄存器接收一个控制声音频率的16位计数值,端口61H的最低位控制通道2门控的开断,以产生特殊的音响。当定时器接收的计数值为533H时,能产生896Hz的声音,因此产生其他频率的计数值就可由下式计算:
计数值=533H×896÷ f=1234DCH÷ f
在送出频率计数值之前,还要给方式寄存器送一个方式值,该数决定核丛对哪一个通道编程,采用什么模式,送入通道的计数值是一字节还是两字节,是二进制码还是BCD码。其位组合的格式如下:
当通道2用于发声时,采用的是模式3,在模式3下,输出线为“1”和为“0”的时间各占计数时间的一半,因而产生一系列间隔均匀的脉冲。
产生指定频率声音的程序段如下:
MOV AL,0B6H
OUT 43H,AL ;43H为8253的控制字端口
MOV DX,12H
MOV AX,34DCH
DIV DI ;(DI)=频率
OUT 42H,AL ;42H为8253的通道2端口
MOV AL,AH
MOV 42H,AL
从定时器输出的方波信号,经功率放大和滤波后驱动扬声器。送到扬声器的信号还受到了从并行接口芯片8255(端口地址为61H)来的双重控制,端口61H的最低位控制通道2的门控开断,以产生特殊的音频信号,端口61H的PB1位和定时器的输出信号同时作为与门的输入,PB0和PB1位可由程序决定为0还是为1。显然只有PB0和PB1都是1时,才能使扬声器发出声音。控制音长的时间可以简单地通过反复执行指令来得到。我们知道执行2801次LOOP指令约需要10MS的时间。因此用10MS的倍数值来控制扬声器开关的时间间隔,就可控制发声的音长了。实现程序如下:
IN AL,61H
MOV AH,AL
OR AL,3
OUT 61H,AL ;开扬声器
L: MOV CX,2801
DY:LOOP DY
DEC BX
JNZ L
MOV AL,AH
OUT 61H,AL ;关扬声器
下图是利用定时器发音的电路图。
方案比较:
在上述两个方案中,输入部分都是一样的。区别在于以不同的方式来驱动扬声器发声。经对比可知,两种方案都各有优缺点。在方案1中,其优点是电路简单,所用的器件芯片少,主要芯片只有需一片8255,产生方波是通过软件来实现的,易于修改和维护。然而它也存在一定的缺点,就是系统不断地通过软件来产生方波,系统资源被占用,无法再做其它事。与方案1相比,方案2增加了一个8253芯片和一个与门,虽然电路比方案1复杂,但通过定时器产生方波,实现起来比较简单,而且也不会出现系统资源被全部占用的情况。
经分析,选择方案2进行设计。
三. 硬件原理,器件功能
在方案2的设计中用到了两个主要的芯片,一个是并行接口8255,另一个是计数器8253。下面就先介绍一下这两个器件的主要功能以及在这个系统中所应用的功能。
1.8255并行接口。
8255是一个40引脚的双列直插式集成电路芯片。按功能可把8255分为三个逻辑电路部分,即:口电路、总线接口电路和控制逻辑电路。8255共有三个8位口,其中A口和B口是单纯的数据口,供数据I/O使用。而C口则既可以作数据口,又可以作控制口使用,用于实现A口和B口的控制功能。总线接口电路用于实现8255和单片微机的信号连接。其中包括:数据总线缓冲器,读/写控制逻辑,控制逻辑电路。内部的结构如下图所示。
8255的引脚信号中,除了电源和地以外,其他信号可以分为两组:
1.和外设一边相连的:
PA7-PA0:A组数据信号
PB7-PB0:B组数据信号
PC7-PC0:C组数据信号
2.和CPU一边相连的:
RESET:复位信号,低电平有效。当RESET信号来到时,所有内部寄存器就被清除,同时,3个数据端口被自动设为输入端口。
D7-D0:它们是8255的数据线,和系统数据总线相连。
:芯片选择信号,低电平有效。在一个系统中,一般根据全部接口芯片来分配若干较低位地址(比如A5、A4、A3)来组成各种芯片选择码,当这几位地址组成某一个代码时,译码器便往8255的端 输出一个低电平,于是8255被选中。只有当 有效时,读信号 和写信号 才对8255有效。
:芯片读出信号低电平有效。
:芯片写入信号低电平有效。
8255共有四个可寻址的端口(即A口、B口、C口和控制寄存器),用二位地址编码即可实现选择。参见下表。
8255共有三种工作方式,即方式0、方式1、方式2。
1.方式0为基本输入/输出方式,方式0下,可供使用的是两个8位口(A口和B口)及两个4位口(C口高4位部分和低4位部分)。四个口可以是输入和输出的任何组合。方式0适用于无条件数据传送,也可以把C口的某一位作为状态位,实现查询方式的数据传送。
2.方式1为选通输入/输出方式,A口和B口分别用于数据的输入/输出。而C口则作为数据传送的联络信号。A口和B口的联络信号都是三个,如果A或B只有一个口按方式1使用,则剩下的另外13位口线仍然可按方式0使用。如果两个口都按方式1使用,则还剩下2位口线,这两位口线仍然可以进行位状态的输入输出。方式1适用于查询或中断方式的数据输入/输出。
8255作为输入时如下图。输入过程如下:当输入设备准备好数据,将数据送至PA7~PA0或PB7~PB0,同时发 ,在 下降沿控制下,8255将PA7~PA0或PB7~PB0上的数据锁存到A口或B口数据输入寄存器中,同时8255向输入设备发IBF有效,告知输入设备暂缓送数。8255A可以两种方式通知CPU取走数据: 第一种方式是用中断方式,在INTE=1∩IBF=1时, 的上升沿使INTR=1,8255向CPU提出中断申请,CPU以中断方式取走数据,在CPU响应中断后,执行IN指令,将8255 A口或B口数据输入寄存器中的数据取走,同时, 信号的下降沿清除INTR信号, 信号的上升沿复位IBF。输入设备仅当检测到IBF为低电平后,才开始传送下一个数据,如此循环;第二种方式是用软件查询,CPU仅当查询到IBF=1时,才从8255A 口或B口数据输入寄存器中取走数据。
8255作为输出时如下图所示。输出过程如下:首先CPU执行OUT指令,在 信号的下降沿CPU输出的数据送入8255数据输出缓冲器,并使INTR复位。 信号上升沿将 置为有效,通知输出设备,CPU已把数据输出到8255的指定端口中,输出设备接到 信号有效后,发 有效, 下降沿将 置为1, 上升沿表示输出设备已从8255A指定端口取走数据,此时若 INTE=1,则INTR被置为高电平,向CPU申请中断,CPU可采用中断方式输出下一个数据。CPU也可通过查询 信号,若 =1,CPU输出下一个数据给8255A,即查询方式传送数据。
3.方式2双向数据传送方式。只允许A口工作在方式2,当A口工作在方式2时,B口可工作在方式0或方式1。 所谓双向,即A口可分时进行I/O *** 作。 A口工作在方式2,信号联络线如下:
(PC6), (PC7), (PC4),IBFA(PC5);
INTE1(PC6)与输出中断有关,可由用户给8255A控制字寄存器送PC6的置位/复位字来实现允许/禁止A口输出中断。
INTE2(PC4):与输入中断有关,可由用户给8255A控制字寄存器送PC4的置位/复位字来实现允许/禁止A口输入中断。
INTRA(PC3):I/O中断申请,高电平有效,产生中断请求信号的条件为: INTRA=IBFA·INTE2· · (输入中断);
INTRA= ·INTE1· · (输出中断)。
在本设计系统中运用的是工作方式0,这种方式比较简单。在这里,主要是A口用于输入,与8个常开型开关连接,用于采集输入。B口中的PB1和PB0用于控制发声。
2.计数器/定时器8253。 8253是8254的改进型,右图是它的芯片实物图。8253包括3个独立的16位计数器通道,而每个计数器都有6种工作方式,可以按二进制或十进制(BCD码)进行计数。如下图为8253的内部结构图。在图中可以清楚地看到,8253主要是由数据总线缓冲存储器,读写控制电路,控制字寄存器和3个通道4部分所组成。
1. 数据总线缓冲器是8253与CPU DB连接的8位双向三态缓冲器,CPU通过它向8253写方式控制字到控制字寄存器中,写计数初值到计数通道,读取计数通道的当前计数值。
2. 读/写控制逻辑控制8253内部 *** 作。当 无效,8253的DB处于高阻状态,当 有效, 和A1、A0、 、 组合,对3个计数通道、控制字寄存器进行读/写 *** 作。
3. 控制字寄存器 8253初始化编程时,CPU写控制字到控制字寄存器,以选择计数通道及相应的工作方式。
4. 数通道0~2。8253内部包括3个功能完全相同和 *** 作完全独立的计数通道,每个计数通道由16位减法计数器、16位计数初值寄存器和16位计数值锁存器组成。初始化时,向计数通道装入的计数初值,先送到计数初值寄存器中保存,然后送到减法计数器。计数器启动后,减法计数器对CLK的下降沿进行减1计数,在未锁定时把结果送入16位计数值锁存器中。当计数值减到0时,输出OUT信号,一次计数结束。计数初值寄存器的内容,在计数过程中保持不变。计数初值寄存器和计数值锁存器占用一个端口地址(即该计数通道口地址),CPU读取计数通道的当前计数值来自计数值锁存器。
各通道可工作在计数器方式,此时被计数的事件以脉冲方式从CLK输入;
各通道可工作在定时器方式,此时确定频率的时钟脉冲从CLK输入。
计数初值=定时时间÷CLK周期
各通道的启动、禁止、允许计数与门控信号GATE有关,GATE的作用OUT的输出波形随各通道工作方式不同而不同。
8253即可以作为计数器又可以作为定时器使用。在本系统中主要是运用了其计数功能。在8253的3个计数器中,都有6种不同的工作方式,其中工作方式3可称为方波发生器,其产生的方波正是在发声系统中所需要的。所以在这里就应用了8253作计数器并工作在方式3下。
下图为8253工作方式3的定时波形图。
任一通道工作在方式3,只在计数值n为偶数,则可输出重复周期为n,占空比为1:1的方波。如图所示,进入工作方式3,OUT输出低电平,装入计数值n后,OUT立即跳变为高电平。如果当前GATE为高电平,则立即开始减1计数,OUT保持为高电平。当计数值减到n/2时,OUT跳变为低电平,一直保持到计数值为0,系统就会自动重新置入计数值n,实现循环计数。这时OUT端输出的周期为n×CLK周期,占空比为1:1的方波序列。
如果在 *** 作过程中,GATE变为无效,则暂停减1计数过程,直到GATE再次有效,重新从初值n开始减计数。这一点对本系统来说非常重要。这使得在控制发声时可以方便随时停止。
下面的是8253的6种工作方式下的输出波形图。在这里就不再一一阐述了。
四. 系统原理
经过分析对比上述的两种方案可知,选取方案2是比较合理的。下面就方案2来分析一下整个系统的工作原理。前面已经提到,整个电路分成输入和发音两大部分。主要的器件有一个并行接口8255,和一个8253定时器。输入部分的硬件原理图比较简单,如右图所示的为输入电路,其主要是由8个常开型开关和一个并行接口8255组成。由图中可看到,8个开关一端接地,另一端接到8255的A口输入,并且通过一个电阻接到+5V。因此,在开关不按下时,从8255A口输入的是高电平,当开关按下时,输入的则是低电平,这样通过低电平触发,既方便也对芯片起保护作用。如下表,当不同的开关按下时,从A口输入就对应一个8位的数据。
开 关 K1 K2 K3 K4 K5 K6 K7 K8
输入数据 0FEH 0FDH 0FBH 0F7H 0EFH 0DFH 0BFH 7FH
通过软件检测输入的数据,然后给8253送相应频率的计数值。检测的程序如下:
IN AL,60H;从8255A口输入一个数据
CMP AL,0FEH
JZ K1;K1—K8分别为不同程序断的标号
CMP AL,0FDH
JZ K2
CMP AL,0FBH
JZ K3
CMP AL,0F7H
JZ K4
CMP AL,0EFH
JZ K5
CMP AL,0DFH
JZ K6
CMP AL,0BFH
JZ K7
CMP AL,7FH
JZ K8
对于发音部分。PC机上的大多数输入/输出(I/O)都是由主板上的8255(或8255A)可编程序外围接口芯片(PPI)管理的。PPI包括3个8位寄存器,两个用于输入功能,一个用于输出功能。输入寄存器分配的I/O端口号为60H和62H,输出寄存器分配的I/O端口号为61H。由PPI输出寄存器中的0、1两位来选择扬声器的驱动方式。如下图。
连接到扬声器上的是定时器2,从上图可以看到,GATE2与端口61H的PB0相连,当PB0=1时,GATE2获得高电平,使定时器2可以在模式3(方波)下工作。定时器2的OUT2与端口61H的PB1通过一个与门与扬声器的驱动电路相连。当PB1=1时,允许OUT2的输出信号到达扬声器电路。因此,只有PB0和PB1同时为“1”时,才能驱动扬声器地声。通过以下指令实现:
IN AL,61H
OR AL,3
OUT 61H,AL
上面的指令用以打开扬声器,如要关闭扬声器时则为:
AND AL,0FCH
OUT 61H,AL
当从8255中采集到输入的数据时,需要确定相应的频率,所以在软件编程时要建立一个数据表:
TABLE DW 493,440,392,349,329,293,261
把相应的频率送到一个寄存器上,通过公式:
计数值=533H×896÷ f=1234DCH÷ f
算出计数值,再把算得的计数值送给8253,就可产生所要频率的方波。在把计数值送8253前,必须先把8253进行初始化:
MOV AL,0B6H
OUT 43H,AL
使其选用通道2,工作在方式3下。
就整个电路而言,接好电路后,通过软件编程不断地采集从8255口中输入的信号,而8个开关都接在8255的A口上,只要有开关按下,就会采集到一个数据,根据这个数据与事先编好的表对应,得到一个计数值,把这个计数值送给8253的通道2,8253的通道2工作的方式3下,这样就可以产生满足频率要求的发声方波。这个方波经驱动放大就可以使扬声器发出相应的声音。
所以8255在这里完成两个任务,它不仅从A口中采集到数据,而且B口的PB1和PB0两个位要控制发声。8253的主要任务就是产生所要求发声的不同频率的方波。
五. 电路图
下图即为本设计中所采用的方案2的硬件连线图。
在设计过程中,独立编址时,用地址线的高位部分和控制信号(如RD、WR、M/IO)进行组合产生 I/O接口电路的片选信号(CS),用地址线的低位部分直接连到 I/O接口芯片实现端口的选择。在此采用的是译码器译码,电路图如下所示,经过74LS138译码后, 输出作为8253的片选信号(CS),即其端口地址为40H~43H。 输出作为8255的片选信号(CS),即其端口地址为60H~63H。
六. 软件思想,流程图,源程序
软件部分对整个系统来说起着重要的作用,在本电子琴系统中,软件可以分为三部分,主程序部分,发音子程序部分和延时子程序部分。
主程序的流程图如下:
发声程序包括3个步骤:
(1)在8253中的42端口送一个控制字0B6H(10110110B),该控制字对定时器2进行初始化,使定时器2准备接收计数初值。
(2)在8253中的42H端口(Timer2)装入一个16位的计数值(533H×895/频率),以建立将要产生的声音频率。
(3)把输出端口61H的PB0、PB1两位置1,发出声音。
以下是发声子程序的流程图:
我们知道LOOP指令执行2801次的时间为10ms,所以延时子程序则很简单,只需要反复执行LOOP指令就可实现,并且所得到的延时时间为10ms的倍数。
下面即为整个程序代码:
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)