📄 library.asm
字号:
LCALL SPIBYTSND
POP SPIPGL
MOV R6,#4
AT45D04CARDRDNBYTR02:
MOV SPIDAT,#0
LCALL SPIBYTSND
DJNZ R6,AT45D04CARDRDNBYTR02
MOV R6,SPINBYT
MOV DPTR,#SPIDBUFR
AT45D04CARDRDNBYTR03:
LCALL SPIBYTRCV
MOVX @DPTR,A
INC DPTR
DJNZ R6,AT45D04CARDRDNBYTR03
MOV R1,#I2CDBUF
MOV @R1,#0FFH ;停止所有SPI总线器件操作
LCALL PCF8574CSWR
LCALL DELAY1MS
RET
;**********************************************
;向SPI存储器连续写SPINBYT字节数据(少于256字节)
;**********************************************
AT45D04WRNBYTR:
CLR SPISCLK
MOV R1,#I2CDBUF
MOV @R1,#AT45D04CS ;选中机内串行数据存储器
LCALL PCF8574CSWR
MOV SPIDAT,#053H ;(SPIDAT)=053H,Main Memory Page To Buffer1 Transfer
LCALL SPIBYTSND
PUSH SPIPGL
MOV A,SPIPGL
CLR C
RLC A
MOV SPIPGL,A
MOV A,SPIPGH
RLC A
MOV SPIDAT,A
LCALL SPIBYTSND
MOV SPIDAT,SPIPGL
LCALL SPIBYTSND
MOV SPIDAT,SPIADR
LCALL SPIBYTSND
POP SPIPGL
MOV R1,#I2CDBUF
MOV @R1,#0FFH ;停止所有SPI总线器件操作
LCALL PCF8574CSWR
LCALL DELAY25
CLR SPISCLK
MOV R1,#I2CDBUF
MOV @R1,#AT45D04CS ;选中机内串行数据存储器
LCALL PCF8574CSWR
MOV SPIDAT,#082H ;(SPIDAT)=082H,Main Memory Page Program Through Buffer1
LCALL SPIBYTSND
PUSH SPIPGL
MOV A,SPIPGL
CLR C
RLC A
MOV SPIPGL,A
MOV A,SPIPGH
RLC A
MOV SPIDAT,A
LCALL SPIBYTSND
MOV SPIDAT,SPIPGL
LCALL SPIBYTSND
MOV SPIDAT,SPIADR
LCALL SPIBYTSND
POP SPIPGL
MOV R6,SPINBYT
MOV DPTR,#SPIDBUFR
AT45D04WRNBYTR02:
MOVX A,@DPTR
MOV SPIDAT,A
LCALL SPIBYTSND
INC DPTR
DJNZ R6,AT45D04WRNBYTR02
MOV R1,#I2CDBUF
MOV @R1,#0FFH ;停止所有SPI总线器件操作
LCALL PCF8574CSWR
LCALL DELAY25
RET
;**********************************************
;从SPI存储器连续读SPINBYT字节数据(少于256字节)
;**********************************************
AT45D04RDNBYTR:
CLR SPISCLK
MOV R1,#I2CDBUF
MOV @R1,#AT45D04CS ;选中机内串行数据存储器
LCALL PCF8574CSWR
MOV SPIDAT,#0D2H ;(SPIDAT)=0D2H,Main Memory Page Read
LCALL SPIBYTSND
PUSH SPIPGL
MOV A,SPIPGL
CLR C
RLC A
MOV SPIPGL,A
MOV A,SPIPGH
RLC A
MOV SPIDAT,A
LCALL SPIBYTSND
MOV SPIDAT,SPIPGL
LCALL SPIBYTSND
MOV SPIDAT,SPIADR
LCALL SPIBYTSND
POP SPIPGL
MOV R6,#4
AT45D04RDNBYTR02:
MOV SPIDAT,#0
LCALL SPIBYTSND
DJNZ R6,AT45D04RDNBYTR02
MOV R6,SPINBYT
MOV DPTR,#SPIDBUFR
AT45D04RDNBYTR03:
LCALL SPIBYTRCV
MOVX @DPTR,A
INC DPTR
DJNZ R6,AT45D04RDNBYTR03
MOV R1,#I2CDBUF
MOV @R1,#0FFH ;停止所有SPI总线器件操作
LCALL PCF8574CSWR
LCALL DELAY1MS
RET
;=============================================
;数学运算子程序
;2002/3/8
;=============================================
;****************************
;十六进制到十进制数据转换
;****************************
;循环控制变量R7=8时,单字节;
; R7=16, 双字节。
;输入:R2 R3
;输出:R4 R5 R6
IBTD: CLR A
MOV R4,ACC
MOV R5,ACC
MOV R6,ACC
IBTD2: CLR C
MOV A,R3
RLC A
MOV R3,ACC
MOV A,R2
RLC A
MOV R2,ACC
MOV A,R6
ADDC A,R6
DA A
MOV R6,ACC
MOV A,R5
ADDC A,R5
DA A
MOV R5,ACC
MOV A,R4
ADDC A,R4
DA A
MOV R4,ACC
DJNZ R7,IBTD2
RET
;****************************
;十六进制整除
;(R2R3R4R5)/(R6R7)=>(R2R3R4R5)
;余数在R3
;****************************
IDIV:
PUSH PSW
ADJ_DIV:MOV B,#16
DIV_LP: MOV A,R5
CLR C
RLC A
MOV R5,ACC
MOV A,R4
RLC A
MOV R4,ACC
MOV A,R3
RLC A
MOV R3,ACC
XCH A,R2
RLC A
XCH A,R2
MOV PSW.5,C
CLR C
SUBB A,R7
MOV R1,ACC
MOV A,R2
SUBB A,R6
JB PSW.5,DIV_MOV
JC DIV_DEC
DIV_MOV:MOV R2,ACC
MOV A,R1
MOV R3,ACC
INC R5
DIV_DEC:DJNZ B,DIV_LP
;CLR PSW.5
;MOV A,#43
;ADD A,R5
;MOV R5,A
;MOV A,#0
;ADDC A,R4
;MOV R4,A
;MOV LOGBUF1,R4
;MOV LOGBUF0,R5
POP PSW
RET
;********************************
;读取键盘扫描码
;2002/05/01
;********************************
KEY: LCALL GETKEY ;获取键盘扫描码
MOV KEYCD0,KEYCODE
LCALL DLKEY1 ;键盘消抖延时
LCALL GETKEY ;再次获取扫描码
MOV A,KEYCODE
CJNE A,KEYCD0,KEY1 ;继续
CJNE A,#0FFH,KEY2 ;有效键盘扫描码
KEY1: CLR KEYWB ;无效键盘扫描码
LJMP KEY3
KEY2: SETB KEYWB
LCALL BUZZ300
KEY3: RET
;**************************
; 键盘扫描程序
; 2001/12/24
;**************************
GETKEY:
MOV R1,#I2CDBUF
MOV @R1,#0
LCALL PCF8574TWR
SETB C
MOV A,P3
ANL C,ACC.4
ANL C,ACC.5
ANL C,ACC.6
JNC GETKEY_LP
MOV KEYCODE,#0FFH ;无效键盘扫描码
MOV KEYCD0,#0FFH ;无效键盘扫描码
RET ;返回
GETKEY_LP:
MOV R1,#I2CDBUF
MOV @R1,#11111110B ;从第0行开始扫描键盘距阵
MOV R2,#0 ;键盘扫描计数器,共8个扫描循环
GETKEY_LP1:
LCALL PCF8574TWR
CLR A
MOV A,P3
JB ACC.4,GETKEY_LP2 ;KR0没键按下,跳转
CLR A
ADD A,R2
SJMP GETKEY_LP5
GETKEY_LP2:
JB ACC.5,GETKEY_LP3 ;KR1没键按下,跳转
MOV A,#08H
ADD A,R2
SJMP GETKEY_LP5
GETKEY_LP3:
JB ACC.6,GETKEY_LP4 ;KR2没键按下,跳转
MOV A,#10H
ADD A,R2
SJMP GETKEY_LP5
GETKEY_LP4:
MOV R1,#I2CDBUF
MOV A,@R1
RL A ;准备下一行扫描
MOV @R1,A
INC R2
CJNE R2,#8,GETKEY_LP1 ;扫描计数器不为8,继续
LJMP GETKEY_LP6
GETKEY_LP5:
MOV MSCOUNT,#00H
MOV TCOUNT,#00H
SETB LCDBKLT
GETKEY_LP6:
MOV KEYCODE,A ;保存键盘扫描码
RET
;===================================================
; LCD显示驱动子程序(基础)
; 2002/05/10
;===================================================
;********************************
;写指令代码子程序(左半屏)
;********************************
LCDPRL0:SETB LCDCS1 ;左半屏片选,设置为"10"
CLR LCDCS2
CLR LCDDI ;LCDDI=0
SETB LCDRW ;LCDRW=1
LCDPRL01:
MOV P0,#0FFH ;LCD数据总线置高电平,准备输入
SETB LCDEN ;LCDEN=1
MOV A,P0 ;从LCD数据总线读状态字
CLR LCDEN ;LCDEN=0
JB ACC.7,LCDPRL01 ;判断"忙"标志为0否,否再读
CLR LCDRW ;LCDRW=0
MOV P0,LCDCMD ;向LCD数据总线写指令代码
SETB LCDEN ;LCDEN=1
CLR LCDEN ;LCDEN=0
RET
;********************************
;写显示数据子程序(左半屏)
;********************************
LCDPRL1:SETB LCDCS1 ;左半屏片选,设置为"10"
CLR LCDCS2
CLR LCDDI ;LCDDI=0
SETB LCDRW ;LCDRW=1
LCDPRL11:
MOV P0,#0FFH ;LCD数据总线置高电平,准备输入
SETB LCDEN ;LCDEN=1
MOV A,P0 ;从LCD数据总线读状态字
CLR LCDEN ;LCDEN=0
JB ACC.7,LCDPRL11 ;判断"忙"标志为0否,否再读
SETB LCDDI ;LCDDI=1
CLR LCDRW ;LCDRW=0
MOV P0,LCDDAT ;写数据到LCD数据总线
SETB LCDEN ;LCDEN=1
CLR LCDEN ;LCDEN=0
RET
;********************************
; 读显示数据子程序(左半屏)
;********************************
LCDPRL2:SETB LCDCS1 ;左半屏片选,设置为"10"
CLR LCDCS2
CLR LCDDI ;LCDDI=0
SETB LCDRW ;LCDRW=1
LCDPRL21:
MOV P0,#0FFH ;LCD数据总线置高电平,准备输入
SETB LCDEN ;LCDEN=1
MOV A,P0 ;从LCD数据总线读状态字
CLR LCDEN ;LCDEN=0
JB ACC.7,LCDPRL21 ;判断"忙"标志为0否,否再读
SETB LCDDI ;LCDDI=1
MOV P0,#0FFH ;LCD数据总线置高电平,准备输入
SETB LCDEN ;LCDEN=1
MOV LCDDAT,P0 ;从LCD数据总线读数据
CLR LCDEN ;LCDEN=0
RET
;********************************
; 写指令子程序(右半屏)
;********************************
LCDPRR0:CLR LCDCS1 ;右半屏片选,设置为"01"
SETB LCDCS2
CLR LCDDI ;LCDDI=0
SETB LCDRW ;LCDRW=1
LCDPRR01:
MOV P0,#0FFH ;LCD数据总线置高电平,准备输入
SETB LCDEN ;LCDEN=1
MOV A,P0 ;从LCD数据总线读状态字
CLR LCDEN ;LCDEN=0
JB ACC.7,LCDPRR01 ;判断"忙"标志为0否,否再读
CLR LCDRW ;LCDRW=0
MOV P0,LCDCMD ;向LCD数据总线写指令代码
SETB LCDEN ;LCDEN=1
CLR LCDEN ;LCDEN=0
RET
;********************************
; 写显示数据子程序(右半屏)
;********************************
LCDPRR1:CLR LCDCS1 ;右半屏片选,设置为"01"
SETB LCDCS2
CLR LCDDI ;LCDDI=0
SETB LCDRW ;LCDRW=1
LCDPRR11:
MOV P0,#0FFH ;LCD数据总线置高电平,准备输入
SETB LCDEN ;LCDEN=1
MOV A,P0 ;从LCD数据总线读状态字
CLR LCDEN ;LCDEN=0
JB ACC.7,LCDPRR11 ;判断"忙"标志为0否,否再读
SETB LCDDI ;LCDDI=1
CLR LCDRW ;LCDRW=0
MOV P0,LCDDAT ;向LCD数据总线写数据
SETB LCDEN ;LCDEN=1
CLR LCDEN ;LCDEN=0
RET
;********************************
; 读显示数据子程序(右半屏)
;********************************
LCDPRR2:CLR LCDCS1 ;右半屏片选,设置为"01"
SETB LCDCS2
CLR LCDDI ;LCDDI=0
SETB LCDRW ;LCDRW=1
LCDPRR21:
MOV P0,#0FFH ;LCD数据总线置高电平,准备输入
SETB LCDEN ;LCDEN=1
MOV A,P0 ;从LCD数据总线读状态字
CLR LCDEN ;LCDEN=0
JB ACC.7,LCDPRR21 ;判断"忙"标志为0否,否再读
SETB LCDDI ;LCDDI=1
MOV P0,#0FFH ;LCD数据总线置高电平,准备输入
SETB LCDEN ;LCDEN=1
MOV LCDDAT,P0 ;从LCD数据总线读取数据
CLR LCDEN ;LCDEN=0
RET
;********************************
;点亮LCD屏BATT(电池)标志
;********************************
LCDBATT_ON:
MOV LCDCMD,#0BFH ;1011 1XXX 其中XXX=111,即第7页
LCALL LCDPRR0 ;LCD右半屏指令写
MOV LCDCMD,#7AH ;01XX XXXX 其中XX XXXX=11 1010,即第58列
;注:每执行一次数据读或写,列计数器均要递增
LCALL LCDPRR0 ;LCD右半屏指令写
LCALL LCDPRR2 ;LCD右半屏数据读
LCALL LCDPRR2 ;再读一次,即必须有一次空读操作
MOV A,LCDDAT
SETB ACC.7 ;置高电平,点亮LCD屏上的BATT(电池)标志
MOV LCDDAT,A
LCALL LCDPRR1 ;LCD右半屏数据写
RET
;********************************
;点亮LCD屏ARROW(箭头)标志
;********************************
LCDARROW_ON:
MOV LCDCMD,#0BFH ;1011 1XXX 其中XXX=111,即第7页
LCALL LCDPRR0 ;LCD右半屏指令写
MOV LCDCMD,#7BH ;01XX XXXX 其中XX XXXX=11 1011,即第59列
;注:每执行一次数据读或写,列计数器均要递增
LCALL LCDPRR0 ;LCD右半屏指令写
LCALL LCDPRR2 ;LCD右半屏数据读
LCALL LCDPRR2 ;再读一次,即必须有一次空读操作
MOV A,LCDDAT
SETB ACC.7 ;置高电平,点亮LCD屏上的ARROW(箭头)标志
MOV LCDDAT,A
LCALL LCDPRR1 ;LCD右半屏数据写
RET
;********************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -