C8051F040中CAN控制器的應(yīng)用
摘要:介紹C8051F040單片機(jī)內(nèi)部CAN控制器的應(yīng)用。詳細(xì)敘述此控制器的構(gòu)成及其訪問方式,指出在使用時(shí)是如何配置控制器的相關(guān)控制寄存器,并且給出CAN控制器在應(yīng)用中的物理層硬件電路和應(yīng)用層軟件設(shè)計(jì)。
關(guān)鍵詞:CAN控制器 寄存器 報(bào)文對(duì)象 C8051F040
單片機(jī)與CAN總線連接的傳統(tǒng)方式是將CPU與總線控制器和總線收發(fā)器相連后再接入總線網(wǎng)絡(luò),這樣使CPU外圍電路復(fù)雜化,整個(gè)系統(tǒng)受外部影響較大。為了解決這一問題,很多單片機(jī)廠商紛紛將CAN控制器集成在單片機(jī)芯片上。目前,單片機(jī)內(nèi)部集成的CAN控制器有Motorola公司的MC68HC912DG128A、Philips公司的P87C591、Atmel公司的AT89C51CC01和AT89C51CC02、Intel公司的TN87C196CA和TN87C196CB以及Cygnal公司的C8051F040等。
不同單片機(jī)內(nèi)部CAN控制器的使用方法有所不同,但存在著很多相似之處。這里以C8051F040為列詳細(xì)介紹其內(nèi)部CAN控制器的使用方法,希望通過這篇文章能給初學(xué)帶來方便,并能和廣大的單片機(jī)愛好者就這一問題做進(jìn)一步的討論。
1 C8051F040 CAN控制器構(gòu)成及訪問方式
C8051F040單片機(jī)是美國Cygnal公司生產(chǎn)的完全集成的混合信號(hào)系統(tǒng)級(jí)芯SoC(System on Chip),具有與8051指令集完全兼容的CIP-51內(nèi)核。它在一塊芯片上集成了構(gòu)成一個(gè)單片機(jī)數(shù)據(jù)采樣或控制系統(tǒng)所需要的幾乎所有模擬和數(shù)字外設(shè)及其它功能部件。它具有64KB Flash、4352B RAM、CAN控制器2.0、2個(gè)串行接口、5個(gè)16位定時(shí)器、12位A/D轉(zhuǎn)換器、8位A/D轉(zhuǎn)換器及12位D/A轉(zhuǎn)換器等,它內(nèi)部還帶有JTAG接口,使調(diào)試變得非常方便。
C8051F040內(nèi)部集成的CAN控制器為Bosch CAN控制器。此CAN控制器有以下幾部分構(gòu)成:CAN內(nèi)核、報(bào)文RAM(與C8051 RAM相互獨(dú)立)、報(bào)文處理狀態(tài)機(jī)制和CAN控制寄存器。其結(jié)構(gòu)框圖如圖1所示。
在CAN控制器里只有三個(gè)寄存器可通過CIP-51中的特殊功能寄存器直接訪問,其它的寄存器只能通過CAN0ADR、CAN0DATH和CAN0DATL寄存器以地址索引的方式間接訪問。在使用CAN控制器時(shí),重點(diǎn)和難點(diǎn)是對(duì)CAN控制器的寄存器的使用,其內(nèi)部寄存器的分類及其主要功能如下:
(1)CAN控制器協(xié)議寄存器
該協(xié)議寄存器是用來配置CAN控制器,處理各種中斷,監(jiān)控總線狀態(tài)以及置控制器為測試模式。CAN控制器協(xié)議寄存器可使用C8051 MCU特殊功能寄存器通過索引方式間接訪問,其中有些還可以很方便的通過C8051內(nèi)部特殊功能寄存器直接尋址來訪問。這部分的寄存器有:CAN控制寄存器(CAN0CN)、CAN狀態(tài)寄存器(CAN0STA)、CAN測試寄存器(CANTST)、錯(cuò)誤計(jì)數(shù)寄存器、位定時(shí)寄存器和波特率預(yù)比列因子擴(kuò)展寄存器。其中,CAN0CN、CAN0STA和CANTST可通過C8051 MCU特殊功能寄存器直接訪問,其它的只能通過間接訪問。
(2)報(bào)文對(duì)象接口寄存器
CAN控制器中有兩組報(bào)文對(duì)象接口寄存器,它們用來配置報(bào)文RAM中32個(gè)報(bào)文對(duì)象是用來向CAN總線發(fā)送數(shù)據(jù),還是從CAN總線接收數(shù)據(jù)。當(dāng)其中的一組被設(shè)置為向報(bào)文RAM中寫數(shù)據(jù),另一組則從報(bào)文RAM中讀取數(shù)據(jù)。利用此接口寄存器可以避免CPU訪問報(bào)文RAM與CAN報(bào)文接收和發(fā)送緩沖轉(zhuǎn)移之間的沖突。所有的報(bào)文對(duì)象都存儲(chǔ)在報(bào)文RAM里面,通過報(bào)文對(duì)象寄存器對(duì)其進(jìn)行訪問和配置,這些寄存器要通過C8051的CAN0ADR和CAN0DAT寄存器,使用間接索引地址方式來訪問。這部分寄存器有:IFX命令請(qǐng)求寄存器、IFX命令屏蔽寄存器、IFX屏蔽寄存器1、IFX屏蔽寄存器2、IFX仲裁寄存器1、IFX仲裁寄存器2、IFX報(bào)文控制寄存器、IFX數(shù)據(jù)寄存器A1、IFX數(shù)據(jù)寄存器A2、IFX數(shù)據(jù)寄存器B1和IFX數(shù)據(jù)寄存器B2。
(3)報(bào)文處理寄存器
所有的報(bào)文處理寄存器都是只讀寄存器。通過讀取它們的值可以實(shí)時(shí)地判斷相應(yīng)報(bào)文對(duì)象的狀態(tài),從而使CAN控制器能正確運(yùn)行。它們的標(biāo)識(shí)位由CAN0ADR、CAN0DATH和CAN0DATL通過索引方式間接來訪問。報(bào)文處理寄存器提供中斷、錯(cuò)誤、發(fā)送/接收請(qǐng)求和新數(shù)據(jù)信息。這部分的寄存器包括:中斷寄存器、發(fā)送請(qǐng)求寄存器、新數(shù)據(jù)寄存器、中斷隊(duì)列寄存器和報(bào)文有效寄存器。
那么,通過CAN0ADR、CAN0DATH和CAN0DATL寄存器以索引方式間接訪問CAN控制器中寄存器的過程會(huì)怎樣呢?因?yàn)槊總€(gè)CAN控制器寄存器都有一個(gè)索引號(hào),如果要訪問某一CAN控制寄存器,只需將此寄存器的索引號(hào)寫入CAN0ADR寄存器,而數(shù)據(jù)讀/寫操作通過CAN0DATH和CAN0DATL來完成。例如:如果需要對(duì)位定時(shí)寄存器重新配置時(shí),只需向CAN0ADR寄存器中寫入0X03,將新配置的數(shù)據(jù)的低字節(jié)寫入CAN0DATL中,高字節(jié)寫入CAN0DATH中。
2 CAN控制器應(yīng)用時(shí)寄存器配置
下面就CAN控制器在應(yīng)用時(shí),根據(jù)所要完成功能的不同而需要做的不同配置做具體描述。這包括報(bào)文對(duì)象初始化處理、發(fā)送對(duì)象配置、接收對(duì)象配置、中斷處理配置;另外,還有發(fā)送對(duì)象的更新、位定時(shí)寄存器等配置。
2.1 報(bào)文對(duì)象初始化處理
報(bào)文RAM中的報(bào)文對(duì)象(除MsgVal、NewDat、IntPnd和TxRqst)配置不受芯片復(fù)位的影響。所有的報(bào)文對(duì)象在使用前必須由CPU來初始化為零或者被設(shè)置為無效。報(bào)文對(duì)象的配置是通過相應(yīng)的接口寄存器來設(shè)置其屏蔽碼、仲裁場、控制場和數(shù)據(jù)場值,而這一設(shè)置過程由相應(yīng)的IFX命令請(qǐng)求寄存器來完成。
當(dāng)CAN控制寄存器中的Init位置零,CAN內(nèi)核中的CAN協(xié)議控制器狀態(tài)機(jī)制和報(bào)文處理狀態(tài)機(jī)制將控制C_CAN的內(nèi)部數(shù)據(jù)流。接收到的報(bào)文通過接收濾波后都存放在報(bào)文RAM中,而得到傳輸請(qǐng)求的報(bào)文都要移入CAN內(nèi)核的移位寄存器中并通過CAN總線傳出。
2.2 發(fā)送對(duì)象的配置
當(dāng)報(bào)文對(duì)象作為發(fā)送對(duì)象時(shí),仲裁寄存器(ID28-0和Xtd位)將被應(yīng)用,它們定義了即將發(fā)送的報(bào)文識(shí)別符和類型,如果使用11位識(shí)別符(標(biāo)準(zhǔn)幀),那么使用的是ID28~I(xiàn)D18,而ID17~I(xiàn)D0將被忽視。如果TxIE位被置位,則IntPnd位在此報(bào)文對(duì)象被成功發(fā)送后被置位;如果RmtEn位被置位,在接收到匹配的遠(yuǎn)程幀將引起TxRqst位被置位。若數(shù)據(jù)寄存器(DLC3-0,Data0-7)將被使用,TxRqst和RmtEn在數(shù)據(jù)有效前不會(huì)被置位。屏蔽寄存器(Msk28-0、Umask、Mxtd和MDir位)可以用來(UMask=‘1’)允許相同識(shí)別符的數(shù)據(jù)幀組被接收。
2.4 中斷處理
在所有中斷中,狀態(tài)中斷具有最高優(yōu)先級(jí),報(bào)文對(duì)象的中斷優(yōu)先級(jí)隨著報(bào)文編號(hào)的增大而減小。如果有幾個(gè)中斷產(chǎn)生,那么CAN中斷寄存器將指向優(yōu)先級(jí)最高的中斷,而不是按中斷先后順序排列。
狀態(tài)中斷通過讀取狀態(tài)寄存器來清除,報(bào)文中斷通過清除報(bào)文對(duì)象的IntPnd位來清除。處于中斷寄存器中的中斷識(shí)別符Intld能表明中斷的原因,如果這個(gè)寄存器的值為0,沒有中斷產(chǎn)生;否則,有中斷發(fā)生。
CPU控制著狀態(tài)寄存器的改變是否可以引起中斷(CAN控制寄存器中的EIE和SIE位);當(dāng)中斷寄存器的值不為0(CAN控制寄存器中的IE位)時(shí)中斷隊(duì)列是否有效。CPU有兩種方式判斷報(bào)文中斷源,每一種是判斷中斷寄存器中的Intld位;另一種是順序掃描中斷發(fā)生寄存器。
圖2
3 CAN控制器的應(yīng)用
CAN總線一般用在工業(yè)檢測和控制現(xiàn)場,它將各功能模塊連接在一起組成一個(gè)現(xiàn)場級(jí)通信網(wǎng)絡(luò)。在本應(yīng)用中,CAN總線完成下位機(jī)各部分之間的通信以及各下位機(jī)與上位機(jī)之間的通信。下位機(jī)以單片機(jī)C8051F040為核心,上位機(jī)由PC機(jī)構(gòu)成。下位機(jī)的CAN通信物理層的電路在下面將做詳細(xì)說明,為了完成上位機(jī)與下位機(jī)的通信,需要外加一塊PC-CAN通信卡。
3.1 CAN控制器外圍硬件電路實(shí)現(xiàn)
由于Cygnal內(nèi)部的CAN控制器只是個(gè)協(xié)議控制器,不能提供物理層驅(qū)動(dòng),所以在使用時(shí)還需外加CAN總線收發(fā)器,常用的CAN總線收發(fā)器有Philips公司的PCA82C250收發(fā)器、高速TJA1050收發(fā)器等。這里使用的是PCA82C250收發(fā)器、高速TJA1050收發(fā)器等。這里使用的是PCA82C250收發(fā)器,它可提高總線的差動(dòng)發(fā)送和接收能力。它與ISO11898標(biāo)準(zhǔn)完全兼容,有三種不同的工作方式,即高速、斜率控制和待機(jī),可根據(jù)實(shí)際情況選擇。此通信物理層電路圖如圖2所示。
為了進(jìn)一步提高系統(tǒng)的抗干擾能力,在CAN控制器引腳CANTX、CANRX和收發(fā)器PCA82C250之間并不是直接相連,而是通過由高速光耦6N137構(gòu)成的隔離電路后再與PCA82C250相連,這樣就可以很好的實(shí)現(xiàn)總線上各節(jié)點(diǎn)的電氣隔離。這部分增加了節(jié)點(diǎn)的復(fù)雜性,但它卻提高了節(jié)點(diǎn)的穩(wěn)定性和安全性。
在PCA80C250與CAN總線接口部分也采用了一些安全和抗干擾措施。PCA82C250的CANH和CANL引腳各自通過一個(gè)5Ω的電阻與CAN總線相連,電阻可起到一定的限流作用,從而保護(hù)PCA82C250免受過流的沖擊。在CANH和CANL與地之間各自接一個(gè)30pF的小電容,可以起到濾除總線上的高頻干擾和防電磁輻射的能力。另外,在CANH和CANL之間并聯(lián)一個(gè)15V的瞬態(tài)電壓抑制二極管(TVS),可以保護(hù)PCA80C250在瞬間高電壓情況下而不受損壞。PCA82C250的RS腳上接有一個(gè)下拉電阻,電阻的大小可根據(jù)總線速率適當(dāng)?shù)恼{(diào)整,其值一般在16kΩ~140kΩ之間,圖2中選用47kΩ。
C8051F040供電電源為2.7V~3.6V,其所有I/O口允許5V(極限值為5.8V)輸入,但是I/O輸出電平為VDD。而PCA82C250為5V系統(tǒng),為了能夠驅(qū)動(dòng)其工作,在CANTX引腳上拉一上拉電阻,其值為4.7kΩ。
3.2 CAN通信軟件實(shí)現(xiàn)
此下位機(jī)CAN通信部分主要完成的任務(wù)是:將現(xiàn)場檢測到的數(shù)據(jù)傳送給上位機(jī)或其它的下位機(jī)節(jié)點(diǎn);同時(shí),上位機(jī)可以對(duì)下位機(jī)的相關(guān)參考進(jìn)行設(shè)置,即下位機(jī)還須接收一定量的數(shù)據(jù)。
由上可知,此節(jié)點(diǎn)的CAN通信主要包括系統(tǒng)初始化程序、發(fā)送程序、接收程序等。軟件部分設(shè)計(jì)的好壞將直接決定系統(tǒng)能否正常工作,對(duì)于初次接觸CAN總線系統(tǒng)的設(shè)計(jì)人員來說是一個(gè)難點(diǎn),也是一個(gè)重點(diǎn)。在本例中,系統(tǒng)軟件采用結(jié)構(gòu)化程序設(shè)計(jì)方案,使其具有較好的模塊性和可移植性,對(duì)于不同的系統(tǒng)功能或不同的應(yīng)用環(huán)境,可以方便地進(jìn)行編程重組。
3.2.1 系統(tǒng)初始化初始化
初始化程序主要完成對(duì)所有的報(bào)文對(duì)象進(jìn)行初始化(一般將所有值置零),對(duì)CAN控制寄存器(CAN0CN)、位定時(shí)寄存器(BITREG)進(jìn)行設(shè)置,還要對(duì)發(fā)送報(bào)文對(duì)象和接收?qǐng)?bào)文對(duì)象分別進(jìn)行初始化。其中,位定時(shí)寄存器的設(shè)置較為復(fù)雜,這里我們使用外部晶振為8MHz,CAN通信速率為500k/s,得到BITREG的初始值為0x2301。主程序中規(guī)定對(duì)象初始化、發(fā)送和接收初始化,最后才啟動(dòng)CAN處理機(jī)制(對(duì)BITREG和CAN0CN初始化),下面為CAN啟動(dòng)程序:
void start_CAN(void){
SFPRAGE=CAN0_PAGE;/*指向CAN0頁面*/
CAN0CN|=0x41; /*將CCE和Init置“1”開始初始化*/
CAN0ADR=BITREG;/*指向位定時(shí)寄存器進(jìn)行配置*/
CAN0DAT=0x2301; /*位率為500k/s*/
CAN0CN|=0x06;/*允許全局中斷,IE和SIE置位*/
CAN0CN &=~0x41; /*清楚CCE和INIT位,啟動(dòng)CAN狀態(tài)機(jī)制*/
}
3.2.2 發(fā)送程序
CAN報(bào)文發(fā)送是由CAN控制器自動(dòng)完成的,用戶只需根據(jù)接收到的遠(yuǎn)程幀的識(shí)別符,將對(duì)應(yīng)的數(shù)據(jù)轉(zhuǎn)移到發(fā)送緩沖寄存器,然后將此報(bào)文對(duì)象的編碼寫入命令請(qǐng)求寄存器啟動(dòng)發(fā)送即可,而發(fā)送由硬件來完成。這里,我們使用定時(shí)更新發(fā)送報(bào)文對(duì)象中的數(shù)據(jù),數(shù)據(jù)的發(fā)送有控制器自動(dòng)完成,當(dāng)其收到一個(gè)遠(yuǎn)程幀時(shí),就將具有相同識(shí)別符的數(shù)據(jù)幀發(fā)送出去。其發(fā)送程序結(jié)構(gòu)如下:
Void transmit_message(char MsgNum){
SFRPAGE=CAN0_PAGE;/*指向CAN0頁面*/
CAN0ADR=IF1CMDMSK;/*向IF1命令屏蔽寄存器寫入命令*/
CAN0DAT=0X0083;
CAN0ADR=IF1ARB2;/*指向IF1仲裁寄存器2*/
CAN0DATH|=0x80;
CAN0ADR=IF1DATA1;/*指向數(shù)據(jù)場的第一個(gè)字節(jié)*/
for(i=0;i<4;i++){
CAN0DAT=can_temp[i];/*將4字節(jié)數(shù)據(jù)寫入發(fā)送緩沖器*/
}
CAN0ADR=IF1CMDRQST;
CAN0DATL=MsgNum;/*將報(bào)文對(duì)象編號(hào)寫入,則數(shù)據(jù)發(fā)送到對(duì)應(yīng)的報(bào)文對(duì)象中*/
}
3.2.3 接收程序
CAN報(bào)文的接收與發(fā)送一樣,是由CAN控制器自動(dòng)完成的,接收程序只需從接收緩存器中讀取接收的數(shù)據(jù),再進(jìn)行相應(yīng)的處理即可。其基本方法與發(fā)送程序一致,只是接收程序采用中斷方式。在此應(yīng)用中,接收程序主要接收上位機(jī)對(duì)下位機(jī)的參數(shù)設(shè)置數(shù)據(jù),只有當(dāng)修改時(shí)才需要接收數(shù)據(jù),所以采用中斷方式處理比較合適。接收程序結(jié)構(gòu)如下:
void receive_data(void){
SFRPAGE=CAN0_PAGE;/*指向CAN0頁面*/
CAN0ADR=IF1CMDMSK;/*向IF1命令屏蔽寄存器寫入命令*/
CAN0DAT=0X0083;
CAN0ADR=IF1ARB2;/*指向IF1仲裁寄存器2*/
CAN0DATH|=0x80;
CAN0ADR=IF1DATA1;/*指向數(shù)據(jù)場的第一個(gè)字節(jié)*/
for(i=0;i<4;i++){
CAN0DAT=can_temp[i];/*將4字節(jié)數(shù)據(jù)寫入發(fā)送緩沖器*/
}
CAN0ADR=IF1CMDRQST;
CAN0DATL=MsgNum;/*將報(bào)文對(duì)象編號(hào)寫入,則數(shù)據(jù)發(fā)送到對(duì)應(yīng)的報(bào)文對(duì)象中*/
}
3.2.3 接收程序
CAN報(bào)文的接收與發(fā)送一樣,是由CAN控制器自動(dòng)完成的,接收程序只需從接收緩存器中讀取接收的數(shù)據(jù),再進(jìn)行相應(yīng)的處理即可。其基本方法與發(fā)送程序一致,只是接收程序采用中斷方式。在此應(yīng)用中,接收程序主要接收上位機(jī)對(duì)下位機(jī)的參數(shù)設(shè)置數(shù)據(jù),只有當(dāng)修改時(shí)才需要接收數(shù)據(jù),所以采用中斷方式處理比較合適。接收程序結(jié)構(gòu)如下:
Void receive_data(void){
SFPRAGE=CAN0_PAGE;/*指向CAN0頁面*/
CAN0ADR=IF2CMDMSK;/*向IF2命令屏蔽寄存器寫命令*/
CAN0DAT=0x003F;
CAN0ADR=IF2CMDRQST;/*將報(bào)文對(duì)象編號(hào)寫入命令請(qǐng)求寄存器,對(duì)應(yīng)地接收*/
CAN0DATL=MsgNum;/*得到數(shù)據(jù)就從報(bào)文RAM中移到數(shù)據(jù)緩沖器中*/
CAN0ADR=IF2DATA1;/*指向數(shù)據(jù)場的第一個(gè)字節(jié)*/
for(i=0;i<4;i++){ /*讀取4個(gè)字節(jié)數(shù)據(jù)*/
CAN_RX[i]=CAN0DAT;
}
結(jié)語
本文是筆者在實(shí)際應(yīng)用中得到的一點(diǎn)應(yīng)用經(jīng)驗(yàn),期望對(duì)使用C8051F040中CAN控制器以及研究CAN總線的同行提供一些借鑒和幫助。文中的CAN控制器物理層電路完全能夠使用,而且抗干擾能力較強(qiáng)。CAN總線以其穩(wěn)定的特性、低廉的價(jià)格將會(huì)被更多用戶所使用,而集成于微控制器內(nèi)部的CAN控制器更是在設(shè)計(jì)過程中的首選。
有關(guān)CAN通信部分源程序見網(wǎng)站www.dpj.com.cn。