📄 moto_car_final.asm
字号:
/************************************************************************
** Jacky's Work
**-----------------------------------------------------------------------
**Jacky's web :http://www.ICFans.com
**Jacky's Blog:http://blog.ICFans.com
**Jacky Lee 2005-05-05 xidian university
*************************************************************************
*************************************************************************
**程 序 名:MOTO_CAR_Fianl
**创 建 人:Jacky
**日 期:2005-05-05
**编程工具:KEIL
**修 改 人:
**日 期:
**描 述:MOTO_CAR_Final
**变量说明:1. Left:R1-R3 Right:R5-R7
** : 2. R0 基本Delay暂存 R4未使用
** : 3. R1,R5 附加Delay暂存
** : 4. R2,R6 附加Delay永久
** : 5. R3,R7 下一步动作
** : 6. Bit 00H Left前进/后退标志 1进 0退
** : 7. Bit 01H Right前进/后退标志 1进 0退
** : 8. Bit 02H Left移动/停止标志 1移 0停
** : 9. Bit 03H Right移动/停止标志 1移 0停
** : 10.Bit 04H 动作已选择标志位 1已选择 0未选择
**接线说明: P0 -> 左轮 P1 -> 右轮 P2->LED模块(显示接收到的串行数据)
**其他说明: SPEED关系说明:MAX_SPEED必须是DEFAULT_SPEED的2^n,MIN_SPEED必须是DEFAULT_SPEED的1/2^n.
**版 本:V1.0.0
*************************************************************************/
ORG 0000H
AJMP START
ORG 0030H
MAX_SPEED EQU 02H ;速度上限,最小值
MIN_SPEED EQU 10H ;速度下限,最大值
DEFAULT_SPEED EQU 08H ;速度默认值
BASIC_DELAY EQU 0FFH ;基本Delay,赋给 R0
START: MOV SP,#60H ;设置堆栈
MOV IE,#80H ;禁止中断
MOV SCON,#01010000B ;UART工作在MODE1,REN=1(允许串口接受数据,无奇偶校验
MOV PCON,#00000000B ;串口波特率不加倍
MOV TMOD,#00100000B ;TIMER1工作在定时器方式MODE2用于做波特率发生器
MOV TH1,#0D0H ;波特率600
MOV TL1,#0D0H ;初始化完毕
SETB TR1 ;启动TIMER1
CLR 04H
SERIAL_CHECK:
JB RI,SERIAL_ACTION ;检测SCON的RI是否为1?是则表示接收到
JB 04H,JUMP_TO_RUN
AJMP SERIAL_CHECK
JUMP_TO_RUN:
AJMP RUN_ACTION
SERIAL_ACTION:
MOV A,SBUF ;SBUF载入A
MOV B,A
CPL A ;LED为低电平有效
MOV P2,A ;将串行数据送显P2
MOV A,B
CLR RI ;清除RI=0
MOV SBUF,A
JNB TI,$ ;检测SCON的TI是否为1?是表示发送完
CLR TI
ACTION_CHECK: ;根据接收到的串行数据选择动作
MOV DPTR,#JUMP_TABLE ;将JUMP_TABLE的首地址赋给DPTR
; MOV A,#06H
MOV B,A ;暂存A至B
SUBB A,#0AH
JNC GO_TO_SERIAL_CHECK ;非法指令保护
AJMP ACTION_CHECK_END
GO_TO_SERIAL_CHECK:
CLR 04H
AJMP SERIAL_CHECK
ACTION_CHECK_END:
MOV A,B
ADD A,B ;由于每个AJMP占用两个字节,故SERIAL*=2
; MOV R2,#08H
; MOV R6,#08H
JMP @A+DPTR
JUMP_TABLE: ;JUMP_TABLE地址表
AJMP FORWARD ;00H
AJMP BACKWARD ;01H
AJMP LEFT_TURN ;02H
AJMP RIGHT_TURN ;03H
AJMP SPEED_DOUBLE ;04H
AJMP SPEED_HALVE ;05H
AJMP SPEED_TO_DEFAULT ;06H
AJMP SPEED_ZERO ;07H
AJMP GO_LEFT_CIRCLE ;08H
AJMP GO_RIGHT_CIRCLE ;09H
FORWARD: ;前进位变量初始化
SETB 00H
SETB 01H
SETB 02H
SETB 03H
AJMP RUN
BACKWARD: ;后退位变量初始化
CLR 00H
CLR 01H
SETB 02H
SETB 03H
AJMP RUN
LEFT_TURN: ;左转位变量初始化
SETB 00H
SETB 01H
CLR 02H
SETB 03H
AJMP RUN
RIGHT_TURN: ;右转位变量初始化
SETB 00H
SETB 01H
SETB 02H
CLR 03H
AJMP RUN
SPEED_DOUBLE:
SPEED_DOUBLE_L: ;左轮SPEED_DOUBLE,R2若未低于最小值,则R2/=2,否则R2保持不变
MOV A,R2
CLR C
SUBB A,#MAX_SPEED
JZ SPEED_DOUBLE_R
MOV A,R2
MOV B,#02H
DIV AB
MOV R2,A
SPEED_DOUBLE_R: ;右轮SPEED_DOUBLE,R6若未低于最小值,则R6/=2,否则R6保持不变
MOV A,R6
CLR C
SUBB A,#MAX_SPEED
JZ SPEED_DOUBLE_END
MOV A,R6
MOV B,#02H
DIV AB
MOV R6,A
SPEED_DOUBLE_END: ;SPEED_DOUBLE位变量初始化
SETB 02H
SETB 03H
AJMP RUN
SPEED_HALVE:
SPEED_HALVE_L: ;左轮SPEED_HALVE,R2若未超过最大值,则R2*=2,否则R2保持不变
MOV A,R2
CLR C
SUBB A,#MIN_SPEED
JZ SPEED_HALVE_R
MOV A,R2
ADD A,R2
MOV R2,A
SPEED_HALVE_R: ;右轮SPEED_HALVE,R6若未超过最大值,则R6*=2,否则R6保持不变
MOV A,R6
CLR C
SUBB A,#MIN_SPEED
JZ SPEED_HALVE_END
MOV A,R6
ADD A,R6
MOV R6,A
SPEED_HALVE_END: ;SPEED_HALVE位变量初始化
SETB 02H
SETB 03H
AJMP RUN
SPEED_TO_DEFAULT: ;SPEED_TO_DEFAULT:R2,R6赋DEFAULT_SPEED
MOV R2,#DEFAULT_SPEED
MOV R6,#DEFAULT_SPEED
AJMP RUN
SPEED_ZERO: ;SPEED_ZERO:Bit 02H 03H 移动标志位清零
CLR 02H
CLR 03H
AJMP RUN
GO_LEFT_CIRCLE: ;GO_LEFT_CIRCLE预定动作,R2,R6,及位变量初始化
MOV R2,#10H
MOV R6,#8H
SETB 00H
SETB 01H
SETB 02H
SETB 03H
AJMP RUN
GO_RIGHT_CIRCLE: ;GO_RIGHT_CIRCLE预定动作,R2,R6,及位变量初始化
MOV R2,#8H
MOV R6,#10H
SETB 00H
SETB 01H
SETB 02H
SETB 03H
AJMP RUN
RUN: ;移动模块
RUN_CHECK:
SPEED_CHECK:
SPEED_CHECK_L: ;左轮速度检查,若R2为零,则赋DEFAULT_SPEED_VALUE
MOV A,R2
CLR C
SUBB A,#00H
JNZ SPEED_CHECK_R
MOV R2,#DEFAULT_SPEED
SPEED_CHECK_R: ;右轮速度检查,若R6为零,则赋DEFAULT_SPEED_VALUE
MOV A,R6
CLR C
SUBB A,#00H
JNZ SPEED_CHECK_END
MOV R6,#DEFAULT_SPEED
SPEED_CHECK_END: ;将R2赋给临时寄存器R1,将R6赋给临时寄存器R5
MOV A,R2
MOV R1,A
MOV A,R6
MOV R5,A
RUN_ACTION:
LEFT_MOVE: ;左轮移动模块
LEFT_CHECK_ENABLE:
JNB 02H,RIGHT_MOVE ;若Bit 02H 左轮移动/停止标志位为0,则跳过左轮移动模块,直接转至右轮移动模块
MOV A,R1
CLR C
SUBB A,#01H ;R1--
MOV R1,A
JZ LEFT_ACTION ;若R1为00H,则跳转至LEFT_ACTION模块,否则跳过LEFT_MOVE模块,直接转至RIGHT_MOVE模块
AJMP RIGHT_MOVE
LEFT_ACTION:
JB 00H,LEFT_FORWARD_ACTION ;若Bit 00H 左轮前进/后退标志位为1,则转到左轮前进,否则执行左轮后退模块
LEFT_BACKWARD_ACTION: ;左轮后退模块
DEC R3
ACALL R3_CHECK
AJMP LEFT_ACTION_END
LEFT_FORWARD_ACTION: ;左轮前进模块
INC R3
ACALL R3_CHECK
LEFT_ACTION_END:
MOV DPTR,#ACTION_TABLE
MOV A,R3
MOVC A,@A+DPTR
MOV P1,A
RIGHT_MOVE: ;右轮移动模块
RIGHT_CHECK_ENABLE:
JNB 03H,NEXT_ROUND ;若Bit 03H 左轮移动/停止标志位为0,则跳过右轮移动模块,直接转至NEXT_ROUND
MOV A,R5
CLR C
SUBB A,#01H ;R5--
MOV R5,A
JZ RIGHT_ACTION
AJMP NEXT_ROUND
RIGHT_ACTION:
JB 01H,RIGHT_FORWARD_ACTION;若Bit 01H 右轮前进/后退标志位为1,则转到右轮前进,否则执行右轮后退模块
RIGHT_BACKWARD_ACTION: ;右轮后退模块
DEC R7
ACALL R7_CHECK
AJMP RIGHT_ACTION_END
RIGHT_FORWARD_ACTION: ;右轮前进模块
INC R7
ACALL R7_CHECK
RIGHT_ACTION_END:
MOV DPTR,#ACTION_TABLE
MOV A,R7
MOVC A,@A+DPTR
MOV P0,A
NEXT_ROUND:
CHECK_R1_VALUE: ;检查R1的值,如果为00H,则重新赋值为R2
MOV A,R1
CLR C
SUBB A,#00H
JNZ CHECK_R5_VALUE
MOV A,R2
MOV R1,A
CHECK_R5_VALUE: ;检查R5的值,如果为00H,则重新赋值为R6
MOV A,R5
CLR C
SUBB A,#00H
JNZ NEXT_ROUND_END
MOV A,R6
MOV R5,A
NEXT_ROUND_END:
SETB 04H ;设置动作已选择标志位04H为1
ACALL BASE_DELAY
AJMP SERIAL_CHECK
BASE_DELAY:
MOV R0,#BASIC_DELAY
DJNZ R0,$
RET
R3_CHECK:
MOV A,R3
CLR C
SUBB A,#0FFH
JZ R3_TO_07H ;若R3为FFH,则R3=07H
MOV A,R3
CLR C
SUBB A,#08H ;若R3为08H,则R3=00H
JZ R3_TO_00H
AJMP R3_CHECK_END
R3_TO_00H:
MOV R3,#00H
AJMP R3_CHECK_END
R3_TO_07H:
MOV R3,#07H
R3_CHECK_END:
RET
R7_CHECK:
MOV A,R7
CLR C
SUBB A,#0FFH
JZ R7_TO_07H ;若R7为FFH,则R7=07H
MOV A,R7
CLR C
SUBB A,#08H ;若R7为08H,则R7=00H
JZ R7_TO_00H
AJMP R7_CHECK_END
R7_TO_00H:
MOV R7,#00H
AJMP R7_CHECK_END
R7_TO_07H:
MOV R7,#07H
R7_CHECK_END:
RET
ACTION_TABLE:
DB 0EH,0AH,0BH,09H,0DH,05H,07H,06H
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -