📄 main.asm
字号:
;注意:由于87LPC764内部有两个EEROM的配置字节,因此用户在进行芯片编程时
; 除了写入编译好的Hex或Bin文件外,还必须对这些EEROM进行单独编程,
; 如果不加注意,87LPC764将不能正常工作.在此程序中,UCFG2可以不用
; 处理,但是UCFG1要如下确定:
; UCFG1.7(WDTE)=0 关闭看门狗.
; UCFG1.6(RPD) =1 关闭复位引脚.
; UCFG1.5(PRHI)=1 口复位为高电平.
; UCFG1.4(BOV) =0或1,用户可以自己选择:1(掉电电压为2.5V)或0(为3.8V).
; UCFG1.3(CLKR)=0(标准8051时钟),用户也可以选1(8051的2倍时钟).
; UCFG[2..0](FOSC[2..0])=000,4MHz-20MHz晶振.
ORG 0FD00H
UCFG1: DB 78H
/*数值定义*/
CTVAL EQU 02H ;设置I2C寄存器标志位CT1,CT0
/*屏蔽I2CFG标志位*/
BTIR EQU 10H ;屏蔽TIRUN
BMRQ EQU 40H ;屏蔽MASTRQ
/*屏蔽I2CON标志位*/
BCXA EQU 80H ;屏蔽CXAE
BIDLE EQU 40H ;屏蔽IDLE
BCDR EQU 20H ;屏蔽CDRL
BCARL EQU 10H ;屏蔽CARL
BCSTR EQU 08H ;屏蔽CSTR
BCSTP EQU 04H ;屏蔽CSTP
BXSTR EQU 02H ;屏蔽XSTR
BXSTP EQU 01H ;屏蔽XSTP
/*由I2C软件分配RAM*/
SubAdr1 DATA 2DH
BitCnt DATA 21H ;I2C数据位计数器
ByteCnt DATA 22H
SlvAdr DATA 23H ;被激活的被控器地址
SubAdr DATA 24H
RcvDat DATA 25H ;接收数据缓冲区(4字节),地址为25H-28H
XmtDat DATA 29H ;发送数据缓冲区(4字节),地址为29H-2CH
StkSave DATA 2EH ;保存堆栈地址
KEY_CODE DATA 15H ;键盘代码
SOFT_TMR3 DATA 12H
jf_jsq DATA 2AH
Flags DATA 20H ;I2C软件状态标志位
NoAck BIT Flags.0 ;指明没有应答标志位
Fault BIT Flags.1 ;指明总线出错
retry BIT Flags.2 ;指明I2C最后的数据传送失败,应该重复操作
KEY_ZJ BIT P0.1
KEY_XSJ BIT P0.2
KEY_XXJ BIT P0.3
KEY_DSJ BIT P0.4
/*程序开始*/
;复位和中断向量
ORG 0000H
AJMP Reset ;复位向量
;***************************************************************
;中断程序
;***************************************************************
; ORG 001BH ;定时器1中断地址
; AJMP TIME1
;**************************************
;定时器1中断程序
;**************************************
;TIME1:
;添一条检测BAR_CNTL寄存器值的程序,如该寄存器前三位值为0,跳出。
; LCALL EXP1 ;读BAR_CNTL寄存器的值
; MOV R0,#RcvDat
; MOV A,@R0
; ANL A,#07H ;屏蔽后五位,以便判断前三位的值。
; CJNE A,#00H,ZXGB
; SJMP SZJS ;如果该寄存器值的前三位为0,则说明不用关闭菜单。
;ZXGB: LCALL SDelay
; LCALL SDelay
; LCALL SDelay
; LCALL GBCD ;关闭菜单
;SZJS: MOV TH1,#00H ;置初值
; MOV TL1,#00H
; CLR TF1 ;软件清除溢出标志
; RETI
;******************************************
ORG 003BH ;键盘中断服务程序
ANL AUXR1,#7FH ;清除KBF溢出标志
CLR EKB ;禁止KBI中断
;LCALL CDZH
RETI
ORG 0053H ;看门狗定时器中断服务程序
CLR EWD ;禁止 WDT 中断
ORL AUXR1, #08H ;软件复位
RETI
/*定时器I中断*/
ORG 0073H ;定时器I中断地址
AJMP TimerI
TimerI: SETB CLRTI ;清除定时器I中断
CLR TIRUN
ACALL ClrInt ;中断返回
MOV SP,StkSave ;恢复堆栈指针返回主程序
LJMP Recover ;试图恢复总线
ClrInt: RETI
;************************************************************
;主程序开始
;************************************************************
ORG 0100H
Reset:
; ACALL INIT_WDT ;看门狗初始化
; ACALL INIT_KBI ;键盘初始化设置
; ACALL INIT_TM1 ;定时器1初始化
ACALL GBDD_CK ;关闭掉电检测功能
; MOV IP1,#02H ;中断优先级设置
LCALL BI
MOV KEY_CODE,#00H ;键值初始化为00H
SETB EA ;开中断
SETB ETI ;开放定时器I中断
; SETB EWD ;开放看门狗定时器中断
LCALL DYSJ ;将EEPROM中的数据调入LM1238
LCALL SDelay ;延时后,再调用数据
LCALL SDelay
LCALL DYSJ
;对ALT寄存器进行操作
CLR A
MOV A,#24H
MOV R0,#XmtDat
MOV @R0,A
LCALL DALT
; ACALL WDT_FEED ;执行喂狗程序
;对图象位置和大小进行控制
CLR A
MOV A,#8BH
MOV R0,#XmtDat
MOV @R0,A
ACALL XHORIZ
ACALL WDT_FEED
CLR A
MOV A,#87H
MOV R0,#XmtDat
MOV @R0,A
ACALL XVERT
; MOV JF_JSQ, #0FFH ;延时20mS, 去抖动
LOOP:
MOV JF_JSQ,#0FFH
LCALL KEY_SCAN1
LCALL KEY_SCAN2
; ACALL WDT_FEED ;执行喂狗程序
; LCALL DYSJ ;调用EEPROM中的数据
LCALL CHK_POF ;检查上电标志POF.
PPOF:
CLR A
CJNE A,KEY_CODE,SPX ;如果当前键值不为0,则检查按键释放
;只有检测到按键释放后,才能进行新的按键操作
LCALL DYSJ ;调用EEPROM中的数据
LCALL KEY_TASK ;执行键盘扫描以及相应操作
MOV KEY_CODE,R7 ;将键盘扫描得到的值保存在KEY_CODE
JMP LOOP ;返回循环检测
SPX:
LCALL KEY_SCAN1
LCALL KEY_SCAN2
LCALL KEY_TASK ;执行键盘扫描以及相应操作
LCALL KEY_RELS ;执行按键释放检查程序
LCALL D20MS
DJNZ JF_JSQ, SPX;等待延时结束.
LCALL KEY_RELS
JNC LOOP ;如果检测到按键未释放,则循环检测
;如果检查到按键释放,则执行下列动作
LCALL SDELAY
LCALL KEY_RELS
JNC LOOP
LCALL SDELAY
LCALL KEY_RELS
JNC LOOP
LCALL SDELAY
LCALL KEY_RELS
JNC LOOP
LCALL SDELAY
LCALL KEY_RELS
JNC LOOP
LCALL SDELAY
LCALL KEY_RELS
JNC LOOP
LCALL SDELAY
LCALL KEY_RELS
JNC LOOP
LCALL SDELAY
LCALL KEY_RELS
JNC LOOP
LCALL SDELAY
LCALL KEY_RELS
JNC LOOP
LCALL GBCD
; LCALL CZ_TM1
; LCALL CSJ ;再一次保存数据
MOV JF_JSQ, #0FFH ;延时20mS, 去抖动
ANL AUXR1,#7FH ;清除键盘中断标志KBF
MOV KEY_CODE,#00H ;设置当前键值为00H(表示无按键)
; CLR ET1
JMP LOOP ;返回循环检测
;**********************************
;看门狗初始化程序
;**********************************
INIT_WDT:ORL WDCON,#17H ;开启看门狗定时器(溢出时间为2.1秒)
ACALL WDT_FEED ;设置完后,喂狗一次
RET
;**********************************
;喂狗程序
;**********************************
WDT_FEED:
MOV WDRST,#1EH
MOV WDRST,#0E1H
RET
;**************************************
;对CLMP/PLL/VBL/OOR寄存器进行操作
;**************************************
BI: MOV A,#12H
MOV R0,#XmtDat
MOV @R0,A
MOV SlvAdr,#0BAH
MOV SubAdr,#1EH
MOV SubAdr1,#08H
MOV ByteCnt,#1
LCALL SendSub
JB retry,BI
RET
;**************************************
;对HORIZ和VERT两个寄存器进行操作
;**************************************
XHORIZ:MOV SlvAdr,#0BAH
MOV SubAdr,#02H
MOV SubAdr1,#08H
MOV ByteCnt,#1
LCALL SendSub
JB retry,XHORIZ
RET
XVERT: MOV SlvAdr,#0BAH
MOV SubAdr,#03H
MOV SubAdr1,#08H
MOV ByteCnt,#1
LCALL SendSub
JB retry,XVERT
RET
;*******************************************************************
;将调节亮度后,进度条的值(即当时BAR_CNTL中的值)存入存储器30H单元中
;*******************************************************************
CLJDT:LCALL EXP1
MOV A,@R0
MOV R0,#XmtDat
MOV @R0,A
MOV SlvAdr,#0A0H
MOV SubAdr,#30H
MOV ByteCnt,#1
LCALL SendSub1
JB retry,CLJDT
RET
;*******************************************************************
;将调节对比度后,进度条的值(即当时BAR_CNTL中的值)存入存储器的31H单元中
;*******************************************************************
CDJDT:LCALL EXP1
MOV A,@R0
MOV R0,#XmtDat
MOV @R0,A
MOV SlvAdr,#0A0H
MOV SubAdr,#31H
MOV ByteCnt,#1
LCALL SendSub1
JB retry,CDJDT
RET
;*******************************************************************
;将调节水平后,进度条的值(即当时BAR_CNTL中的值)存入存储器的32H单元中
;*******************************************************************
CSJDT:LCALL EXP1
MOV A,@R0
MOV R0,#XmtDat
MOV @R0,A
MOV SlvAdr,#0A0H
MOV SubAdr,#32H
MOV ByteCnt,#1
LCALL SendSub1
JB retry,CSJDT
RET
;*****************************************************************
;将调节垂直后,进度条的值(即当时BAR_CNTL中的值)存入存储器的33H单元中
;*****************************************************************
CCJDT:LCALL EXP1
MOV A,@R0
MOV R0,#XmtDat
MOV @R0,A
MOV SlvAdr,#0A0H
MOV SubAdr,#33H
MOV ByteCnt,#1
LCALL SendSub1
JB retry,CCJDT
RET
;***************************************************************
;将存储器30H单元中值调入BAR_CNTL中
;***************************************************************
DLBRZ:MOV SlvAdr,#0A0H
MOV SubAdr,#30H
MOV ByteCnt,#1
LCALL RcvSub1
JB retry,DLBRZ
MOV R0,#RcvDat
MOV A,@R0
ANL A,#0F8H ;屏蔽A的前三位
MOV R2,A
LCALL EXP1 ;读BAR_CNTL寄存器中的值
MOV R0,#RcvDat
MOV A,@R0
ANL A,#07H ;屏蔽A的后五位
ORL A,R2
MOV R0,#XmtDat
MOV @R0,A
LCALL XMLL3
RET
;***************************************************************
;将存储器31H单元中值调入BAR_CNTL中
;***************************************************************
DDBRZ:MOV SlvAdr,#0A0H
MOV SubAdr,#31H
MOV ByteCnt,#1
LCALL RcvSub1
JB retry,DDBRZ
MOV R0,#RcvDat
MOV A,@R0
ANL A,#0F8H ;屏蔽A的前三位
MOV R2,A
LCALL EXP1 ;读BAR_CNTL寄存器中的值
MOV R0,#RcvDat
MOV A,@R0
ANL A,#07H ;屏蔽A的后五位
ORL A,R2
MOV R0,#XmtDat
MOV @R0,A
LCALL XMLL3
RET
;***************************************************************
;将存储器32H单元中值调入BAR_CNTL中
;***************************************************************
DSBRZ:MOV SlvAdr,#0A0H
MOV SubAdr,#32H
MOV ByteCnt,#1
LCALL RcvSub1
JB retry,DSBRZ
MOV R0,#RcvDat
MOV A,@R0
ANL A,#0F8H ;屏蔽A的前三位
MOV R2,A
LCALL EXP1 ;读BAR_CNTL寄存器中的值
MOV R0,#RcvDat
MOV A,@R0
ANL A,#07H ;屏蔽A的后五位
ORL A,R2
MOV R0,#XmtDat
MOV @R0,A
LCALL XMLL3
RET
;***************************************************************
;将存储器33H单元中值调入BAR_CNTL中
;***************************************************************
DCBRZ:MOV SlvAdr,#0A0H
MOV SubAdr,#33H
MOV ByteCnt,#1
LCALL RcvSub1
JB retry,DCBRZ
MOV R0,#RcvDat
MOV A,@R0
ANL A,#0F8H ;屏蔽A的前三位
MOV R2,A
LCALL EXP1 ;读BAR_CNTL寄存器中的值
MOV R0,#RcvDat
MOV A,@R0
ANL A,#07H ;屏蔽A的后五位
ORL A,R2
MOV R0,#XmtDat
MOV @R0,A
LCALL XMLL3
RET
;**************************************
;对ALT寄存器进行操作(使用第一套图)
;**************************************
DALT: MOV SlvAdr,#0BAH
MOV SubAdr,#04H
MOV SubAdr1,#08H
MOV ByteCnt,#1
LCALL SendSub
JB retry, DALT
RET
;**************************************
;读BAR_CNTL寄存器的程序
;**************************************
EXP1: MOV R0,#RcvDat
MOV BYTECNT,#4
CLR A
CLEAR0: MOV @R0,A
INC R0
DJNZ BYTECNT,CLEAR0
XML0: MOV SLVADR,#0BAH
MOV SubAdr,#00H
MOV SubAdr1,#08H
MOV BYTECNT,#1
LCALL RcvSub
JB retry,XML0
RET
;**************************************
;一般情况下使用
;**************************************
XMLL3: MOV SLVADR,#0BAH
MOV SUBADR,#00H
MOV SUBADR1,#08H
MOV ByteCnt,#1
LCALL SendSub
JB retry,XMLL1
RET
;**************************************
;对BAR_CNTL寄存器进行写操作(增加时使用)
;**************************************
XMLL1: LCALL EXP1
MOV A,@R0
ANL A,#0F8H
CJNE A,#0F8H,CFG1
SJMP CGH
;CFG: CJNE A,#00H,CFG1
; SJMP CGH
CFG1: MOV A,@R0
ADD A,#08H
MOV R0,#XmtDat
MOV @R0,A
MOV SLVADR,#0BAH
MOV SUBADR,#00H
MOV SUBADR1,#08H
MOV ByteCnt,#1
LCALL SendSub
JB retry,XMLL1
CGH: RET
;***************************************
;减少或降低时使用
;***************************************
XMLL4: LCALL EXP1
MOV A,@R0
ANL A,#0F8H
CJNE A,#00H,CFG
SJMP CGH1
;CFG: CJNE A,#00H,CFG1
; SJMP CGH
CFG: MOV A,@R0
SUBB A,#08H
MOV R0,#XmtDat
MOV @R0,A
MOV SLVADR,#0BAH
MOV SUBADR,#00H
MOV SUBADR1,#08H
MOV ByteCnt,#1
LCALL SendSub
JB retry,XMLL4
CGH1: RET
;***************************************
;对ICN_INDX寄存器进行写操作
;***************************************
XMLL2: MOV SLVADR,#0BAH
MOV SUBADR,#01H
MOV SUBADR1,#08H
MOV ByteCnt,#1
LCALL SendSub
JB retry,XMLL2
RET
;***************************************
;读ICN_INDX寄存器的程序
;***************************************
EXP2: MOV R0, #RCVDAT
MOV BYTECNT, #4
CLR A
CLEAR1: MOV @R0,A
INC R0
DJNZ BYTECNT, CLEAR1
XML2 : MOV SLVADR,#0BAH
MOV SUBADR,#01H ;将调用OSD寄存器地址送入SUBADR
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -