SJA1000的主要新功能如下:
*標準結構和擴展結構報文的接收和發(fā)送;
*64字節(jié)的接收FIFO;
*標準和擴展幀格式都具有單/雙接收濾波器(含接收屏蔽和接收碼寄存器);
*可進行讀/寫訪問的錯誤計數(shù)器;
*可編程的錯誤報警限制;
*最近一次的錯誤代碼寄存器;
*每一個CAN總線錯誤都可以產(chǎn)生錯誤中斷;
*具有丟失仲裁定位功能的丟失仲裁中斷;
*單發(fā)方式(當發(fā)生錯誤或丟失仲裁時不重發(fā));
*只聽方式(監(jiān)聽CAN總線,無應答,無錯誤標志);
*支持熱插拔(無干擾軟件驅動位速率檢測);
*硬件禁止CLKOUT輸出。
二、智能節(jié)點硬件電路設計
本文中所設計的CAN總線系統(tǒng)智能節(jié)點,采用89C51作為節(jié)點的微處理器。在CAN總線通信接口中,采用PHILIPS公司的SJA1000和82C250芯片。SJA1000是獨立CAN通信控制器,82C250為高性能CAN總線收發(fā)器。
圖1所示為CAN總線系統(tǒng)智能節(jié)點硬件電路原理圖。從圖1中可以看出,電路主要由四部分構成:微控制器89C51、獨立CAN通信控制器SJA1000、CAN總線收發(fā)器82C250和高速光電耦合器6N137。微處理器89C51負責SJA1000的初始化,通過控制SJA1000實現(xiàn)數(shù)據(jù)的接收和發(fā)送等通信任務。

