我的课程设计,实现交通灯
DATA SEGMENT
I08259_0 EQU 0F000H ;8259地址
I08259_1 EQU 0F001H
K8255A EQU 0F000H ;8255地址
K8255B EQU 0F001H
K8255C EQU 0F003H
ADD8253_0 EQU 0D000H ;8253地址
ADD8253_1 EQU 0D001H
ADD8253_2 EQU 0D002H
ADD8253_C EQU 0D003H
LIGHT EQU 5AH ;从高到低每两位依次表示东西南北,高位绿灯,地位红灯
TAB DB 3FH,3FH,06H,3FH,5BH,3FH,4FH,3FH,66H,3FH ;数码管显
DB 6DH,3FH,7DH,3FH,07H,3FH,7FH,3FH,6FH,3FH
DB 3FH,06H,06H,06H,5BH,06H,4FH,06H,66H,06H
DB 6DH,06H,7DH,06H,07H,06H,7FH,06H,6FH,06H
DB 3FH,5BH,06H,5BH,5BH,5BH,4FH,5BH,66H,5BH
DB 6DH,5BH,7DH,5BH,07H,5BH,7FH,5BH,66H,5BH
DB 3FH,4FH,06H,4FH,5BH,4FH,4FH,4FH,66H,4FH
DB 6DH,4FH,7DH,4FH,07H,4FH,7FH,4FH,6FH,4FH
DB 3FH,66H,06H,66H,5BH,66H,4FH,66H,66H,66H
DB 6DH,66H,7DH,66H,07H,66H,7FH,66H,6FH,66H
DB 3FH,6DH,06H,6DH,5BH,6DH,4FH,6DH,66H,6DH
DB 6DH,6DH,7DH,6DH,07H,6DH,7FH,6DH,6FH,6DH
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE , DS:DATA
START:MOV AX,DATA
MOV DS,AX
MOV ES,AX
NOP
MOV DX,K8255K ;写8255控制字,A,B,C均为输出,方式0
MOV AL,80H
OUT DX,AL
START I :MOV DX,K8255C ;C口输出,控制灯
MOV AL,55H ;红灯亮
OUT DX,AL
CALL DELAY ;调延时
MOV AL,0 ;红灯灭
OUT DX,AL
CALL DELAY
MOV AL55H
OUT DX,AL
CALL DELAY
MOV AL,0
OUT DX,AL
CALL DELAY
OUT DX,AL
CALL DELAY
MOV AL,0
OUT DX,AL
CALL DELAY
OUT DX,AL
START II :MOV DX,ADD8253_C ;写8253控制字
MOV AL,36H ;0计数器,低高字节读写,方式三
OUT DX,AL
MOV AX,63352 ;写计数初值,根据输入设定,方波频率1HZ
MOV DX,ADD8253_0
MOV DX,AL
MOV AL,AH
OUT DX,AL
CALL Init8259 ;调8259初始化子程序
CALL WriInter ;调写中断向量表子程序
MOV BX,OFFSET TAB ;给数码管显示表头偏移地址
MOV IS,25 ;写计数值(红绿灯变换的间隔时间)
MOV DX,1
STI
NOP
START III : INC DX ;给出中断以外CPU的工作(其实这时候CPU是没事找事做,在等中断信号)
JMP START III
Init8259 PROC NEAR ;8259初始化子程序
MOV DX,I08259_0 ;写ICW1,边沿触发,单片,需写ICW4
MOV AL,13H
OUT DX,AL
MOV DX,I08259_1 ;写ICW2,中断类型号8
MOV AL,08H
OUT DX,AL
MOV AL,09H ;写ICW4,非特殊全嵌套,缓冲,正常中断,8086配置
OUT DX,AL
MOV AL,OFEH ;写OCW1,除IR0全屏蔽中断
OUT DX,AL
RET
Init8259 ENDP
WriIntver PROC NEAR ;写中断向量表子程序
PUSH ES
MOV AX,0
MOV ES,AX
MOV DI,20H ;中断类型号8,对应20H,21H,22H,23H四个单元
LEA AX,INT_0 ;取中断服务程序IP
STOSW
MOV AX,CS ;取中段服务程序CS
STOSW
POP ES
RET
WriIntver ENDP
INT_0:DEC SI ;中断服务程序(关键部分)
PUSH AX
PUSH DX
PUSH SI ;保护循环值,否则取数码管显示会破坏
PUSH BX
SHL SI,1 ;取循环值后乘2(一个2位数的数码管显示值要2个单元存放)
ADD BX,SI
MOV AH,[BX] ;取数码管显示值,8255A口输出
MOV DX,K8255A
MOV AL,AH
OUT DX,AL
ADD BX,1
MOV AL,[BX] ;取数码管显示值,8255B输出
MOV DX,K8255B
OUT DX,AL
POP BX
POP SI ;要先取出循环制,否则后面可能无法将其置为初值
CMP SI,0 ;循环不到0转跳GG,为0则交换交通灯状态(取反),SI回初值
JNZ GG
MOV SI,25
NOT CL
MOV AL,CL
MOV DX,K8255C
OUT DX,AL
GG: MOV DX,IO8259_0 ;结束中断服务,写OCW2,给8259送EOI命令,LSR1清零
MOV AL,20H
OUT DX,AL
POP DX
POP AX
IRENT
DELAY PROC;延时子程序
MOV BX,05H
DELAY1:MOV CX,10H
LOOP $
DEC BX
JNZ DELAY1
RET
DELAY ENDP
CODE ENDS
END START
硬件连接:计时器0OUT端接8259IR0,8255AB口接数码管显示倒计时,C端接二极管,表示信号灯(图略)
设计思想:定时器产生1HZ方波,脉冲到8259,产生中断,调中断服务程序,此程序主要是计数,运行一次SI减一,到0时换灯并返回初值,显示时间主要也是利用SI值查表,取出对应显示数的二进制代码,交8255输出。程序开始时段,红灯闪烁功能考虑到硬件连接问题采用软件定时,时间可调
可能存在的问题:1,个别变量忘记用堆栈保护造成程序不能正常工作
2,定时器初值设定由于未确定输入值不能计算得到,若输入频率过大可先用计数器1发出频率中等(如0.05HZ)脉冲,计数器1OUT接计数器0CLK,再由0生成1HZ脉冲
3,数码管显示程序也可先16进制转10进制,分离个十位后查表,此表只需10个单元,且程序移植性好,尤其对大计数值系统更为有利
水平有限,如有错误,敬请指正
QQ:351311006
E:tankpig_2004@163.com
T:13913822706
胖
09.6.12