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