📄 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 + -