SJA1000的AD0~AD7連接到89C51的P0口。CS連接到89C51的P2.0,P2.0為0的CPU片外存儲器地址可選中SJA1000,CPU通過這些地址可對SJA1000執(zhí)行相應的讀寫操作。SJA1000的RD、WR、ALE分別與89C51的對應引腳相連,INT接89C51的INT0。89C51也可通過中斷方式訪問SJA1000。
為了增強CAN總線節(jié)點的抗干擾能力,SJA1000的TX0和RX0并不是直接與82C250的TXD和RXD相連,而是通過高速光耦6N137后與82C250相連,這樣就很好地實現(xiàn)了總線上各CAN節(jié)點間的電氣隔離。不過,應該特別說明的一點是光耦部分電路所采用的兩個電源VCC和VDD必須完全隔離,否則采用光耦也就失去了意義。電源的完全隔離可采用小功率電源隔離模塊或帶多5V隔離輸出的開關電源模塊實現(xiàn)。這些部分雖然增益了節(jié)點的復雜程序,但是卻提高了節(jié)點的穩(wěn)定性和安全性。
82C250與CAN總線的接口部分也采用了一定的安全和抗干擾措施。82CF250的CANH和CAHL引腳各自通過1個5Ω的電阻與CAN總線相連。電阻可起到一定的限流作用,保護82C250免受過流的沖擊。CANH和CANL與地之間并聯(lián)了2個30pF的小電容,可以起到濾除總線上的高頻干擾和一定的防電磁輻射的能力。另外,在兩根CAN總線接入端與地之間分別反接了1個保護二極管,當CAN總線有較高的負電壓時,通過二極管的短路可起到一定的過壓保護作用。82C250的Rs腳上接有一個斜率電阻,電阻大小可根據(jù)總線通信速度適當高調整,一般在16~140kΩ之間。
三、智能節(jié)點軟件設計
CAN總線節(jié)點的軟件設計主要包括三大部分;CAN節(jié)點初始化、報文發(fā)送和報文接收。熟悉這三部分程序的設計,就能編寫出利用CAN總線進行通信的一般應用程序。當然要將CAN總線應用于通信任務比較復雜的系統(tǒng)中,還需詳細了解有關CAN總線錯誤處理、總線脫離處理、接收濾波處理、波特率參數(shù)設置和自動檢測以及CAN總線通信距離和節(jié)點數(shù)的計算等方面的內(nèi)容。下面僅就前面提出的三部分程序的設計作一個描述,以供大家在實際應用中參考。
1.初始化子程序
SJA1000的初始化只有在復位模式下才可以進行。初始化主要包括工作方式的設置、接收濾波方式的設置、接收屏蔽寄存器(AMR)和接收代碼寄存器(ACR)的設置、波特率參數(shù)設置和中斷允許寄存器(IER)的設置等。在完成SJA1000的初始化設置以后,SJA1000就可以回到工作狀態(tài),進行正常的通信任務。下面提供了SJA1000初始化的51匯編源程序。程序中寄存器符號表示的是SJA1000相應寄存器占用的片外存儲器地址,這些符號可在程序的頭部用偽指令EQU進行定義。后文對這一點不再作特別說明。
CANINI:
MOV DPTR,#MODE ;方式寄存器
MOV A,#09H ;進放復位模式,對
;SJA1000進行初始化
MOVX @DPTR,A
MOV DPTR,#CDR ;時鐘分頻寄存器
MOV A,#88H ;選擇PeliCAN模式,
;關準備時鐘輸出(CLKOUT)
MOVX @DPTR,A
MOV DPTR,#IER ;中斷允許寄存器
MOV A,#0DH ;開發(fā)發(fā)送中斷、超
;載中斷和錯誤警告中斷
MOVX @DPTR,A
MOV DPTR,#AMR ;接收屏蔽寄存器
MOV R6,#4
MOV R0,#DAM ;接收屏蔽寄存器內(nèi)容
;在片內(nèi)RAM中的首址
AMR:MOV A,@R0
MOVX @DPTR,A ;接收屏蔽寄存器賦初值
INC DPTR
DJNZ R6,AMR
MOV DPTR,#ACR ;接收代碼寄存器
MOV R6,#4
MOV R0,#DACR ;收收代碼寄存器內(nèi)容
;在片內(nèi)RAM中的首址
ACR:MOV A,@R0
MOVX @DPTR,A 接收代碼寄存器賦初值
INC DPTR
DJNZ R6,ACR
MOV DPTR,#BTR0 ;總線定時寄存器0
MOV A,#03H
MOVX @DPTR,A
MOV DPTR,#BTR1 ;總線定時寄存器1
MOV A,#0FFH ;16MHz晶振情況下,
;設置波特率為80kbps
MOVX @DPTR,A
MOV DPTR,#OCR ;輸出控制寄存器
MOV A,#0AAH
MOVX @DPTR,A
MOV DPTR,#RBSA ;接收緩存器起始
;地址寄存器
MOV A,#0 ;設置接收緩存器
;FIFO起始地址為0
MOVX @DPTR, A
MOV DPTR,#TXERR ;發(fā)送錯誤計數(shù)寄存器
MOV A,#0 ;清除發(fā)送錯誤計數(shù)寄存器
MOVX @DPTR,A
MOV DPTR,#ECC ;錯誤代碼捕捉寄存器
MOVX A,@DPTR ;清除錯誤代碼捕捉寄存器
MOV DPTR,#MODE ;方式寄存器
MOV A,#08H ;設置單濾波接收方式
;并返回工作狀態(tài)
MOVX @DPTR,A
RET
2.發(fā)送子程序
發(fā)送子程序負責節(jié)點報文的發(fā)送。發(fā)送時用戶只需將待發(fā)送的數(shù)據(jù)按特定格式組合成一幀報文,送入SJA1000發(fā)送緩存區(qū)中,然后啟動SJA1000發(fā)送即可。當然在往SJA1000發(fā)送緩存區(qū)送報文之前,必須先作一些判斷(如下文程序所示)。發(fā)送程序分發(fā)送遠程幀和數(shù)據(jù)幀兩種。遠程幀無數(shù)據(jù)場。下面以發(fā)送數(shù)據(jù)幀為例對發(fā)送子程序作一個說明。
TDATA:MOV DPTR,#SR ;狀態(tài)寄存器
MOVX A,@DPTR ;從SJA1000讀入
;狀態(tài)寄存器值
JB ACC.4,TDATA ;判斷是正在接收,
正在接收則等待
TS0:MOVX A,@DPTR
JNB ACC.3,TS0 ;判斷上次發(fā)送是否完成,未完成則等待發(fā)送完成
TS1:MOVX A,@DPTR
JNB ACC.2,TS1 :判斷發(fā)送緩沖區(qū)是否
;鎖定,鎖定則等待
TS2:MOV DPTR,#CANTXB ;SJA1000發(fā)送緩
;存區(qū)首址
MOV A,#88H ;發(fā)送數(shù)據(jù)長度為8個
;字節(jié)的擴展幀格式報文
MOVX @DPTR,A
INC DPTR
MOV A,#ID0;4個字節(jié)的標識符(ID0~ID3),
;依據(jù)實際情況賦值
MOVX @DPTR,A
INC DPTR
MOV A,#ID1
MOVX @DPTR,A
INC DPTR
MOV A,#ID2
MOVX @DPTR,A
INC DPTR
MOV A,#ID3
MOVX @DPTR,A
MOV R0,#TRDATA;CPU發(fā)送數(shù)據(jù)區(qū)首
;址,數(shù)據(jù)內(nèi)容由用戶定義
MTBF:MOV A,@R0
INC DPTR
MOVX @DPTR,A
INC R0
CJNE R0,#TRDATA+8,MTBF;向發(fā)送緩
;沖區(qū)寫8個字節(jié)
MOV DPTR,#CMR ;命令寄存器地址
MOV A,#01H
MOVX @DPTR,A ;啟動SJA1000發(fā)送
RET
3.查詢方式接收子程序
接收子程序負責節(jié)點報文的接收以及其它情況處理。接收子程序比發(fā)送子程序要復雜一些,因為在處理接收報文的過程中,同時要時諸如總線脫離、錯誤報警、接收溢出等情況進行處理。SJA1000報文的接收主要有兩種方式:中斷接收方式和查詢接收方式。如果對通信的實時性要求不是很強,建議采用查詢接收方式。兩種接收方式編程的思路基本相同。下面僅以查詢方式接收報文為例對接收子程序作一個說明。
SEARCH:
MOV DPTR,#SR ;狀態(tài)寄存器地址
MOVX A,@DPTR
ANL A,#0C3H ;讀取總線脫離、錯誤狀
;態(tài)、接收溢出、有數(shù)據(jù)等位
JNZ PROC
RET ;無上述狀態(tài),結束
PROC:JNB ACC.7, PROCI
BUSERR:
MOV DPTR,#IR :IR中斷寄存器,
;出現(xiàn)總線脫離
MOVX A,@DPTR ;讀中斷寄存器,
;清除中斷位
MOV DPTR,#MODE ;方式寄存器地址
MOV A,#08H ;
MOVX @DPTR,A ;將方式寄存器復位,
;清求位清0
LCALL ALARM. ;調用報警子程序
RET
NOP
PROC1:MOV DPTR,#IR ;總線正常
MOVX A,@DPTR ;讀取中斷位
JNB ACC.3,OTHER
OVER: MOV DPTR,#CMR ;數(shù)據(jù)溢出中斷置位
MOV A,#0CH
MOVX @DPTR,A;在命令寄存器中精除數(shù)
;據(jù)溢出和釋放接收緩沖區(qū)
RET
NOP
OTHER:JB ACC.0,RECE;IR.0=1,接收FIFO
;示滿或接收中斷使能
LJMP RECOUT ;IR.0=0,接收緩沖區(qū)
;無數(shù)據(jù),退出接收
NOP
RECE:MOV DPTR,#CANRXB;接收緩沖區(qū)首地
;地(16),準備讀取數(shù)據(jù)
MOVX A,@DPTR ;首字節(jié)是接收幀格式字
JNB ACC.6,RDATA ;RTR=1是遠程
;請求幀,無數(shù)據(jù)
MOV DPTR,#CMR ;
MOV A,#04H ;CMR.2=1釋放接收緩沖區(qū)
MOVX @DPTR,A ;只有接收了數(shù)據(jù)才能
;釋放接收緩沖區(qū)
LCALL TDATA ;發(fā)送對方請求的數(shù)據(jù)
LJMP RECOUT ;退出接收
NOP
RDATA:MOV DPTR,#CANRXB; 讀取并保存接收
;緩沖區(qū)的數(shù)據(jù)
MOV R1,#CPURBF ;CPU片內(nèi)接收
;緩沖區(qū)首址
MOVX A,@DPTR ;讀取CAN緩沖區(qū)
;的2個字節(jié)
MOV @R1,A ;保存
ANL A,#0FH ;截取低4位是;
數(shù)據(jù)長度(0~8)
ADD A,#4 ;加4個字節(jié)的標識符(ID)
MOV R6,A
RDATA:INC DPTR
INC R1
MOVX A,@DPTR
MOV @R1,A
DJNZ R6,RDATA0 循環(huán)讀取與保存
MOV DPTR,#CMR
MOV A,#04H ;釋放CAN接收緩沖區(qū)
MOVX @DPTR,A
RECOUT:MOV DPTR,#ALC ;釋放仲裁丟失捕捉
;寄存器和錯誤捕捉寄存器
MOVX A,@DPTR
MOV DPTR,#ECC
MOVX A,@DPTR
NOP
RET
結束語
上述介紹的是SJA1000工作在Peli CAN模式下的三種最基本的操作子程序。由于篇幅的關系,這里沒有列出和解決SJA1000內(nèi)部寄存器的地址和位定義。有關接收屏蔽寄存器(AMR)和接收編碼寄存器(ACR)的使用在以往的文章中已有介紹。至于其它一些寄存器或位功能的使用,沒有在上述例程中體現(xiàn)出來,需要視實際情況而定。





