?? ir_uart.asm
字號:
;*******************************************************************************************
; 文件名: IR_UART.ASM *
; 創建人: 邱作霖 創建時間 : 2005.10.1 *
; 修改人: 邱作霖 修改時間 : 2005.10.1 *
; 功能 : 接收紅外鍵盤\鼠標數據 上位機通訊 送出數據 紅外學習、紅外發射 *
; 版權 : *
;*******************************************************************************************
; IR_UART.asm ; 文件名
; IR1.0 ; 版本
INCLUDE "MAIN.H" ; 包含文件 偉福自定義包含文件
;$INCLUDE (MAIN.H) ; 包含文件 COMP51定義包含文件
; 代碼開始 ;┌──────────────────┐
ORG 0000H ;│代碼段開始地址 │
LJMP MAIN ;│ │
ORG 0003H ;│外部中斷0 入口: IE0 紅外通訊 │
LJMP INT_IRDA ;│ │
DB 32H ;│防止 程序調入 中斷向量地址, 清零 │
ORG 000BH ;│定時器 T0 中斷入口地址 32H = RETI │
DB 32H ;│將 不使用的 中斷地址 清零 │
ORG 0013H ;│外部中斷1 入口: IE1 鍵盤通訊 │
DB 32H ;│防止 程序調入 中斷向量地址, 清零 │
ORG 001BH ;│定時器 T1 中斷入口地址 │
LJMP INT_TMER1 ;│定時器 T1 中斷入口地址 │
DB 32H ;│ │
; ORG 0023H ;│串口 中斷入口地址 │
; LJMP INT_UART ;│串口 中斷入口地址 │
; DB 00H,00H,00H,00H,32H ;│ │
;***************************************************;└──────────────────┘
; 程序開始 ;
MAIN: ACALL MYMCU ; 設置單片機的參數
MOV R0,#7FH ; 清零前 RAM 128 字節
MOV @R0,#00H ; 00H-7FH
DJNZ R0,$-2 ; 清理 殘留的數據,在熱啟動時有用 一般在軟開機
CLR f_IR_OUT ; 置0 紅外發射
CLR f_LED1 ; LED滅
CLR f_LED2 ; LED滅
CLR f_LED3 ; LED滅
CLR f_LED4 ; LED滅
;***************************************************;
; 系統資源初始化 ;
SYSTEM: MOV SP,#c_SYSTEM_SP ; 設置堆棧
MOV g_DATA_SP_E,#c_DATA_SP_S ; 送數據緩沖區片內數據 RAM 指針 初始值
MOV g_WINK_TMER,#255 ; LED閃爍時間計數器 初值 大概255*60us
MOV g_WINK_TMER1,#2 ; LED閃爍次數計數器 初值 閃兩次
MOV g_IR_TMER_DOG1,#c_TMER_OVER ;
ACALL IR_INI ; 紅外復位子程序
SETB EA ; 開啟總中斷
;***************************************************;
; 主循環 優先級從上到下減小 ;
MAIN_LOOP: JB f_DATA,TASK1 ; 單片機是否有數據要上傳給CPU
JB RI,TASK2 ; 是否收到串口數據
SETB EX0 ; 允許 外部 0 中斷 實時設置中斷,防止中斷被屏蔽。紅外通訊
LOOP: AJMP MAIN_LOOP ; 循環結束
; 主循環結束 ;
;***************************************************;
; 任務表 ; 優先級從上到下減小
TASK1: AJMP DATA_OUT ; 鍵盤鼠標數據緩沖區滿 使用模擬串口送給上位機cpu19200
TASK2: AJMP UART_RXD ; 接收到上位機CPU數據 處理 19200
; 任務表結束 ; 任務表結束
;***************************************************;
;┌─────┬─────────────────-┐;
;│DATA_OUT │送出緩沖區數據 │;
;├─────┼─────────────────-┤;
;│入口參數: │f_DATA=1 │;
;├─────┼─────────────────-┤;
;│出口參數: │ │;
;├─────┼─────────────────-┤;
;│影響資源: │A,R1,g_DATA_SP_E │;
;└─────┴─────────────────-┘;
DATA_OUT: ACALL DATA_TXD ; TASK1 送出數據
CLR f_DATA ; 處理完畢
AJMP MAIN_LOOP ; 退出
;┌─────┬─────────────────-┐;
;│DATA_TXD │ 清緩沖區 │;
;└─────┴─────────────────-┘;
DATA_TXD: MOV R1,#c_DATA_SP_S ; 送數據緩沖區片內數據 RAM 指針 初始值
DATA_TXD_LOOP: MOV A,R1 ;
CJNE A,g_DATA_SP_E,DATA_TXD_BYTE ; 判斷是否棧底 不是就送出數據
SETB f_LED_WINK ; 申請LED 閃爍
DATA_TXD_RET: MOV g_DATA_SP_E,#c_DATA_SP_S ; 送數據緩沖區片內數據 RAM 指針 初始值
RET ;
DATA_TXD_BYTE: MOV A,@R1 ; 取數據 間接尋址
ACALL UART_TXD ;
INC R1 ; 調整指針
AJMP DATA_TXD_LOOP ; 繼續送出數據
;┌─────┬─────────────────-┐;
;│UART_TXD │ 從串口送出數據 │;
;└─────┴─────────────────-┘;
UART_TXD: CLR TI ; 冗余指令 防止 以前的TI沒有清除 TI中斷需要軟件清除
MOV SBUF,A ; 串口送出數據
MOV g_SOFT_DOG,#0 ; 軟件看門狗延時 最大4*256=1024us
WAIT_TI: JB TI,TXD_RET ; 等待發送完畢 ,需要加限時服務 如果 1024us內沒有收到 放棄本次發送
DJNZ g_SOFT_DOG,WAIT_TI ; 防止串口出錯一直在這里等待
RET ; 時間溢出 返回 暫時沒有考慮傳輸錯誤的處理
TXD_RET: CLR TI ; TI中斷需要軟件清除
RET ;
;****************************************************
;┌─────┬─────────────────-┐;
;│UART_RXD │上位機串口命令處理 │;
;├─────┼─────────────────-┤;
;│入口參數: │RI=1 │;
;├─────┼─────────────────-┤;
;│出口參數: │ │;
;├─────┼─────────────────-┤;
;│影響資源: │A,SBUF │;
;└─────┴─────────────────-┘;
UART_RXD: CLR RI ; TASK2 處理了 清除標志位
MOV A,SBUF ; 接收的CPU模擬串口數據
;┌──────┬────────────────-┐;
;│FACTORY │工廠測試命令 │;
;└──────┴────────────────-┘;
FACTORY: CJNE A,#"F",IROUT ;
CLR f_LED3 ; 工廠測試 LED關閉
ACALL UART_TXD ;
MOV A,#0DH ;
ACALL UART_TXD ;
MOV DPTR,#FACTORY_LIST ;
MOV R7,#19 ; 計數器
FACTORY_LOOP: CLR A ;
MOVC A,@A+DPTR ;
ACALL UART_TXD ;
INC DPTR ;
DJNZ R7,FACTORY_LOOP ; 是否傳輸完畢
AJMP FACTORY_TEST ;
FACTORY_LIST: DB "enter factory mode" ;
DB 0DH, ; 回車 0AH:新行
;┌──────┬────────────────-┐;
;│FACTORY_TEST│工廠測試 │;
;├──────┼────────────────-┤;
;│入口參數: │收到上位機串口命令“F” │;
;└──────┴────────────────-┘;
FACTORY_TEST: CLR EX0 ; 不允許紅外中斷 進入工廠測試,獨占模式 只有定時器和串口工作
CLR ET0 ; 不允許鼠標中斷
CLR EX1 ; 不允許鍵盤中斷
MOV R3,#0 ; 計時器清零
CLR f_TIME_OVER ; 標志位清零
TEST_LOOP: JB RI,TEST_RI ; 是否收到串口數據
JB f_TIME_OVER,TEST_TIME ; 是否計滿122880us
AJMP TEST_LOOP ; 循環
TEST_RI: CLR RI ; TASK2 處理了 清除標志位
MOV A,SBUF ; 接收的CPU模擬串口數據
CJNE A,#"f",TEST_LOOP ; 除了"f"啥子都不處理。 "f":喂狗指令
ACALL UART_TXD ;
MOV A,#0DH ;
ACALL UART_TXD ;
MOV R3,#0 ; 計時器清零
AJMP TEST_LOOP ; 上位機工廠測試清零指令
TEST_TIME: CLR f_TIME_OVER ; 清除122880us時間溢出標志位
INC R3 ; 計數器加一
MOV A,R3 ; 判斷是否溢出
CJNE A,#60,TEST_LOOP ; 總時間 :60*122880uS= 7.372800秒
SETB f_LED3 ; 工廠測試看門狗溢出 LED打開 報警
MOV DPTR,#TEST_TIME_LIST ;
MOV R7,#10 ; 計數器
TEST_TIME_LOOP: CLR A ;
MOVC A,@A+DPTR ;
ACALL UART_TXD ;
INC DPTR ;
DJNZ R7,TEST_TIME_LOOP ; 是否傳輸完畢
AJMP MAIN_LOOP ;
TEST_TIME_LIST: DB "time over" ;
DB 0DH, ; 回車 0AH:新行
;┌─────┬─────────────────-┐;
;│IROUT │紅外發射處理程序 │;
;└─────┴─────────────────-┘;
IROUT: CJNE A,#"S",VER ; 判斷是否紅外發射 后面跟3個字節的遙控器鍵碼數據
CALL IROUT_OUT ; 調用紅外發射程序
ACALL UART_TXD ; 返回命令字
MOV A,#0DH ; 送回車換行
ACALL UART_TXD ;
AJMP MAIN_LOOP ;
;┌─────┬─────────────────-┐;
;│VER │上位機命令處理: 要求版本 │;
;└─────┴─────────────────-┘;
VER: CJNE A,#"V",DATE ; 判斷是要輸出:時間,版本信息,鍵盤鼠標命令
ACALL UART_TXD ;
MOV A,#0DH ;
ACALL UART_TXD ;
MOV DPTR,#VER_LIST ;
MOV R7,#7 ; 計數器
VER_LOOP: CLR A ;
MOVC A,@A+DPTR ;
ACALL UART_TXD ;
INC DPTR ;
DJNZ R7,VER_LOOP ; 是否傳輸完畢
AJMP MAIN_LOOP ;
VER_LIST: DB "IR1.00" ; IR1.00
DB 0DH ; 回車
;┌─────┬─────────────────-┐;
;│DATE │上位機命令處理: 請求日期 │; 暫時沒有用到
;└─────┴─────────────────-┘;
DATE: CJNE A,#"D",RI_RET ; 判斷命令是否請求日期
ACALL UART_TXD ;
MOV A,#0DH ;
ACALL UART_TXD ;
MOV DPTR,#DATA_LIST ;
MOV R7,#11 ; 計數器
DATE_LOOP: CLR A ;
MOVC A,@A+DPTR ;
ACALL UART_TXD ;
INC DPTR ;
DJNZ R7,DATE_LOOP ; 是否傳輸完畢
DATA_LIST: DB "2005 10 01" ; 2005-10-1
DB 0DH, ; 回車 0AH:新行
;**************************************************** 錯誤命令
RI_RET: ACALL UART_TXD ; 命令返回
MOV A,#0DH ;
ACALL UART_TXD ;
MOV DPTR,#BAD_LIST ;
MOV R7,#12 ; 計數器
BAD_LOOP: CLR A ;
MOVC A,@A+DPTR ;
ACALL UART_TXD ;
INC DPTR ;
DJNZ R7,BAD_LOOP ; 是否傳輸完畢
AJMP MAIN_LOOP ;
BAD_LIST: DB "bad command" ;
DB 0DH ; 回車 0AH:新行
;┌─────┬─────────────────-┐;
;│IROUT_OUT │紅外發射處理程序 │;
;└─────┴─────────────────-┘;
IROUT_OUT: CLR EA ; 禁止所有中斷
MOV g_SOFT_DOG,#0 ; 軟件看門狗延時 最大4*256=1024us
IROUT_HEAD1: JB RI,IROUT_HEAD2 ; 等待發送完畢 ,需要加限時服務 如果 1024us內沒有收到 放棄本次發送
NOP ; 增加計時時間
DJNZ g_SOFT_DOG,IROUT_HEAD1 ; 防止串口出錯一直在這里等待
AJMP IROUT_RET ; 時間溢出 返回
IROUT_HEAD2: CLR RI ;
MOV A,SBUF ;
MOV g_IR_HEAD1,A ; 傳送數據
MOV g_SOFT_DOG,#0 ; 軟件看門狗延時 最大4*256=1024us
IROUT_HEAD3: JB RI,IROUT_HEAD4 ; 等待發送完畢 ,需要加限時服務 如果 1024us內沒有收到 放棄本次發送
NOP ;
DJNZ g_SOFT_DOG,IROUT_HEAD3 ; 防止串口出錯一直在這里等待
AJMP IROUT_RET ; 時間溢出 返回
IROUT_HEAD4: CLR RI ;
MOV A,SBUF ;
MOV g_IR_HEAD2,A ; 傳送數據
MOV g_SOFT_DOG,#0 ; 軟件看門狗延時 最大4*256=1024us
IROUT_HEAD5: JB RI,IROUT_HEAD6 ; 等待發送完畢 ,需要加限時服務 如果 1024us內沒有收到 放棄本次發送
NOP ;
DJNZ g_SOFT_DOG,IROUT_HEAD5 ; 防止串口出錯一直在這里等待
AJMP IROUT_RET ; 時間溢出 返回
IROUT_HEAD6: CLR RI ;
MOV A,SBUF ;
MOV g_IR_HEAD3,A ; 傳送數據
ACALL IROUT_DATA ;
ACALL LED_WINK ;
IROUT_RET: CLR TF1 ; 清除定時器1
CLR IE0 ; 清除紅外中斷
SETB EA ; 開中斷
RET ;
;****************************************************
LED_WINK: MOV g_SOFT_DOG,#10 ;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -