汽车速度控制系统:在自行设计接口板的按键转换汽车的挡位;发光二极管显示挡位;数码管显示汽车的速度。加速控制:拨动对应的档位再拨动加速开关,数码管显示速度递增至99(加速要与档位匹配,若不匹配则,加速失效);减速控制:拨动减速开关,速度减至0。
1.开关控制速度加速、减速,4个档位控制,共需6个开关。
2.两个数码管显示2位十进制数。
3.4个二极管显示档位(档位对应亮灯个数)。
4.8086CPU,以及8255端口芯片。
6个输入开关K1-K4、K7-K8 连接到8255输入端PA0 ~ PA3、PA6~PA7。
数码管端A~ Dp连接到8255输出端PB0~PB7。
数码管显示单元X1X2连接到8255输出端PC6~PC7,用于选择数码管。
4个led灯与8255的输出端PC0~PC3相连,用于显示档位。
8255 A0、A1连接系统总线XA1、XA2。
8255数据端D0-D7与CPU总线数据端XD0~XD7相连,用于数据交换。
8255片选端CS与总线IOY端相连。
8255WR和RD分别与总线IOW和IOR端相连。
ASSUME CS:CODE,DS:DATA,SS:STACK
DATA_PORT EQU 0606H
DATA_CONTROAL EQU 10010000B
PORT_A EQU 0600H
PORT_B EQU 0602H
PORT_C EQU 0604H
LOOP_COUNT EQU 200D
DIGIT_LAMP_FIRST EQU 01110000B
DIGIT_LAMP_SECOND EQU 10110000B
DIGIT_NUMBER_UPPER EQU 9D
DIGIT_LAMP_OFF EQU 00000000B
DATA SEGMENT
SPEED DW 0H
NUMBER DW 0H,0H
DIGIT DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
LEVE DB 0H
UP_STATE DB 0H
DOWN_STATE DB 0H
LAST_INPUT_DATA DB 0H
DATA ENDS
STACK SEGMENT
DW 50 DUP(?)
STACK ENDS
CODE SEGMENT
START:
MOV DX,DATA_PORT ;写控制字
MOV AL,DATA_CONTROAL
OUT DX,AL
MOV AX,DATA ;初始化 数据段,堆栈段
MOV DS,AX
MOV AX,STACK
MOV SS,AX
LOP:
CALL GET_STATE ;获取速度档位信息
CALL PRINT_SPEED ;打印速度
CMP UP_STATE,10000000B ;判断加减速
JNE IS_DOWN_SYSTEM
CALL SPEED_UP_SYSTEM
JMP TO_END
IS_DOWN_SYSTEM:
CMP DOWN_STATE,01000000B
JNE TO_END
CALL SPEED_DOWN_SYSTEM
TO_END:
JMP LOP
MOV AX,4C00H
INT 21H
GET_STATE:
MOV DX,PORT_A
IN AL,DX
CMP LAST_INPUT_DATA,AL
JE GET_STATE_END
MOV LAST_INPUT_DATA,AL
MOV UP_STATE,AL ;截取加速信息
AND UP_STATE,10000000B
MOV DOWN_STATE,AL ;截取减速信息
AND DOWN_STATE,01000000B
MOV LEVE,AL ;截取档位信息
AND LEVE,00001111B
GET_STATE_END:
RET
SPEED_UP_SYSTEM:
MOV AX,SPEED
CMP AL,98
JA SPEED_UP_SYSTEM_END
CMP AL,46
JA SPEED_OVER_47__UP
CMP AL,35
JA SPEED_46_AND_36__UP
CMP AL,24
JA SPEED_35_AND_25__UP
JMP SPEED_24_AND_0__UP
SPEED_24_AND_0__UP:
MOV BL,LEVE
CMP BL,1
JNE SPEED_UP_SYSTEM_END
CALL ADD_SPEED
JMP SPEED_UP_SYSTEM_END
SPEED_35_AND_25__UP:
MOV BL,LEVE
CMP BL,2
JNE SPEED_UP_SYSTEM_END
CALL ADD_SPEED
JMP SPEED_UP_SYSTEM_END
SPEED_46_AND_36__UP:
MOV BL,LEVE
CMP BL,4
JNE SPEED_UP_SYSTEM_END
CALL ADD_SPEED
SPEED_UP_SYSTEM_END:
RET
SPEED_DOWN_SYSTEM:
MOV AX,SPEED
CMP AL,1
JB SPEED_DOWN_SYSTEM_END
CALL SUB_SPEED
SPEED_DOWN_SYSTEM_END:
RET
PRINT_LEVE:
MOV AL,LEVE
CMP AL,0 ;档位为0 退出
JE END_
SUB AL,1 ;波动2个以上档位退出
AND AL,LEVE
JNZ END_
MOV AL,LEVE ;档位灯数计算
SUB AL,1
OR AL,LEVE
MOV DX,PORT_C
OUT DX,AL
CALL WAIT_TIME
END_:
RET
PRINT_SPEED:
MOV AX,SPEED
MOV BX,10
DIV BL ;截取十位和个位
MOV BYTE PTR NUMBER[0],AL
MOV BYTE PTR NUMBER[2],AH
MOV CX,LOOP_COUNT
LOOP_PRINT:
MOV DX,PORT_C
MOV AL,DIGIT_LAMP_FIRST ;选择数码管
OUT DX,AL
MOV DI,WORD PTR NUMBER[0]
CALL OUT_DIGIT ;输出数
MOV DX,PORT_C
MOV AL,DIGIT_LAMP_SECOND
OUT DX,AL
MOV DI,WORD PTR NUMBER[2]
CALL OUT_DIGIT
CALL PRINT_LEVE ;打印档位
LOOP LOOP_PRINT
RET
ADD_SPEED:
MOV AX,SPEED
INC AL
MOV SPEED,AX
RET
SUB_SPEED:
MOV AX,SPEED
DEC AL
MOV SPEED,AX
RET
WAIT_TIME:
PUSH CX
MOV CX,000CH
WAIT_LOOP:
LOOP WAIT_LOOP
POP CX
RET
OUT_DIGIT:
CMP DI,DIGIT_NUMBER_UPPER
JA OUT_DIGIT_END
MOV DX,PORT_B
MOV AL,DIGIT[DI]
OUT DX,AL
CALL WAIT_TIME ;延时
MOV AL,DIGIT_LAMP_OFF ;关闭数码管
OUT DX,AL
OUT_DIGIT_END:
RET
CODE ENDS
END START
对于汇编的编写,与C稍微不同,即对寄存器使用。刚开始还不会使用内存空间,只知道寄存器。于是就挨个用寄存器,甚至下意识将某些寄存器当做存储空间。这很明显展示了自己的低水平。所以,我单独研究如何申请空间,将寄存器数据存储到空间里。程序的关键数据保存到内存里,这种做法为程序解耦奠定基础。我觉得程序设计最忌讳的是胡子眉毛一起抓,将代码堆砌在一起,如同一字长蛇。这种代码最容易出现bug,难以修改。代码过长,过一会儿就不知道前面在写什么。故程序模块设计,仍旧是编码最有力、最清楚、最省事的编写手段。通过函数设计,使得编写变得容易清楚,头脑逻辑清晰,不知不觉中体会到程序解耦优势。这样一来再加入新功能时,就不必担心运行过程中寄存的数据流失。程序的设计结构:外层是循环,内部是对数据的分支处理。主要两大主分支,加速系统和减速系统;一个数据输出处理。设计框架和设计思想确立后,剩下的就是实现的细节问题和程序bug,只有耐心地发现问题。最后感谢队友帮助,共同完成此次课设。