作者:未知 来源:89s52.cn
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 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位外部控制定时器
MOV SP,#75H ;堆栈在75H开始
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: 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
&, nbsp; MOV 72H,A ; 放入72H单元
MOV A,24H ; 24H数移入A
SWAP A ; 高低四位交换
ANL A,#0FH ; 将高四位置为0
MOV 73H,A ; 放入73H单元
RET ;子程序返回
;
;
;;;;;;;;;;;;;;;;;;;;
;;VVV PROGRAM ;;
;;;;;;;;;;;;;;;;;;;;
; 时速处理程序,最大显示速度为99公里/小时(用作自行车)
VVV: MOV 18H,68H ; 除数赋值
MOV 17H,69H ; 除数赋值
MOV 16H,6AH ; 除数赋值
MOV 11H,#00H ; 被除数赋值
MOV 12H,#00H ; 被除数赋值
MOV 13H,#36H ; 被除数赋值
MOV 14H,#0EEH ; 被除数赋值
MOV 15H,#80H ; 被除数赋值
LCALL DIVST ; 调除法程序
MOV 14H,#00H ; 舍去一位
LCALL BCDST ;二进制转BCD码程序
MOV A,25H ;以下将速度值放入显示单元
ANL A,#0FH ;高四位为0
MOV 70H,A ;放入70H内
MOV A,25H ;再取数
SWAP A ;高低四交换
ANL A,#0FH ;高四位为0
MOV 71H,A ;放入71H内
MOV 72H,#00H ;72H为0(高二位LED显示0)
MOV 73H,#00H ;73H为0
RET ;子程序返回
;
;
;;;;;;;;;;;;;;;;;
; DL1MS ;;
;;;;;;;;;;;;;;;;;
;1毫秒延时程序,LED点亮用
DL1MS: MOV R6,#14H
DL1: MOV R7,#19H
DL2: DJNZ R7,DL2
DJNZ R6,DL1
RET
;
;;;;;;;;;;;;;;;;;
; DL0.5S ;;
;;;;;;;;;;;;;;;;;
;出错闪烁用延时(255毫秒)
DL5S: MOV R5,#0FFH
DL3: LCALL DL1MS
DJNZ R5,DL3
RET
;;;;;;;;;;;;;;;;;
; 除法子程序 ;;
;;;;;;;;;;;;;;;;;
;除法子程序,用作四位除法,除数在16H-19H,被除数在11H-15H。
DIVST: CLR C ;运算开始
MOV A,13H
SUBB A,18H
MOV A,12H
SUBB A,17H
MOV A,11H
SUBB A,16H
JNC LOOP4
MOV B,#10H
NDIV1: CLR C
MOV A,15H
RLC A
MOV 15H,A
MOV A,14H
RLC A
MOV 14H,A
MOV A,13H
RLC A
MOV 13H,A
MOV A,12H
RLC A
MOV 12H,A
MOV A,11H
RLC A
MOV 11H,A
MOV F0,C
CLR C
MOV A,13H
SUBB A,18H
MOV 1AH,A
MOV A,12H
SUBB A,17H
MOV 19H,A
MOV A,11H
SUBB A,16H
JB F0,NDIV2
JC NDIV3
NDIV2: MOV 11H,A
MOV A,19H
MOV 12H,A
MOV A,1AH
MOV 13H,A
INC 15H
NDIV3: DJNZ B,NDIV1
CLR F0
DIVEND: RET
LOOP4: SETB F0
SJMP DIVEND
;
;;;;;;;;;;;;;;;;; ;;
; BCD码转换程序 ;
;;;;;;;;;;;;;;;;; ;;
;将14H、15H单元内数据转换成十进制BCD码放在24H、25H单元内。
BCDST: MOV R7,#10H
CLR C
MOV 25H,#00H
MOV 24H,#00H
KKK: MOV A,15H
RLC A
MOV 15H,A
MOV A,14H
RLC A
MOV 14H,A
MOV A,25H
ADDC A,25H
DA A
MOV 25H,A
MOV A,24H
ADDC A,24H
DA A
MOV 24H,A
DJNZ R7,KKK
RET
;
END ;程序结束