?? adcon.asm
字號:
;ADuC812晶振為11.0592MHz
$MOD812 ; Use 8052&ADuC812 predefined symbols
;CAN控制器SJA1000的片選地址為08000H
CR EQU 8000H ;控制寄存器地址
CMR EQU 8001H ;命令寄存器地址
SR EQU 8002H ;狀態寄存器地址
IR EQU 8003H ;中斷寄存器地址
ACR EQU 8004H ;驗收代碼寄存器地址
AMR EQU 8005H ;驗收屏蔽寄存器地址
BTR0 EQU 8006H ;總線定時寄存器0
BTR1 EQU 8007H ;總線定時寄存器1
OCR EQU 8008H ;輸出控制寄存器
;************************************************************************
;*發送緩沖區(內部地址0AH--13H) *
;************************************************************************
TXB EQU 800AH ;發送緩沖區首址
;************************************************************************
;*接收緩沖區(內部地址014H--01DH) *
;************************************************************************
RXB EQU 8014H ;接收緩沖區首址
;************************************************************************
;*內部地址 01EH 備用 *
;************************************************************************
;************************************************************************
;*時鐘分頻寄存器(內部地址01FH) *
;************************************************************************
CDR EQU 801FH ;時鐘分頻寄存器
;************************************************************************
;*SJA1000的命令字 *
;************************************************************************
TR_CMD EQU 01h ;//發送請求命令
AT_CMD EQU 02h ;//夭折發送命令
RRB_CMD EQU 04h ;//釋放接收緩沖區
CDO_CMD EQU 08h ;//清除數據溢出
GTS_CMD EQU 010h ;//進入睡眠狀態命令
;************************************************************************
;*SJA1000操作的錯誤 *
;************************************************************************
SJA_INTFACE_ERR EQU 0FFH
SJA_INIT_ERR EQU 0FEH
SJA_RCV_ERR EQU 0FDH
SJA_SEND_ERR EQU 0FCH
SJA_INITOBJ_ERR EQU 0FBH
SJA_INITBTR_ERR EQU 0FAH
SJA_INITOCLK_ERR EQU 0F9H
CSEG
CHAN EQU 0 ; convert this ADC input channel..
; ..chan values can be 0 thru 8
CHANNUM EQU 8
IP1 EQU 192
IP2 EQU 168
IP3 EQU 1
IP4 EQU 47
;使用前變量定義
RCV_GOOD BIT 00H ;成功的接收一幀標志
SEC_FLAG BIT 01H ;一秒到標志
ERR_FLAG BIT 02H ;監測到錯誤標志
OVER_FLAG BIT 03H ;超載標志
DS_END_FLAG BIT 04H ;SJA1000發送完成標志
WUI_FLAG BIT 05H ;喚醒SJA1000標志
T0IR BIT 06H ;定時器T0標志
SEND_DLM BIT 07H ;發送次序標志(區分一輪采樣(16字節)的兩次發送)
SEC_COUNT_L EQU 30H ;秒定時計數器
SEC_COUNT_H EQU 31H
SAVE_INT_INFO EQU 32H ;保存SJA1000中斷寄存器的內容
ERRORCOUNT EQU 33H ;錯誤計數
DISPLAYBUF0 EQU 34H ;顯示緩沖區34H--38H
ERROR_STATUS DATA 7CH ;錯誤狀態表示
TEST_DATA DATA 7FH ;測試發送數據
SEND_DATA_BUF EQU 40H ;CPU發送緩沖區首址
REC_DATA_BUF EQU 50H ;CPU接收緩沖區首址
COUNTER_L DATA 80H ;采樣次數高位字節
COUNTER_H DATA 08H ;采樣次數低位字節
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ORG 0000H
LJMP MAIN
;T0中斷入口
ORG 000BH
LJMP LOOP1
;主程序開始
ORG 004BH
MAIN: MOV SP,#7FH
MOV R0,#7FH
CLR A ;清零片內RAM
CLRIR: MOV @R0,A
DJNZ R0,CLRIR
;MOV P2,#0FFH
LCALL SJA1000_INIT ;SJA1000初始化
;SETB EA ;開中斷
;主程序監控流程
MLOOP: LCALL CANREC
MOV R0,#REC_DATA_BUF+2
MOV A,@R0
CJNE A,#03H,MLOOP ;不是測試A/D采樣命令,則一直查詢直到接收到測試A/D采樣命令
LCALL ADCONV
LCALL SENDDATA_PRG
LCALL SENDDATA_PRG
LOOP: LCALL CANREC
MOV R0,#REC_DATA_BUF+2
MOV A,@R0
CJNE A,#01H,LOOP
MOV R3,COUNTER_H
LOOP1: MOV R6,COUNTER_L
LOOP2: ;MOV TMOD,#01H ;A/D采樣命令,同時設置T0為方式1開始定時
;MOV TL0,#33H ;設置定時初值,定時3mS
;MOV TH0,#0F5H
;SETB ET0 ;允許T0中斷
;SETB TR0 ;啟動T0定時
LCALL ADCONV ;開始一輪采樣
LCALL SENDDATA_PRG ;采完一輪后發送(CPU數據區的前4個通道的轉換結果)
LCALL SENDDATA_PRG ;繼續發送后4個通道的轉換結果
AJMP $
DJNZ R6,LOOP2
DJNZ R3,LOOP1
CLR ET0 ;關閉T0中斷
;SJMP MLOOP
;LCALL DELAY
LCALL FINISH
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ADCONV: PUSH 3 ;將R3壓入堆棧
MOV R2, #CHANNUM ;設置A/D采樣的通道數(8通道)
MOV R3, #CHAN ;設置A/D采樣的初始通道號
MOV R0, #SEND_DATA_BUF ;設置發送緩沖區首址,A/D轉換結果存放地址
MOV ADCCON1,#060H ;設置A/D轉換于正常工作狀態
AGAIN:
MOV ADCCON2,R3 ;本次A/D轉換的通道號
SETB SCONV ;啟動單步A/D轉換
JB SCONV,$
MOV A, ADCDATAH
MOV @R0, A ;將轉換數據放入發送緩沖區
INC R0
MOV A, ADCDATAL
MOV @R0, A
INC R0
INC R3
DJNZ R2,AGAIN ;通道沒采完,則繼續下一個通道
POP 3 ;將R3彈出堆棧
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SENDDATA_PRG: PUSH 6 ;將R6壓入堆棧
MOV DPTR, #SR ;狀態寄存器
MOVX A, @DPTR ;從SJA1000讀入狀態寄存器值
JB ACC.4,SENDDATA_PRG ;判斷是否正在接受,正在接受則等待
TS0: MOVX A,@DPTR
JNB ACC.3, TS0 ;判斷上次發送是否完成,
;未完成則等待發送完成
TS1: MOVX A, @DPTR
JNB ACC.2, TS1 ;判斷發送緩沖器是否鎖定,鎖定則等待
TS2: CLR EA ;發送過程中關中斷,以免干擾發送
MOV DPTR, #TXB ;SJA1000發送緩沖器首址
MOV A, #01H ;設置識別碼為01H(即為1號節點)
MOVX @DPTR, A
INC DPTR
MOV A, #08H ;數據場長度為8個字節
MOVX @DPTR, A
MOV R6, A
JB SEND_DLM, SEND_SEQ2
SEND_SEQ1: MOV R0, #SEND_DATA_BUF ;單片機片內RAM發送數據區地址,
;數據內容為A/D采樣值
SJMP MTBF1
SEND_SEQ2:
MOV R0, #SEND_DATA_BUF+8
SJMP MTBF2
MTBF1: MOV A, @R0
INC DPTR
MOVX @DPTR, A
INC R0
DJNZ R6, MTBF1 ;向發送緩沖器寫8個字節
SETB SEND_DLM
SJMP SEND_END
MTBF2: MOV A, @R0
INC DPTR
MOVX @DPTR, A
INC R0
DJNZ R6, MTBF2 ;向發送緩沖器寫8個字節
CLR SEND_DLM
SEND_END: MOV DPTR, #CMR ;命令寄存器地址
MOV A, #01H
MOVX @DPTR, A ;啟動SJA1000發送
SENDLOOP1: MOV DPTR, #SR ;讀取狀態寄存器
MOVX A, @DPTR ;判斷上次發送是否完成
JB ACC.5, SENDLOOP1 ;若正在發送,則取消上次未完成的發送
JNB ACC.3, SENDLOOP1
;CLR P3.4
;LCALL DELAY1
;LCALL DELAY1
;SETB P3.4
POP 6 ;將R6彈出堆棧
SETB EA
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CANREC: CLR EA ;關閉所有中斷,以免影響接受
MOV DPTR, #SR ;狀態寄存器地址
MOVX A, @DPTR
ANL A, #0C3H ;讀取總線關閉、錯誤狀態、接收溢出、有數據等位狀態
JNZ PROC ;有上述狀態,進入處理
RET
PROC:
;JNB ACC.7, PROCI
;BUSERR: MOV DPTR,#IR ;中斷寄存器;出現總線關閉
; MOVX A,@DPTR ;讀取中斷寄存器,清除中斷位(CPU的任何讀操作
; ;都會將中斷寄存器的相應中斷位清除)
; MOV DPTR,#CR
; MOV A,#01H
; MOVX @DPTR,A ;將控制寄存器復位請求位清零
; RET
; NOP
;PROCI: MOV DPTR,#IR ;總線正常
; MOVX A,@DPTR ;讀取中斷寄存器,清除中斷位
; JNB ACC.3, OTHER
;OVER: MOV DPTR,#CMR ;數據溢出
; MOV A,#0CH
; MOVX @DPTR,A ;在命令寄存器中清除數據溢出和釋放接收緩沖器
; RET
; NOP
;OTHER: JB ACC.0, RECE ;接收緩沖器有數據,轉入接收子程序
; LJMP RECOUT ;接收緩沖器無數據,退出接收
; NOP
RECE: MOV DPTR, #RXB ;讀取并保存接收緩沖器的數據
MOV R1,#REC_DATA_BUF ;CPU片內接收緩沖器首址
MOVX A,@DPTR
MOV @R1,A
INC DPTR
INC R1
MOVX A, @DPTR
MOV @R1,A
ANL A, #0FH ;截取低四位是數據長度
MOV R6, A
RDATA0: INC DPTR
INC R1
MOVX A,@DPTR
MOV @R1,A
DJNZ R6,RDATA0
MOV DPTR,#CMR
MOV A,#04H
MOVX @DPTR,A ;釋放CAN接收緩沖器
;CLR P3.4
;LCALL DELAY1
;LCALL DELAY1
;LCALL DELAY1
;LCALL DELAY1
;SETB P3.4
RECOUT: SETB EA ;開中斷
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;SJA1000初始化子程序
SJA1000_INIT:
MOV DPTR, #CR ;控制寄存器訪問
MOV A,01H ;置位復位請求,對SJA1000進行初始化
MOVX @DPTR,A
MOVX @DPTR, A
MOV DPTR, #CDR ;設置時鐘分頻寄存器CDR
MOV A, #046H
MOVX @DPTR, A
MOV DPTR, #ACR ;設置驗收代碼寄存器ACR,低半字節為節點號,暫定為0號
MOV A, #00H
MOVX @DPTR, A
INC DPTR ;設置接收屏蔽寄存器AMR
MOV A, #0FCH
MOVX @DPTR, A
MOV DPTR, #BTR0 ;分別設置寄存器BTR0和BTR1
MOV A, #05H ;將波特率定為500kbps
MOVX @DPTR, A
INC DPTR
MOV A, #0A3H
MOVX @DPTR, A
MOV DPTR, #OCR ;設置輸出寄存器OCR
MOV A, #0FAH
MOVX @DPTR, A
MOV DPTR, #CR ;控制寄存器訪問
MOVX A, @DPTR
MOV A, #1AH ;清零復位請求,返回工作狀態,同時開接收中斷、溢出中斷和錯誤告警中斷
MOVX @DPTR, A
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;延時子程序
DELAY: PUSH 6
MOV R7, #10 ;10*500uS=5mS
DLY1: MOV R6, #229 ;229*2.17uS=500uS
DJNZ R6, $
DJNZ R7, DLY1
POP 6
RET
DELAY1: PUSH 6 ;眼時10×5mS=50mS(用于指示發送狀態燈)
MOV R6,#10
DLY2: LCALL DELAY
DJNZ R6,DLY2
POP 6
RET
FINISH: NOP
END
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -