;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; SPEED/MILE FOR BIKE PROGRAM ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;
; 60H,61H,62H作里程计数单元,6CH,6DH作T1计数扩充单元,
; 68H,69H,6AH,6BH存放自行车每圈时间数,70H,71H,72H,73H
; 作显示BCD码存放数用,11H--15H存放被除数,16H-19H存放除数
;
;
; 定义
VSDA EQU P1.5 ; EEPROM数据传送口
VSCL EQU P1.4 ; EEPROM时钟传送口
SLA EQU 50H ; EEPROM器件寻址字节存放单元
NUMBYT EQU 51H ; EEPROM传送字节数存放单元
MTD EQU 30H ; EEPROM发送数据缓冲单元
MRD EQU 40H ; EEPROM读出数据存放单元
SLAW EQU 0A0H ; EEPROM寻址字节写
SLAR EQU 0A1H ; EEPROM寻址字节读
DPHH EQU 62H ; DPTR计数扩展高8位
TH1H EQU 6CH ; 定时器T1扩展高8位
TH1HH EQU 6DH ; 定时器T1扩展高8-16位
;
;;;;;;;;;;;;;;;;;;;;
;; PROGRAM INPUT ;;
;;;;;;;;;;;;;;;;;;;;
;
ORG 0000H ;程序执行开始地址
LJMP START ;跳至START
ORG 0003H ;外中断0中断程序入口
LJMP INTEX0 ;跳至INTEX0中断服务程序
ORG 000BH ;定时器T0中断程序入口
RETI ;中断返回
ORG 0013H ;外中断1中断入口
LJMP INTEX1 ; 跳至INTEX1中断服务程序
ORG 001BH ; 定时器T1中断程序入口
LJMP INTT1 ; 跳至INTT1中断服务程序
ORG 0023H ;串口中断入口地址
RETI ;中断返回
ORG 002BH ;定时器T2中断入口地址
RETI ;中断返回
;
;
;;;;;;;;;;;;;;;;;;;;
;; PROGRAM CLEAR ;;
;;;;;;;;;;;;;;;;;;;;
;上电初始化程序
CLEARMEN: MOV TMOD,#90H ;T1为16位外部控制定时器
SETB PX0 ;外中断0优先级为1
SETB IT0 ;外中断0用边沿触发
SETB IT1 ;外中断1用边沿触发
CLR A ;清A
MOV 20H,A ;清内存中特定单元
MOV 6CH,A ;
MOV 6DH,A ;
MOV 70H,A ;
MOV 71H,A ;
MOV 72H,A ;
MOV 73H,A ;
MOV 60H,A ;
MOV 61H,A ;
MOV 62H,A ;
MOV 63H,A ; 清内存中特定单元
DEC A ;A为#0FFH
MOV 68H,A ;内存置数据#0FFH
MOV 69H,A ; 内存置数据#0FFH
MOV 6AH,A ; 内存置数据#0FFH
MOV 6BH,A ; 内存置数据#0FFH
MOV P1, A ;P1口置1
CLEAR1: JB P1.2,KEY1 ;根据P1.2,P1.3,P1.6,P1.7设置状态,
;在21H地址单元赋自行车周长值
MOV 21H,#0FH ;22寸自行车周长值
LJMP CLEAR2 ;转CLEAR2
KEY1: JB P1.3,KEY2 ;
MOV 21H,#12H ; 24寸自行车周长值
LJMP CLEAR2 ; 转CLEAR2
KEY2: JB P1.6,KEY3 ;
MOV 21H,#14H ; 26寸自行车周长值
LJMP CLEAR2 ; 转CLEAR2
KEY3: JB P1.7,ERR ;四个开关都没合上,转出错处理
MOV 21H,#19H ; 28寸自行车周长值
CLEAR2: SETB TR1 ;开定时器T1
SETB EA ;开中断允许
SETB EX0 ;开外中断0
SETB ET1 ;开定时中断T1
SETB P3.1 ;关报警器
LCALL VIICREAD ;将EEPROM中原里程数据调入内存
RET ;子程序返回
ERR: CPL P3.1 ;轮周长设置出错,LED灯闪烁堤醒
LCALL DL5S ;延时
LJMP CLEAR1 ;重新初始化,等待轮周长设置开关合上
;
;;;;;;;;;;;;;;;;;;;;
;; PROGRAM START ;;
;;;;;;;;;;;;;;;;;;;;
;
START: MOV SP,#75H ;堆栈在75H开始
LCALL CLEARMEN ;上电初始化
START1: JB P3.0,DISPLAYS ;P3.0=1,显示里程
LCALL DISPLAYV ;显示速度
START2: SJMP START1 ;转START1循环
;
;;;;;;;;;;;;;;;;;;;;
;;INTEX0 PROGRAM ;;
;;;;;;;;;;;;;;;;;;;;
; 里程计数程序,用外中断0实现,计数用60H-62H内存单元。
INTEX0: PUSH ACC ; 累加器堆栈保护
PUSH PSW ;状态字堆栈保护
INC 60H ;圈加1
CLR A ;清A
CJNE A,60H,INTEX0OUT ;计数没溢出转INTEX0OUT
INC 61H ;溢出进位(61H加1)
CJNE A,61H,INTEX0OUT ; 计数没溢出转INTEX0OUT
INC 62H ; 溢出进位(62H加1)
INTEX0OUT: LCALL VIICWRITE ;里程数据存入EEPROM
SETB EX1 ;开外中断1
POP PSW ;状态字恢复
POP ACC ;累加器恢复
RETI ;中断返回
;;;;;;;;;;;;;;;;;;;;
;;INTEX1 PROGRAM ;;
;;;;;;;;;;;;;;;;;;;;
; 每转1圈时间计数处理程序,每圈时间放在68H-6BH单元中。
INTEX1: PUSH ACC ; 堆栈保护
PUSH PSW ;
CLR EX1 ;关外中断1
JNB 00H,INTEX11 ;溢出标志为0转INTEX11
MOV TL1,#0FFH ;溢出时计时单元赋#0FFH(显示速度为零)
MOV TH1,#0FFH ;
MOV 6CH,#0FFH ;
MOV 6DH,#0FFH ;
INTEX11: MOV 68H,TL1 ;将时间计数值移入暂存单元68H-6BH
MOV 69H,TH1 ;
MOV 6AH,6CH ;
MOV 6BH,6DH ;
CLR A ;清A
MOV TL1,A ;计时单元置0
MOV TH1,A ;
MOV 6CH,A ;
MOV 6DH,A ;
CLR 00H ;清溢出标志
POP PSW ;堆栈恢复
POP ACC ;
RETI ;中断返回
;
;;;;;;;;;;;;;;;;;;;;
;;INTT1 PROGRAM ;;
;;;;;;;;;;;;;;;;;;;;
;
; T1计数器中断服务程序。(计数器T1由外中断1输入控制,当为高电平时计时开始)
INTT1: PUSH ACC ;堆栈保护
PUSH PSW ;
INC 6CH ;6CH计时 单元加1
MOV A,6CH ;移入A
JNZ INTT11 ;不等于0转INTT11
INC 6DH ;进位,6DH单元加1
MOV A,6DH ;移入A
JNZ INTT11 ; 不等于0转INTT11
SETB 00H ;计时器溢出,置溢出标志
INTT11: POP PSW ;恢复堆栈
POP ACC ;
RETI ;中断返回
;
;;;;;;;;;;;;;;;;;;;;
;;DISPLAY S ;;
;;;;;;;;;;;;;;;;;;;;
;
;里程显示控制程序
DISPLAYS: SETB P1.0 ;点亮LED1(显示里程状态)
CLR P1.1 ;关闭速度指示灯
SETB P3.7 ;显示小数点(最小显示为0.1公里)
LCALL SSS ;将圈数转为公里数
LCALL DISPLAY ;显示公里数据
LJMP START1 ;跳回START1
;
;
;;;;;;;;;;;;;;;;;;;;
;;DISPLAY V ;;
;;;;;;;;;;;;;;;;;;;;
;速度显示控制程序
DISPLAYV: CLR P1.0 ;关闭LED1(里程)灯
SETB P1.1 ;点亮LED2(显示时速状态)
CLR P3.7 ;关小数点显示
LCALL VVV ;每圈时间换算为公里/小时程序
MOV A,71H ;将十位数(BCD码)值移入A
SUBB A,#04H ; 与预定报警值比较
JNC WARING ; 时速超过40时报警
SETB P3.1 ;关报警灯
V1: LCALL DISPLAY ;显亮一次(为了改善闪烁)
RET ;子程序返回
WARING: CLR P3.1 ; 报警灯LED3点亮(并呜叫)
AJMP V1 ;转V1退出
;
;;;;;;;;;;;;;;;;;;;;
;;VIICWRITE ;;
;;;;;;;;;;;;;;;;;;;;
;归一化EEPROM存入程序(12M时钟),存入数在50H起单元
VIICWRITE: ACALL WMOV9
MOV SLA,#SLAW
MOV NUMBYT,#09H
LCALL WRNBYT
RET
WMOV9: MOV 5FH,#50H
MOV R0,#MTD
MOV R1,#5FH
MOV R2,#09H
WMOV: MOV A,@R1
MOV @R0,A
INC R0
INC R1
DJNZ R2,WMOV
RET
;
;;;;;;;;;;;;;;;;;;;;
;;VIICREAD ;;
;;;;;;;;;;;;;;;;;;;;
; 归一化EEPROM读出程序(12M时钟),读出数放入60H-67H单元
VIICREAD: MOV MTD,#50H ;
MOV SLA,#SLAW
MOV NUMBYT,#01H
LCALL WRNBYT
MOV SLA,#SLAR
MOV NUMBYT,#08H
LCALL RDNBYT
ACALL RMOV8
RET
RMOV8: MOV R0,#MRD
MOV R1,#60H
MOV R2,#08H
RMOV: MOV A,@R0
MOV @R1,A
INC R0
INC R1
DJNZ R2,RMOV
RET
;
;;;;;;;;;;;;;;;;;;;;
;;VIIC PROGRAM ;;
;;;;;;;;;;;;;;;;;;;;
; I2C串行归一化存储子程序
STA: SETB VSDA
SETB VSCL
NOP
NOP
NOP
NOP
CLR VSDA
NOP
CLR VSDA
NOP
NOP
NOP
NOP
CLR VSCL
RET
STOP: CLR VSDA
SETB VSCL
NOP
NOP
NOP
NOP
SETB VSDA
NOP
NOP
NOP
NOP
CLR VSDA
CLR VSCL
RET
MACK: CLR VSDA
SETB VSCL
NOP
NOP
NOP
NOP
CLR VSCL
SETB VSDA
RET
MNACK: SETB VSDA
SETB VSCL
NOP
NOP
NOP
NOP
CLR VSCL
CLR VSDA
RET
CACK: SETB VSDA
SETB VSCL
CLR F0
MOV C,VSDA
JNC CEND
SETB F0
CEND: CLR VSCL
RET
WRBYT: MOV R0,#08H
WLP: RLC A
JC WR1
AJMP WR0
WLP1: DJNZ R0,WLP
RET
WR1: SETB VSDA
SETB VSCL
NOP
NOP
NOP
NOP
CLR VSCL
CLR VSDA
AJMP WLP1
WR0: CLR VSDA
SETB VSCL
NOP
NOP
NOP
NOP
CLR VSCL
AJMP WLP1
RDBYT: MOV R0,#08H
RLP: SETB VSDA
SETB VSCL
MOV C,VSDA
MOV A,R2
RLC A
MOV R2,A
CLR VSCL
DJNZ R0,RLP
RET
WRNBYT: MOV R3,NUMBYT
LCALL STA
MOV A,SLA
LCALL WRBYT
LCALL CACK
JB F0,WRNBYT
MOV R1,#MTD
WRDA: MOV A,@R1
LCALL WRBYT
LCALL CACK
JB F0,WRNBYT
INC R1
DJNZ R3,WRDA
LCALL STOP
RET
RDNBYT: MOV R3,NUMBYT
LCALL STA
MOV A,SLA
LCALL WRBYT
LCALL CACK
JB F0,RDNBYT
RDN: MOV R1,#MRD
RDN1: LCALL RDBYT
MOV @R1,A
DJNZ R3,ACK
LCALL MNACK
LCALL STOP
RET
ACK: LCALL MACK
INC R1
SJMP RDN1
;
;;;;;;;;;;;;;;;;;;;;
;;DISPLAY PROGRAM ;;
;;;;;;;;;;;;;;;;;;;;
; 显示程序。显示BCD码在70H-73H单元内,采用共阴LED数码管
DISPLAY: MOV R1,#70H ;显示单元首址
MOV R2,#0FEH ;扫描字
PLAY: MOV A,R2 ;扫描字入A
MOV P2,A ;放到端口
MOV A,@R1 ;取显示数据
ANL A,#0FH ;去掉高四位(为0)
MOV DPTR,#TAB ;取段码表首址
MOVC A,@A+DPTR ;查显示数据对应段码
MOV P0,A ;段码输出
LCALL DL1MS ;点亮1毫秒
INC R1 ;指向下一显示数据地址
MOV A,R2 ;取扫描字
JNB ACC.3,ENDOUT ;已扫描到第四位,转ENDOUT退出
RL A ;循环左移
MOV R2,A ;放回R2
AJMP PLAY ;转PLAY循环
ENDOUT: SETB P2.0 ;关扫描
SETB P2.1 ;关扫描
SETB P2.2 ;关扫描
SETB P2.3 ;关扫描
RET ;扫描结束
;共阴段码表(可显示0-F)
TAB: DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H
DB 7FH,6FH,77H,7CH,39H,5EH,79H,71H
DB 00H
;
;;;;;;;;;;;;;;;;;;;;
;;SSS PROGRAM ;;
;;;;;;;;;;;;;;;;;;;;
; 里程处理程序,将自行车圈数据换算成公里数
SSS: MOV 19H,#64H ;除数最高位赋值
MOV 18H,#00H ; 除数赋值
MOV 17H,#00H ; 除数赋值
MOV 16H,#00H ; 除数赋值
MOV 11H,#00H ; 被除数赋值
MOV 12H,#00H ; 被除数赋值
MOV 13H,62H ; 被除数赋值
MOV 14H,61H ; 被除数赋值
MOV 15H,60H ; 被除数赋值
LCALL DIVST ; 调除法程序
LCALL BCDST ; 调二进制转BCD码程序
MOV A,25H ; 结果处理,将25H数移入A
ANL A,#0FH ; 将高四位置为0
MOV 70H,A ; 放入70H单元
MOV A,25H ; 25H数移入A
SWAP A ; 高低四位交换
ANL A,#0FH ; 将高四位置为0
MOV 71H,A ; 放入71H单元
MOV A,24H ; 24H数移入A
ANL A,#0FH ; 将高四位置为0
MOV 72H,A ; 放入72H单元