單片機STC15W404AS的串口中斷方式接收上位機的命令(5個字節(jié),5F 01 02 XX FE,其中第四字節(jié)XX是變量,根據(jù)XX做相應的判斷執(zhí)行不同動作)
當?shù)谒淖止?jié)為#11H時,串口發(fā)送遞增再遞減的電壓值(做呼吸燈控制)現(xiàn)在只能執(zhí)行一次,第二次就不行,死機了。如果上電后接收到命令,不是11H
都能正常工作,只要有#11H,可以執(zhí)行循環(huán),但是要是有新的命令過來,就會死機了
TmpData EQU 01H
AUXR EQU 08EH
P5 DATA 0C8H
P1M1 DATA 091H
P1M0 DATA 092H
T2H DATA 0D6H
T2L DATA 0D7H
FagHX BIT P1.0 ;呼吸模式循環(huán)標志
TmpVset EQU 17H ;臨時電壓變量地址
TmpVsetL EQU 18H ;遞增初始電壓值地址
TmpVsetH EQU 19H ;遞減終止電壓值地址
ORG 0000H
LJMP MAIN ;上電,轉(zhuǎn)向主程序
ORG 0023H ;串行口的中斷入口地址
LJMP Uart1_Int_Recceive ;轉(zhuǎn)向中斷服務程序
ORG 0100H
;=======主程序開始=====================================================================
MAIN: LCALL Uart1_Initial ;串口初始化
MOV R3,#0 ;亮度檔位標識清零
Waitdata: SETB ES ;允許串行口中斷
SETB EA ;CPU開中斷
MOV R0,#40H ;存放接受的數(shù)據(jù)首地址---------------------
MOV R2,#0 ;存放接受的數(shù)據(jù)長度---------------------
Save_UartData:
LOP:MOV A,TmpData ;等待新的數(shù)據(jù)
CJNE R2,#5,LOP
CLR FagHX ; 呼吸循環(huán)標志:0---退出 ,1---執(zhí)行
CLR ES ;所有數(shù)據(jù)接收完畢,禁止串行中斷
CLR EA
;------------------------------------------------------------------------
;======根據(jù)上位機命令(5F 01 FE 11 FE,第四字節(jié)是變量)控制對應燈具亮度(變量放在43H的地址中)
KK: MOV A,43H ;查看地址43H(接收到的5個字節(jié)數(shù)據(jù)的第四個字節(jié)內(nèi)容做相應的功能判斷)
CJNE A,#11H,JJ
SETB FagHX
JMP HuxiMode
JJ: CJNE A,#12H,HH
MOV DPTR,#LED_AC5 ; 調(diào)光5檔
LCALL SendString ; UART發(fā)送 A220V
JMP Waitdata
HH: CJNE A,#13H,WW
MOV DPTR,#LED_AC1 ; 調(diào)光1檔
LCALL SendString ; UART發(fā)送 A030V
JMP Waitdata
WW: CJNE A,#14H,WW
MOV DPTR,#LED_AC3 ; 調(diào)光1檔
LCALL SendString ; UART發(fā)送 A100V
JMP Waitdata
;--------呼吸模式串口控制--------------------------------------
HuxiMode:
JNB FagHX,ExitHuxi ; 呼吸循環(huán)標志:0---退出 ,1---執(zhí)行
MOV 10H,#41H ;A
MOV 11H,#30H ;可控硅電壓值百位 0
MOV 12H,#30H ;可控硅電壓值十位 0
MOV 13H,#30H ;可控硅電壓值個位 0
MOV 14H,#56H ;V
MOV 15H,#0DH ;0D
MOV 16H,#0AH ;0A
MOV TmpVsetH,#0AAH ;6EH=110V,78H=120V,82=130v 8CH=140V 96H=150V A0H=160V AAH=170V B4H=180V BEH=190V C8H=200V
MOV TmpVsetL, #4BH ;1EH=30v 23H=35v 28H=40v,2DH=45v 32H=50V 37H=55V 3CH=60v 41H=65v 46H=70v 4BH=75v 50H=80v
AdjVsetUP:
MOV A,TmpVsetL ;起始電壓遞增
MOV TmpVset,A
VsetUP: JNB FagHX,ExitHuxi ; 呼吸循環(huán)標志:0---退出 ,1---執(zhí)行
MOV A,TmpVset ;起始電壓遞增
ADD A,#02H ;遞增步進值
MOV TmpVset,A ;步進增加的值保存
LCALL HextoASC ;轉(zhuǎn)ASCC字符
LCALL Uart1_Send ;發(fā)送控制值
LCALL Dly200ms ;延時
; Mov R1,#30 ; 30X10MS=300ms秒延時子程序
; DL44: LCall Delay
; JNB FagHX,XX ; 呼吸循環(huán)標志:0---退出 ,1---執(zhí)行
; Djnz R1,DL44
; XX:
MOV A,TmpVset
CJNE A,TmpVsetH,UPstop ;遞增后是否超過最大值
JMP VsetDonw
UPstop:JC VsetUP ;小于最大值繼續(xù)遞增
VsetDonw:
JNB FagHX,ExitHuxi ; 呼吸循環(huán)標志:0---退出 ,1---執(zhí)行
MOV A,TmpVset ;起始電壓遞減
SUBB A,#02H ;遞減步進值
MOV TmpVset,A ;步進遞減的值保存
LCALL HextoASC ;轉(zhuǎn)ASCC字符
LCALL Uart1_Send ;發(fā)送控制值
LCALL Dly200ms
; Mov R1,#30 ; 30X10MS=300ms秒延時子程序
; DL444: LCall Delay
; JNB FagHX,YY ; 呼吸循環(huán)標志:0---退出 ,1---執(zhí)行
; Djnz R1,DL444
;YY:
MOV A,TmpVset
CJNE A,TmpVsetL,DownStop ;遞減后的值與設定的最小值比較
JMP LOOPSTOP
DownStop:JC LOOPSTOP ;大于最小值繼續(xù)遞減
JMP VsetDonw
LOOPSTOP:JMP HuxiMode ;繼續(xù)下一次繼續(xù)循環(huán)
ExitHuxi:Ljmp MAIN
;----------單字節(jié)16進制數(shù)轉(zhuǎn)為3字節(jié)的ASCII碼-------------------------------
HextoASC: MOV A,TmpVset ;待轉(zhuǎn)的16進制數(shù)
MOV B,#100
DIV AB
ADD A,#30H
MOV 11H,A ;百位數(shù)存入地址11H
MOV A,B
MOV B,#10
DIV AB
ADD A,#30H
MOV 12H,A ;十位數(shù)存入地址12H
MOV A,B
ADD A,#30H
MOV 13H,A ;個位數(shù)存入地址13H
RET
;---------串口初始化-------------------------------------------------------
Uart1_Initial:
; CLR A
; CLR BUSY
; CLR EA
MOV SP, #3FH
MOV SCON,#50H ;8位數(shù)據(jù),可變波特率
ORL AUXR,#01H ;串口1選擇定時器2為波特率發(fā)生器
ORL AUXR,#04H ;定時器2時鐘為Fosc,即1T
MOV T2L,#0E0H ;設定定時初值
MOV T2H,#0FEH ;設定定時初值
ORL AUXR,#10H ;啟動定時器2
; SETB ES ;允許串行口中斷
; SETB EA ;CPU開中斷
RET
;-----------串口中斷接收---------------------------------------
UART1_Int_Recceive:
PUSH ACC
U1REC1:JBC RI,GetData1 ;是接收中斷,清除此標志,轉(zhuǎn)向GetData1接收
CLR TI ;是發(fā)送中斷,清除此標志,中斷返回
SJMP U1REC1
GetData1:MOV A,SBUF ;接收(讀入)數(shù)據(jù)
MOV @R0,A ;存放數(shù)據(jù)到30H開頭的RAM-----------
MOV TmpData,A
INC R0 ;修改數(shù)據(jù)區(qū)指針-------------
INC R2 ;是否接收到5個字節(jié) ,數(shù)據(jù)長度為5個字節(jié)
CLR FagHX ;呼吸模式循環(huán)標志置零
POP ACC
RETI;中斷返回
;16進制發(fā)送---------------------------------------------------
Uart1_Send: CLR ES ; 禁止串行口中斷
CLR EA ; 禁止CPU中斷
CLR A
MOV R0,#10H ;發(fā)送從10H地址開始中的數(shù)據(jù)
MOV R2,#07 ;轉(zhuǎn)發(fā)的數(shù)據(jù)長度7個字節(jié)
S1: MOV A,@R0 ; 串口發(fā)送子程序/取碼指針
MOV SBUF,A ; 載入SBUF發(fā)送
S2:JBC TI,S3 ; 是否發(fā)送完?
SJMP S2
S3:INC R0 ; 取下一個碼
DJNZ R2,S1
SETB ES ; 允許串行口中斷
SETB EA ; CPU開中斷
RET
;----串口發(fā)送字符串-------------------------------------------------
SendString:
CLR ES ; 禁止串行口中斷
CLR EA ; 禁止CPU中斷
CLR A
MOVC A,@A+DPTR ; 到TABLE取碼
MOV SBUF,A ; 載入SBUF發(fā)送
SCONQ2:JBC TI,SCONQ3 ; 是否發(fā)送完?
SJMP SCONQ2
SCONQ3:INC DPTR ; 取下一個碼
CJNE A,#0AH,SendString ; 數(shù)據(jù)塊取碼未完成繼續(xù)取碼 發(fā)送AXXXV 如果發(fā)到字母V(ACSII碼56H)則結束
SETB ES ; 允許串行口中斷
SETB EA ; CPU開中斷
RET
;-----------軟件延時----------------------------------------------
Dly800ms: Mov R1,#80 ; 80X10MS=800ms秒延時子程序
DL6: Call Delay
Djnz R1,DL6
Ret
Dly500ms: Mov R1,#50 ; 50X10MS=500ms秒延時子程序
DL5: Call Delay
Djnz R1,DL5
Ret
Dly300ms: Mov R1,#30 ; 20X10MS=200ms秒延時子程序
DL4: Call Delay
Djnz R1,DL4
Ret
Dly200ms: Mov R1,#20 ; 20X10MS=200ms秒延時子程序
DL3: Call Delay
Djnz R1,DL3
Ret
Dly100ms: Mov R1,#10 ; 20X10MS=200ms秒延時子程序
DL2: Call Delay
Djnz R1,DL2
Ret
Delay:MOV R7,#01H ;誤差 0.000000000000us 3.6864M 10ms
DL1:MOV R6,#0DEH ; 222
DL0:MOV R5,#28H ;40
DJNZ R5,$
DJNZ R6,DL0
DJNZ R7,DL1
RET
;====PWM對應亮度的可控硅電壓設置=============================
LED_OFF:DB 'A020V',0DH,0AH ;關機控制命令
LED_ON:DB 'A030V',0DH,0AH ;開機默認亮度
LED_AC1:DB 'A030V',0DH,0AH ;第一檔亮度控制
LED_AC2:DB 'A080V',0DH,0AH ;第二檔亮度控制
LED_AC3:DB 'A100V',0DH,0AH ;第三檔亮度控制
LED_AC4:DB 'A140V',0DH,0AH ;第四檔亮度控制
LED_AC5:DB 'A220V',0DH,0AH ;第五檔亮度控制
LED_Sleep:DB 'A030V',0DH,0AH ;睡眠模式亮度控制
LED_Warm:DB 'A070V',0DH,0AH ;溫馨模式亮度控制
LED_Reading:DB 'A190V',0DH,0AH ;閱讀模式亮度控制
LED_Bright:DB 'A220V',0DH,0AH ;明亮模式亮度控制
LED_Moon:DB 'A040V',0DH,0AH ;夜燈模式亮度控制
END
;============程序結束========================================
|