最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊

STM32 CAN通信詳解

2023-03-09 17:07 作者:月影sh0  | 我要投稿

?首先是自己項(xiàng)目工程中自己的東西分享給大家,后面CAN詳解內(nèi)容是轉(zhuǎn)載他人的優(yōu)秀文檔。

?????? 由于STM32F4中我使用的擴(kuò)展標(biāo)識符(ID)是29位(28~0),STM32的過濾器和掩碼是32位分別映射到{10~0、28~0、IDE、RTR、0}上;那么我們就可以根據(jù)這些內(nèi)容建立自己的過濾和掩碼。其中不建議使用CAN接收中斷中的EXtID進(jìn)行多個(gè)節(jié)點(diǎn)ID區(qū)分,因?yàn)檠诖a中為零的是不定的也即不判斷,X可能是0或1。比如下圖中1,ID 、掩碼、映射,之間的關(guān)系。

我們代碼初始化中有提示比如標(biāo)識符ID,ExtId范圍0~0x1FFFFFFF。CAN_FilterIdLow低三位其實(shí)是IDE、RTR、0;過濾ID不要用最低三位。

?如下圖展示的是不用最低3位的CAN_init函數(shù)


另外一種方法是規(guī)定好本機(jī)地址以及目標(biāo)發(fā)送地址,比如我們程序中使用29位擴(kuò)展標(biāo)識符

uint32_t?StdId;?/*存儲(chǔ)報(bào)文的標(biāo)準(zhǔn)標(biāo)識符11位,0-0x7FF. */

uint32_t?ExtId;?/*存儲(chǔ)報(bào)文的擴(kuò)展標(biāo)識符29位,0-0x1FFFFFFF. */

29位ExtId中,28-21位目標(biāo)地址 7-14位本機(jī)地址,那么在CAN發(fā)送中,ExtId表示為


?目標(biāo)地址左移21位,本機(jī)地址左移7位,組成ExtId。另外在過濾中,過濾28-21位,因?yàn)檫@個(gè)是其他設(shè)備發(fā)送過來的,這個(gè)時(shí)候其他設(shè)備28-21位對應(yīng)的本機(jī)地址。如圖



本章參考資料:《STM32F4xx?中文參考手冊2》、《STM32F4xx規(guī)格書》、庫幫助文檔《stm32f4xx_dsp_stdperiph_lib_um.chm》。

若對CAN通訊協(xié)議不了解,可先閱讀《CAN總線入門》、《CAN-bus規(guī)范》文檔內(nèi)容學(xué)習(xí)。

關(guān)于實(shí)驗(yàn)板上的CAN收發(fā)器可查閱《TJA1050》文檔了解。


40.1 CAN協(xié)議簡介

CAN是控制器局域網(wǎng)絡(luò)(Controller Area Network)的簡稱,它是由研發(fā)和生產(chǎn)汽車電子產(chǎn)品著稱的德國BOSCH公司開發(fā)的,并最終成為國際標(biāo)準(zhǔn)(ISO11519),是國際上應(yīng)用最廣泛的現(xiàn)場總線之一。

CAN總線協(xié)議已經(jīng)成為汽車計(jì)算機(jī)控制系統(tǒng)和嵌入式工業(yè)控制局域網(wǎng)的標(biāo)準(zhǔn)總線,并且擁有以CAN為底層協(xié)議專為大型貨車和重工機(jī)械車輛設(shè)計(jì)的J1939協(xié)議。近年來,它具有的高可靠性和良好的錯(cuò)誤檢測能力受到重視,被廣泛應(yīng)用于汽車計(jì)算機(jī)控制系統(tǒng)和環(huán)境溫度惡劣、電磁輻射強(qiáng)及振動(dòng)大的工業(yè)環(huán)境。

40.1.1?CAN物理層

與I2C、SPI等具有時(shí)鐘信號的同步通訊方式不同,CAN通訊并不是以時(shí)鐘信號來進(jìn)行同步的,它是一種異步通訊,只具有CAN_High和CAN_Low兩條信號線,共同構(gòu)成一組差分信號線,以差分信號的形式進(jìn)行通訊。

1.????閉環(huán)總線網(wǎng)絡(luò)

CAN物理層的形式主要有兩種,圖?401中的CAN通訊網(wǎng)絡(luò)是一種遵循ISO11898標(biāo)準(zhǔn)的高速、短距離”閉環(huán)網(wǎng)絡(luò)”,它的總線最大長度為40m,通信速度最高為1Mbps,總線的兩端各要求有一個(gè)”120歐”的電阻。

圖?401 CAN閉環(huán)總線通訊網(wǎng)絡(luò)

2.????開環(huán)總線網(wǎng)絡(luò)

圖?402中的是遵循ISO11519-2標(biāo)準(zhǔn)的低速、遠(yuǎn)距離”開環(huán)網(wǎng)絡(luò)”,它的最大傳輸距離為1km,最高通訊速率為125kbps,兩根總線是獨(dú)立的、不形成閉環(huán),要求每根總線上各串聯(lián)有一個(gè)”2.2千歐”的電阻。

圖?402 CAN開環(huán)總線通訊網(wǎng)絡(luò)

3.????通訊節(jié)點(diǎn)????

從CAN通訊網(wǎng)絡(luò)圖可了解到,CAN總線上可以掛載多個(gè)通訊節(jié)點(diǎn),節(jié)點(diǎn)之間的信號經(jīng)過總線傳輸,實(shí)現(xiàn)節(jié)點(diǎn)間通訊。由于CAN通訊協(xié)議不對節(jié)點(diǎn)進(jìn)行地址編碼,而是對數(shù)據(jù)內(nèi)容進(jìn)行編碼的,所以網(wǎng)絡(luò)中的節(jié)點(diǎn)個(gè)數(shù)理論上不受限制,只要總線的負(fù)載足夠即可,可以通過中繼器增強(qiáng)負(fù)載。

CAN通訊節(jié)點(diǎn)由一個(gè)CAN控制器及CAN收發(fā)器組成,控制器與收發(fā)器之間通過CAN_Tx及CAN_Rx信號線相連,收發(fā)器與CAN總線之間使用CAN_High及CAN_Low信號線相連。其中CAN_Tx及CAN_Rx使用普通的類似TTL邏輯信號,而CAN_High及CAN_Low是一對差分信號線,使用比較特別的差分信號,下一小節(jié)再詳細(xì)說明。

當(dāng)CAN節(jié)點(diǎn)需要發(fā)送數(shù)據(jù)時(shí),控制器把要發(fā)送的二進(jìn)制編碼通過CAN_Tx線發(fā)送到收發(fā)器,然后由收發(fā)器把這個(gè)普通的邏輯電平信號轉(zhuǎn)化成差分信號,通過差分線CAN_High和CAN_Low線輸出到CAN總線網(wǎng)絡(luò)。而通過收發(fā)器接收總線上的數(shù)據(jù)到控制器時(shí),則是相反的過程,收發(fā)器把總線上收到的CAN_High及CAN_Low信號轉(zhuǎn)化成普通的邏輯電平信號,通過CAN_Rx輸出到控制器中。

例如,STM32的CAN片上外設(shè)就是通訊節(jié)點(diǎn)中的控制器,為了構(gòu)成完整的節(jié)點(diǎn),還要給它外接一個(gè)收發(fā)器,在我們實(shí)驗(yàn)板中使用型號為TJA1050的芯片作為CAN收發(fā)器。CAN控制器與CAN收發(fā)器的關(guān)系如同TTL串口與MAX3232電平轉(zhuǎn)換芯片的關(guān)系,MAX3232芯片把TTL電平的串口信號轉(zhuǎn)換成RS-232電平的串口信號,CAN收發(fā)器的作用則是把CAN控制器的TTL電平信號轉(zhuǎn)換成差分信號(或者相反)。

4.????差分信號

差分信號又稱差模信號,與傳統(tǒng)使用單根信號線電壓表示邏輯的方式有區(qū)別,使用差分信號傳輸時(shí),需要兩根信號線,這兩個(gè)信號線的振幅相等,相位相反,通過兩根信號線的電壓差值來表示邏輯0和邏輯1。見圖?403,它使用了V+與V-信號的差值表達(dá)出了圖下方的信號。

圖?403?差分信號

相對于單信號線傳輸?shù)姆绞?,使用差分信號傳輸具有如下?yōu)點(diǎn):

?????抗干擾能力強(qiáng),當(dāng)外界存在噪聲干擾時(shí),幾乎會(huì)同時(shí)耦合到兩條信號線上,而接收端只關(guān)心兩個(gè)信號的差值,所以外界的共模噪聲可以被完全抵消。

?????能有效抑制它對外部的電磁干擾,同樣的道理,由于兩根信號的極性相反,他們對外輻射的電磁場可以相互抵消,耦合的越緊密,泄放到外界的電磁能量越少。

?????時(shí)序定位精確,由于差分信號的開關(guān)變化是位于兩個(gè)信號的交點(diǎn),而不像普通單端信號依靠高低兩個(gè)閾值電壓判斷,因而受工藝,溫度的影響小,能降低時(shí)序上的誤差,同時(shí)也更適合于低幅度信號的電路。

由于差分信號線具有這些優(yōu)點(diǎn),所以在USB協(xié)議、485協(xié)議、以太網(wǎng)協(xié)議及CAN協(xié)議的物理層中,都使用了差分信號傳輸。

5.????CAN協(xié)議中的差分信號

CAN協(xié)議中對它使用的CAN_High及CAN_Low表示的差分信號做了規(guī)定,見表?401及圖?404。以高速CAN協(xié)議為例,當(dāng)表示邏輯1時(shí)(隱性電平),CAN_High和CAN_Low線上的電壓均為2.5v,即它們的電壓差VH-VL=0V;而表示邏輯0時(shí)(顯性電平),CAN_High的電平為3.5V,CAN_Low線的電平為1.5V,即它們的電壓差為VH-VL=2V。例如,當(dāng)CAN收發(fā)器從CAN_Tx線接收到來自CAN控制器的低電平信號時(shí)(邏輯0),它會(huì)使CAN_High輸出3.5V,同時(shí)CAN_Low輸出1.5V,從而輸出顯性電平表示邏輯0。

表?401 CAN協(xié)議標(biāo)準(zhǔn)表示的信號邏輯

信號

ISO11898(高速)

ISO11519-2(低速)

隱性(邏輯1)

顯性(邏輯0)

隱性(邏輯1)

顯性(邏輯0)

最小值

典型值

最大值

最小值

典型值

最大值

最小值

典型值

最大值

最小值

典型值

最大值

CAN_High(V)

2.0

2.5

3.0

2.75

3.5

4.5

1.6

1.75

1.9

3.85

4.0

5.0

CAN_Low(V)

2.0

2.5

3.0

0.5

1.5

2.25

3.10

3.25

3.4

0

1.0

1.15

High-Low電位差?(V)

-0.5

0

0.05

1.5

2.0

3.0

-0.3

-1.5

-

0.3

3.0

-

圖?404 CAN的差分信號(高速)

在CAN總線中,必須使它處于隱性電平(邏輯1)或顯性電平(邏輯0)中的其中一個(gè)狀態(tài)。假如有兩個(gè)CAN通訊節(jié)點(diǎn),在同一時(shí)間,一個(gè)輸出隱性電平,另一個(gè)輸出顯性電平,類似I2C總線的”線與”特性將使它處于顯性電平狀態(tài),顯性電平的名字就是這樣來的,即可以認(rèn)為顯性具有優(yōu)先的意味。

由于CAN總線協(xié)議的物理層只有1對差分線,在一個(gè)時(shí)刻只能表示一個(gè)信號,所以對通訊節(jié)點(diǎn)來說,CAN通訊是半雙工的,收發(fā)數(shù)據(jù)需要分時(shí)進(jìn)行。在CAN的通訊網(wǎng)絡(luò)中,因?yàn)楣灿每偩€,在整個(gè)網(wǎng)絡(luò)中同一時(shí)刻只能有一個(gè)通訊節(jié)點(diǎn)發(fā)送信號,其余的節(jié)點(diǎn)在該時(shí)刻都只能接收。

40.1.2?協(xié)議層

以上是CAN的物理層標(biāo)準(zhǔn),約定了電氣特性,以下介紹的協(xié)議層則規(guī)定了通訊邏輯。

1.????CAN的波特率及位同步

由于CAN屬于異步通訊,沒有時(shí)鐘信號線,連接在同一個(gè)總線網(wǎng)絡(luò)中的各個(gè)節(jié)點(diǎn)會(huì)像串口異步通訊那樣,節(jié)點(diǎn)間使用約定好的波特率進(jìn)行通訊,特別地,CAN還會(huì)使用”位同步”的方式來抗干擾、吸收誤差,實(shí)現(xiàn)對總線電平信號進(jìn)行正確的采樣,確保通訊正常。

位時(shí)序分解

為了實(shí)現(xiàn)位同步,CAN協(xié)議把每一個(gè)數(shù)據(jù)位的時(shí)序分解成如圖?405所示的SS段、PTS段、PBS1段、PBS2段,這四段的長度加起來即為一個(gè)CAN數(shù)據(jù)位的長度。分解后最小的時(shí)間單位是Tq,而一個(gè)完整的位由8~25個(gè)Tq組成。為方便表示,圖?405中的高低電平直接代表信號邏輯0或邏輯1(不是差分信號)。

圖?405 CAN位時(shí)序分解圖

該圖中表示的CAN通訊信號每一個(gè)數(shù)據(jù)位的長度為19Tq,其中SS段占1Tq,PTS段占6Tq,PBS1段占5Tq,PBS2段占7Tq。信號的采樣點(diǎn)位于PBS1段與PBS2段之間,通過控制各段的長度,可以對采樣點(diǎn)的位置進(jìn)行偏移,以便準(zhǔn)確地采樣。

各段的作用如介紹下:

?????SS段(SYNC SEG)

SS譯為同步段,若通訊節(jié)點(diǎn)檢測到總線上信號的跳變沿被包含在SS段的范圍之內(nèi),則表示節(jié)點(diǎn)與總線的時(shí)序是同步的,當(dāng)節(jié)點(diǎn)與總線同步時(shí),采樣點(diǎn)采集到的總線電平即可被確定為該位的電平。SS段的大小固定為1Tq。

?????PTS段(PROP SEG)

PTS譯為傳播時(shí)間段,這個(gè)時(shí)間段是用于補(bǔ)償網(wǎng)絡(luò)的物理延時(shí)時(shí)間。是總線上輸入比較器延時(shí)和輸出驅(qū)動(dòng)器延時(shí)總和的兩倍。PTS段的大小可以為1~8Tq。

?????PBS1段(PHASE SEG1),

PBS1譯為相位緩沖段,主要用來補(bǔ)償邊沿階段的誤差,它的時(shí)間長度在重新同步的時(shí)候可以加長。PBS1段的初始大小可以為1~8Tq。

?????PBS2段(PHASE SEG2)

PBS2這是另一個(gè)相位緩沖段,也是用來補(bǔ)償邊沿階段誤差的,它的時(shí)間長度在重新同步時(shí)可以縮短。PBS2段的初始大小可以為2~8Tq。

通訊的波特率

總線上的各個(gè)通訊節(jié)點(diǎn)只要約定好1個(gè)Tq的時(shí)間長度以及每一個(gè)數(shù)據(jù)位占據(jù)多少個(gè)Tq,就可以確定CAN通訊的波特率。

例如,假設(shè)上圖中的1Tq=1us,而每個(gè)數(shù)據(jù)位由19個(gè)Tq組成,則傳輸一位數(shù)據(jù)需要時(shí)間T1bit?=19us,從而每秒可以傳輸?shù)臄?shù)據(jù)位個(gè)數(shù)為:

1x106/19 = 52631.6 (bps)

這個(gè)每秒可傳輸?shù)臄?shù)據(jù)位的個(gè)數(shù)即為通訊中的波特率。

同步過程分析

????波特率只是約定了每個(gè)數(shù)據(jù)位的長度,數(shù)據(jù)同步還涉及到相位的細(xì)節(jié),這個(gè)時(shí)候就需要用到數(shù)據(jù)位內(nèi)的SS、PTS、PBS1及PBS2段了。

根據(jù)對段的應(yīng)用方式差異,CAN的數(shù)據(jù)同步分為硬同步和重新同步。其中硬同步只是當(dāng)存在”幀起始信號”時(shí)起作用,無法確保后續(xù)一連串的位時(shí)序都是同步的,而重新同步方式可解決該問題,這兩種方式具體介紹如下:

(1)????硬同步

若某個(gè)CAN節(jié)點(diǎn)通過總線發(fā)送數(shù)據(jù)時(shí),它會(huì)發(fā)送一個(gè)表示通訊起始的信號(即下一小節(jié)介紹的幀起始信號),該信號是一個(gè)由高變低的下降沿。而掛載到CAN總線上的通訊節(jié)點(diǎn)在不發(fā)送數(shù)據(jù)時(shí),會(huì)時(shí)刻檢測總線上的信號。

見圖?406,可以看到當(dāng)總線出現(xiàn)幀起始信號時(shí),某節(jié)點(diǎn)檢測到總線的幀起始信號不在節(jié)點(diǎn)內(nèi)部時(shí)序的SS段范圍,所以判斷它自己的內(nèi)部時(shí)序與總線不同步,因而這個(gè)狀態(tài)的采樣點(diǎn)采集得的數(shù)據(jù)是不正確的。所以節(jié)點(diǎn)以硬同步的方式調(diào)整,把自己的位時(shí)序中的SS段平移至總線出現(xiàn)下降沿的部分,獲得同步,同步后采樣點(diǎn)就可以采集得正確數(shù)據(jù)了。

圖?406?硬同步過程圖

(2)????重新同步

前面的硬同步只是當(dāng)存在幀起始信號時(shí)才起作用,如果在一幀很長的數(shù)據(jù)內(nèi),節(jié)點(diǎn)信號與總線信號相位有偏移時(shí),這種同步方式就無能為力了。因而需要引入重新同步方式,它利用普通數(shù)據(jù)位的高至低電平的跳變沿來同步(幀起始信號是特殊的跳變沿)。重新同步與硬同步方式相似的地方是它們都使用SS段來進(jìn)行檢測,同步的目的都是使節(jié)點(diǎn)內(nèi)的SS段把跳變沿包含起來。

重新同步的方式分為超前和滯后兩種情況,以總線跳變沿與SS段的相對位置進(jìn)行區(qū)分。第一種相位超前的情況如圖?407,節(jié)點(diǎn)從總線的邊沿跳變中,檢測到它內(nèi)部的時(shí)序比總線的時(shí)序相對超前2Tq,這時(shí)控制器在下一個(gè)位時(shí)序中的PBS1段增加2Tq的時(shí)間長度,使得節(jié)點(diǎn)與總線時(shí)序重新同步。

圖?407?相位超前時(shí)的重新同步

第二種相位滯后的情況如圖?408,節(jié)點(diǎn)從總線的邊沿跳變中,檢測到它的時(shí)序比總線的時(shí)序相對滯后2Tq,這時(shí)控制器在前一個(gè)位時(shí)序中的PBS2段減少2Tq的時(shí)間長度,獲得同步。

圖?408?相位滯后時(shí)的重新同步

在重新同步的時(shí)候,PBS1和PBS2中增加或減少的這段時(shí)間長度被定義為”重新同步補(bǔ)償寬度SJW (reSynchronization Jump Width)“。一般來說CAN控制器會(huì)限定SJW的最大值,如限定了最大SJW=3Tq時(shí),單次同步調(diào)整的時(shí)候不能增加或減少超過3Tq的時(shí)間長度,若有需要,控制器會(huì)通過多次小幅度調(diào)整來實(shí)現(xiàn)同步。當(dāng)控制器設(shè)置的SJW極限值較大時(shí),可以吸收的誤差加大,但通訊的速度會(huì)下降。

2.????CAN的報(bào)文種類及結(jié)構(gòu)

在SPI通訊中,片選、時(shí)鐘信號、數(shù)據(jù)輸入及數(shù)據(jù)輸出這4個(gè)信號都有單獨(dú)的信號線,I2C協(xié)議包含有時(shí)鐘信號及數(shù)據(jù)信號2條信號線,異步串口包含接收與發(fā)送2條信號線,這些協(xié)議包含的信號都比CAN協(xié)議要豐富,它們能輕易進(jìn)行數(shù)據(jù)同步或區(qū)分?jǐn)?shù)據(jù)傳輸方向。而CAN使用的是兩條差分信號線,只能表達(dá)一個(gè)信號,簡潔的物理層決定了CAN必然要配上一套更復(fù)雜的協(xié)議,如何用一個(gè)信號通道實(shí)現(xiàn)同樣、甚至更強(qiáng)大的功能呢?CAN協(xié)議給出的解決方案是對數(shù)據(jù)、操作命令(如讀/寫)以及同步信號進(jìn)行打包,打包后的這些內(nèi)容稱為報(bào)文。

報(bào)文的種類

在原始數(shù)據(jù)段的前面加上傳輸起始標(biāo)簽、片選(識別)標(biāo)簽和控制標(biāo)簽,在數(shù)據(jù)的尾段加上CRC校驗(yàn)標(biāo)簽、應(yīng)答標(biāo)簽和傳輸結(jié)束標(biāo)簽,把這些內(nèi)容按特定的格式打包好,就可以用一個(gè)通道表達(dá)各種信號了,各種各樣的標(biāo)簽就如同SPI中各種通道上的信號,起到了協(xié)同傳輸?shù)淖饔?。?dāng)整個(gè)數(shù)據(jù)包被傳輸?shù)狡渌O(shè)備時(shí),只要這些設(shè)備按格式去解讀,就能還原出原始數(shù)據(jù),這樣的報(bào)文就被稱為CAN的”數(shù)據(jù)幀”。

為了更有效地控制通訊,CAN一共規(guī)定了5種類型的幀,它們的類型及用途說明如表?402。

表?402?幀的種類及其用途

幀用途

數(shù)據(jù)幀

用于節(jié)點(diǎn)向外傳送數(shù)據(jù)

遙控幀

用于向遠(yuǎn)端節(jié)點(diǎn)請求數(shù)據(jù)

錯(cuò)誤幀

用于向遠(yuǎn)端節(jié)點(diǎn)通知校驗(yàn)錯(cuò)誤,請求重新發(fā)送上一個(gè)數(shù)據(jù)

過載幀

用于通知遠(yuǎn)端節(jié)點(diǎn):本節(jié)點(diǎn)尚未做好接收準(zhǔn)備

幀間隔

用于將數(shù)據(jù)幀及遙控幀與前面的幀分離開來

數(shù)據(jù)幀的結(jié)構(gòu)

數(shù)據(jù)幀是在CAN通訊中最主要、最復(fù)雜的報(bào)文,我們來了解它的結(jié)構(gòu),見圖?409。

圖?409?數(shù)據(jù)幀的結(jié)構(gòu)

數(shù)據(jù)幀以一個(gè)顯性位(邏輯0)開始,以7個(gè)連續(xù)的隱性位(邏輯1)結(jié)束,在它們之間,分別有仲裁段、控制段、數(shù)據(jù)段、CRC段和ACK段。

?????幀起始

SOF段(Start Of Frame),譯為幀起始,幀起始信號只有一個(gè)數(shù)據(jù)位,是一個(gè)顯性電平,它用于通知各個(gè)節(jié)點(diǎn)將有數(shù)據(jù)傳輸,其它節(jié)點(diǎn)通過幀起始信號的電平跳變沿來進(jìn)行硬同步。

?????仲裁段

當(dāng)同時(shí)有兩個(gè)報(bào)文被發(fā)送時(shí),總線會(huì)根據(jù)仲裁段的內(nèi)容決定哪個(gè)數(shù)據(jù)包能被傳輸,這也是它名稱的由來。

仲裁段的內(nèi)容主要為本數(shù)據(jù)幀的ID信息(標(biāo)識符),數(shù)據(jù)幀具有標(biāo)準(zhǔn)格式和擴(kuò)展格式兩種,區(qū)別就在于ID信息的長度,標(biāo)準(zhǔn)格式的ID為11位,擴(kuò)展格式的ID為29位,它在標(biāo)準(zhǔn)ID的基礎(chǔ)上多出18位。在CAN協(xié)議中,ID起著重要的作用,它決定著數(shù)據(jù)幀發(fā)送的優(yōu)先級,也決定著其它節(jié)點(diǎn)是否會(huì)接收這個(gè)數(shù)據(jù)幀。CAN協(xié)議不對掛載在它之上的節(jié)點(diǎn)分配優(yōu)先級和地址,對總線的占有權(quán)是由信息的重要性決定的,即對于重要的信息,我們會(huì)給它打包上一個(gè)優(yōu)先級高的ID,使它能夠及時(shí)地發(fā)送出去。也正因?yàn)樗@樣的優(yōu)先級分配原則,使得CAN的擴(kuò)展性大大加強(qiáng),在總線上增加或減少節(jié)點(diǎn)并不影響其它設(shè)備。

報(bào)文的優(yōu)先級,是通過對ID的仲裁來確定的。根據(jù)前面對物理層的分析我們知道如果總線上同時(shí)出現(xiàn)顯性電平和隱性電平,總線的狀態(tài)會(huì)被置為顯性電平,CAN正是利用這個(gè)特性進(jìn)行仲裁。

若兩個(gè)節(jié)點(diǎn)同時(shí)競爭CAN總線的占有權(quán),當(dāng)它們發(fā)送報(bào)文時(shí),若首先出現(xiàn)隱性電平,則會(huì)失去對總線的占有權(quán),進(jìn)入接收狀態(tài)。見圖?4010,在開始階段,兩個(gè)設(shè)備發(fā)送的電平一樣,所以它們一直繼續(xù)發(fā)送數(shù)據(jù)。到了圖中箭頭所指的時(shí)序處,節(jié)點(diǎn)單元1發(fā)送的為隱性電平,而此時(shí)節(jié)點(diǎn)單元2發(fā)送的為顯性電平,由于總線的”線與”特性使它表達(dá)出顯示電平,因此單元2競爭總線成功,這個(gè)報(bào)文得以被繼續(xù)發(fā)送出去。

圖?4010?仲裁過程

仲裁段ID的優(yōu)先級也影響著接收設(shè)備對報(bào)文的反應(yīng)。因?yàn)樵贑AN總線上數(shù)據(jù)是以廣播的形式發(fā)送的,所有連接在CAN總線的節(jié)點(diǎn)都會(huì)收到所有其它節(jié)點(diǎn)發(fā)出的有效數(shù)據(jù),因而我們的CAN控制器大多具有根據(jù)ID過濾報(bào)文的功能,它可以控制自己只接收某些ID的報(bào)文。

回看圖?409中的數(shù)據(jù)幀格式,可看到仲裁段除了報(bào)文ID外,還有RTR、IDE和SRR位。

(1)????RTR位(Remote Transmission Request Bit),譯作遠(yuǎn)程傳輸請求位,它是用于區(qū)分?jǐn)?shù)據(jù)幀和遙控幀的,當(dāng)它為顯性電平時(shí)表示數(shù)據(jù)幀,隱性電平時(shí)表示遙控幀。

(2)????IDE位(Identifier Extension Bit),譯作標(biāo)識符擴(kuò)展位,它是用于區(qū)分標(biāo)準(zhǔn)格式與擴(kuò)展格式,當(dāng)它為顯性電平時(shí)表示標(biāo)準(zhǔn)格式,隱性電平時(shí)表示擴(kuò)展格式。

(3)????SRR位(Substitute Remote Request Bit),只存在于擴(kuò)展格式,它用于替代標(biāo)準(zhǔn)格式中的RTR位。由于擴(kuò)展幀中的SRR位為隱性位,RTR在數(shù)據(jù)幀為顯性位,所以在兩個(gè)ID相同的標(biāo)準(zhǔn)格式報(bào)文與擴(kuò)展格式報(bào)文中,標(biāo)準(zhǔn)格式的優(yōu)先級較高。

?????控制段

在控制段中的r1和r0為保留位,默認(rèn)設(shè)置為顯性位。它最主要的是DLC段(Data Length Code),譯為數(shù)據(jù)長度碼,它由4個(gè)數(shù)據(jù)位組成,用于表示本報(bào)文中的數(shù)據(jù)段含有多少個(gè)字節(jié),DLC段表示的數(shù)字為0~8。

?????數(shù)據(jù)段

數(shù)據(jù)段為數(shù)據(jù)幀的核心內(nèi)容,它是節(jié)點(diǎn)要發(fā)送的原始信息,由0~8個(gè)字節(jié)組成,MSB先行。

?????CRC段

為了保證報(bào)文的正確傳輸,CAN的報(bào)文包含了一段15位的CRC校驗(yàn)碼,一旦接收節(jié)點(diǎn)算出的CRC碼跟接收到的CRC碼不同,則它會(huì)向發(fā)送節(jié)點(diǎn)反饋出錯(cuò)信息,利用錯(cuò)誤幀請求它重新發(fā)送。CRC部分的計(jì)算一般由CAN控制器硬件完成,出錯(cuò)時(shí)的處理則由軟件控制最大重發(fā)數(shù)。

在CRC校驗(yàn)碼之后,有一個(gè)CRC界定符,它為隱性位,主要作用是把CRC校驗(yàn)碼與后面的ACK段間隔起來。

?????ACK段

ACK段包括一個(gè)ACK槽位,和ACK界定符位。類似I2C總線,在ACK槽位中,發(fā)送節(jié)點(diǎn)發(fā)送的是隱性位,而接收節(jié)點(diǎn)則在這一位中發(fā)送顯性位以示應(yīng)答。在ACK槽和幀結(jié)束之間由ACK界定符間隔開。

?????幀結(jié)束

EOF段(End Of Frame),譯為幀結(jié)束,幀結(jié)束段由發(fā)送節(jié)點(diǎn)發(fā)送的7個(gè)隱性位表示結(jié)束。

其它報(bào)文的結(jié)構(gòu)

關(guān)于其它的CAN報(bào)文結(jié)構(gòu),不再展開講解,其主要內(nèi)容見圖?4011。

圖?4011?各種CAN報(bào)文的結(jié)構(gòu)


40.2 STM32的CAN外設(shè)簡介

STM32的芯片中具有bxCAN控制器?(Basic Extended CAN),它支持CAN協(xié)議2.0A和2.0B標(biāo)準(zhǔn)。

該CAN控制器支持最高的通訊速率為1Mb/s;可以自動(dòng)地接收和發(fā)送CAN報(bào)文,支持使用標(biāo)準(zhǔn)ID和擴(kuò)展ID的報(bào)文;外設(shè)中具有3個(gè)發(fā)送郵箱,發(fā)送報(bào)文的優(yōu)先級可以使用軟件控制,還可以記錄發(fā)送的時(shí)間;具有2個(gè)3級深度的接收FIFO,可使用過濾功能只接收或不接收某些ID號的報(bào)文;可配置成自動(dòng)重發(fā);不支持使用DMA進(jìn)行數(shù)據(jù)收發(fā)。

40.2.1?STM32的CAN架構(gòu)剖析

圖?4012 STM32的CAN外設(shè)架構(gòu)圖

STM32的有兩組CAN控制器,其中CAN1是主設(shè)備,框圖中的”存儲(chǔ)訪問控制器”是由CAN1控制的,CAN2無法直接訪問存儲(chǔ)區(qū)域,所以使用CAN2的時(shí)候必須使能CAN1外設(shè)的時(shí)鐘??驁D中主要包含CAN控制內(nèi)核、發(fā)送郵箱、接收FIFO以及驗(yàn)收篩選器,下面對框圖中的各個(gè)部分進(jìn)行介紹。

1.????CAN控制內(nèi)核

框圖中標(biāo)號處的CAN控制內(nèi)核包含了各種控制寄存器及狀態(tài)寄存器,我們主要講解其中的主控制寄存器CAN_MCR及位時(shí)序寄存器CAN_BTR。

主控制寄存器CAN_MCR

主控制寄存器CAN_MCR負(fù)責(zé)管理CAN的工作模式,它使用以下寄存器位實(shí)現(xiàn)控制。

(1)????DBF調(diào)試凍結(jié)功能

DBF(Debug freeze)調(diào)試凍結(jié),使用它可設(shè)置CAN處于工作狀態(tài)或禁止收發(fā)的狀態(tài),禁止收發(fā)時(shí)仍可訪問接收FIFO中的數(shù)據(jù)。這兩種狀態(tài)是當(dāng)STM32芯片處于程序調(diào)試模式時(shí)才使用的,平時(shí)使用并不影響。

(2)????TTCM時(shí)間觸發(fā)模式

TTCM(Time triggered communication mode)時(shí)間觸發(fā)模式,它用于配置CAN的時(shí)間觸發(fā)通信模式,在此模式下,CAN使用它內(nèi)部定時(shí)器產(chǎn)生時(shí)間戳,并把它保存在CAN_RDTxR、CAN_TDTxR寄存器中。內(nèi)部定時(shí)器在每個(gè)CAN位時(shí)間累加,在接收和發(fā)送的幀起始位被采樣,并生成時(shí)間戳。利用它可以實(shí)現(xiàn)ISO 11898-4 CAN標(biāo)準(zhǔn)的分時(shí)同步通信功能。

(3)????ABOM自動(dòng)離線管理

ABOM(Automatic bus-off management)?自動(dòng)離線管理,它用于設(shè)置是否使用自動(dòng)離線管理功能。當(dāng)節(jié)點(diǎn)檢測到它發(fā)送錯(cuò)誤或接收錯(cuò)誤超過一定值時(shí),會(huì)自動(dòng)進(jìn)入離線狀態(tài),在離線狀態(tài)中,CAN不能接收或發(fā)送報(bào)文。處于離線狀態(tài)的時(shí)候,可以軟件控制恢復(fù)或者直接使用這個(gè)自動(dòng)離線管理功能,它會(huì)在適當(dāng)?shù)臅r(shí)候自動(dòng)恢復(fù)。

(4)????AWUM自動(dòng)喚醒

AWUM(Automatic bus-off management),自動(dòng)喚醒功能,CAN外設(shè)可以使用軟件進(jìn)入低功耗的睡眠模式,如果使能了這個(gè)自動(dòng)喚醒功能,當(dāng)CAN檢測到總線活動(dòng)的時(shí)候,會(huì)自動(dòng)喚醒。

(5)????NART自動(dòng)重傳

NART(No automatic retransmission)報(bào)文自動(dòng)重傳功能,設(shè)置這個(gè)功能后,當(dāng)報(bào)文發(fā)送失敗時(shí)會(huì)自動(dòng)重傳至成功為止。若不使用這個(gè)功能,無論發(fā)送結(jié)果如何,消息只發(fā)送一次。

(6)????RFLM鎖定模式

RFLM(Receive FIFO locked mode)FIFO鎖定模式,該功能用于鎖定接收FIFO。鎖定后,當(dāng)接收FIFO溢出時(shí),會(huì)丟棄下一個(gè)接收的報(bào)文。若不鎖定,則下一個(gè)接收到的報(bào)文會(huì)覆蓋原報(bào)文。

(7)????TXFP報(bào)文發(fā)送優(yōu)先級的判定方法

TXFP(Transmit FIFO priority)報(bào)文發(fā)送優(yōu)先級的判定方法,當(dāng)CAN外設(shè)的發(fā)送郵箱中有多個(gè)待發(fā)送報(bào)文時(shí),本功能可以控制它是根據(jù)報(bào)文的ID優(yōu)先級還是報(bào)文存進(jìn)郵箱的順序來發(fā)送。

位時(shí)序寄存器(CAN_BTR)及波特率

CAN外設(shè)中的位時(shí)序寄存器CAN_BTR用于配置測試模式、波特率以及各種位內(nèi)的段參數(shù)。

(1)????測試模式

為方便調(diào)試,STM32的CAN提供了測試模式,配置位時(shí)序寄存器CAN_BTR的SILM及LBKM寄存器位可以控制使用正常模式、靜默模式、回環(huán)模式及靜默回環(huán)模式,見圖?4013。

圖?4013?四種工作模式

各個(gè)工作模式介紹如下:

?????正常模式

正常模式下就是一個(gè)正常的CAN節(jié)點(diǎn),可以向總線發(fā)送數(shù)據(jù)和接收數(shù)據(jù)。

?????靜默模式

靜默模式下,它自己的輸出端的邏輯0數(shù)據(jù)會(huì)直接傳輸?shù)剿约旱妮斎攵?,邏?可以被發(fā)送到總線,所以它不能向總線發(fā)送顯性位(邏輯0),只能發(fā)送隱性位(邏輯1)。輸入端可以從總線接收內(nèi)容。由于它只可發(fā)送的隱性位不會(huì)強(qiáng)制影響總線的狀態(tài),所以把它稱為靜默模式。這種模式一般用于監(jiān)測,它可以用于分析總線上的流量,但又不會(huì)因?yàn)榘l(fā)送顯性位而影響總線。

?????回環(huán)模式

回環(huán)模式下,它自己的輸出端的所有內(nèi)容都直接傳輸?shù)阶约旱妮斎攵耍敵龆说膬?nèi)容同時(shí)也會(huì)被傳輸?shù)娇偩€上,即也可使用總線監(jiān)測它的發(fā)送內(nèi)容。輸入端只接收自己發(fā)送端的內(nèi)容,不接收來自總線上的內(nèi)容。使用回環(huán)模式可以進(jìn)行自檢。

?????回環(huán)靜默模式

回環(huán)靜默模式是以上兩種模式的結(jié)合,自己的輸出端的所有內(nèi)容都直接傳輸?shù)阶约旱妮斎攵?,并且不?huì)向總線發(fā)送顯性位影響總線,不能通過總線監(jiān)測它的發(fā)送內(nèi)容。輸入端只接收自己發(fā)送端的內(nèi)容,不接收來自總線上的內(nèi)容。這種方式可以在”熱自檢”時(shí)使用,即自我檢查的時(shí)候,不會(huì)干擾總線。

以上說的各個(gè)模式,是不需要修改硬件接線的,如當(dāng)輸出直連輸入時(shí),它是在STM32芯片內(nèi)部連接的,傳輸路徑不經(jīng)過STM32的CAN_Tx/Rx引腳,更不經(jīng)過外部連接的CAN收發(fā)器,只有輸出數(shù)據(jù)到總線或從總線接收的情況下才會(huì)經(jīng)過CAN_Tx/Rx引腳和收發(fā)器。

(2)????位時(shí)序及波特率

STM32外設(shè)定義的位時(shí)序與我們前面解釋的CAN標(biāo)準(zhǔn)時(shí)序有一點(diǎn)區(qū)別,見圖?4014。

圖?4014 STM32中CAN的位時(shí)序

STM32的CAN外設(shè)位時(shí)序中只包含3段,分別是同步段SYNC_SEG、位段BS1及位段BS2,采樣點(diǎn)位于BS1及BS2段的交界處。其中SYNC_SEG段固定長度為1Tq,而BS1及BS2段可以在位時(shí)序寄存器CAN_BTR設(shè)置它們的時(shí)間長度,它們可以在重新同步期間增長或縮短,該長度SJW也可在位時(shí)序寄存器中配置。

理解STM32的CAN外設(shè)的位時(shí)序時(shí),可以把它的BS1段理解為是由前面介紹的CAN標(biāo)準(zhǔn)協(xié)議中PTS段與PBS1段合在一起的,而BS2段就相當(dāng)于PBS2段。

了解位時(shí)序后,我們就可以配置波特率了。通過配置位時(shí)序寄存器CAN_BTR的TS1[3:0]及TS2[2:0]寄存器位設(shè)定BS1及BS2段的長度后,我們就可以確定每個(gè)CAN數(shù)據(jù)位的時(shí)間:

BS1段時(shí)間:

TS1=Tq x (TS1[3:0] + 1),

BS2段時(shí)間:

TS2= Tq x (TS2[2:0] + 1),

一個(gè)數(shù)據(jù)位的時(shí)間:

T1bit?=1Tq+TS1+TS2?=1+ (TS1[3:0] + 1)+ (TS2[2:0] + 1)= N Tq

其中單個(gè)時(shí)間片的長度Tq與CAN外設(shè)的所掛載的時(shí)鐘總線及分頻器配置有關(guān),CAN1和CAN2外設(shè)都是掛載在APB1總線上的,而位時(shí)序寄存器CAN_BTR中的BRP[9:0]寄存器位可以設(shè)置CAN外設(shè)時(shí)鐘的分頻值,所以:

Tq = (BRP[9:0]+1) x TPCLK

其中的PCLK指APB1時(shí)鐘,默認(rèn)值為45MHz。

最終可以計(jì)算出CAN通訊的波特率:

BaudRate = 1/N Tq

例如表?403說明了一種把波特率配置為1Mbps的方式。

表?403?一種配置波特率為1Mbps的方式

參數(shù)

說明

SYNC_SE段

固定為1Tq

BS1段

設(shè)置為5Tq (實(shí)際寫入TS1[3:0]的值為4)

BS2段

設(shè)置為3Tq (實(shí)際寫入TS2[2:0]的值為2)

TPCLK

APB1按默認(rèn)配置為F=45MHz,TPCLK=1/45M

CAN外設(shè)時(shí)鐘分頻

設(shè)置為5分頻(實(shí)際寫入BRP[9:0]的值為4)

1Tq時(shí)間長度

Tq = (BRP[9:0]+1) x TPCLK?????= ????5 x 1/45M=1/9M

1位的時(shí)間長度

T1bit?=1Tq+TS1+TS2 ????????????= ????1+5+3 = 9Tq

波特率

BaudRate = 1/N Tq????????????=????1/(1/9M x 9)=1Mbps

2.????CAN發(fā)送郵箱

回到圖?245中的CAN外設(shè)框圖,在標(biāo)號?處的是CAN外設(shè)的發(fā)送郵箱,它一共有3個(gè)發(fā)送郵箱,即最多可以緩存3個(gè)待發(fā)送的報(bào)文。

每個(gè)發(fā)送郵箱中包含有標(biāo)識符寄存器CAN_TIxR、數(shù)據(jù)長度控制寄存器CAN_TDTxR及2個(gè)數(shù)據(jù)寄存器CAN_TDLxR、CAN_TDHxR,它們的功能見表?405。

表?404?發(fā)送郵箱的寄存器

寄存器名

功能

標(biāo)識符寄存器CAN_TIxR

存儲(chǔ)待發(fā)送報(bào)文的ID、擴(kuò)展ID、IDE位及RTR位

數(shù)據(jù)長度控制寄存器CAN_TDTxR

存儲(chǔ)待發(fā)送報(bào)文的DLC段

低位數(shù)據(jù)寄存器CAN_TDLxR

存儲(chǔ)待發(fā)送報(bào)文數(shù)據(jù)段的Data0-Data3這四個(gè)字節(jié)的內(nèi)容

高位數(shù)據(jù)寄存器CAN_TDHxR

存儲(chǔ)待發(fā)送報(bào)文數(shù)據(jù)段的Data4-Data7這四個(gè)字節(jié)的內(nèi)容

當(dāng)我們要使用CAN外設(shè)發(fā)送報(bào)文時(shí),把報(bào)文的各個(gè)段分解,按位置寫入到這些寄存器中,并對標(biāo)識符寄存器CAN_TIxR中的發(fā)送請求寄存器位TMIDxR_TXRQ置1,即可把數(shù)據(jù)發(fā)送出去。

其中標(biāo)識符寄存器CAN_TIxR中的STDID寄存器位比較特別。我們知道CAN的標(biāo)準(zhǔn)標(biāo)識符的總位數(shù)為11位,而擴(kuò)展標(biāo)識符的總位數(shù)為29位的。當(dāng)報(bào)文使用擴(kuò)展標(biāo)識符的時(shí)候,標(biāo)識符寄存器CAN_TIxR中的STDID[10:0]等效于EXTID[18:28]位,它與EXTID[17:0]共同組成完整的29位擴(kuò)展標(biāo)識符。

3.????CAN接收FIFO

圖?245中的CAN外設(shè)框圖,在標(biāo)號?處的是CAN外設(shè)的接收FIFO,它一共有2個(gè)接收FIFO,每個(gè)FIFO中有3個(gè)郵箱,即最多可以緩存6個(gè)接收到的報(bào)文。當(dāng)接收到報(bào)文時(shí),F(xiàn)IFO的報(bào)文計(jì)數(shù)器會(huì)自增,而STM32內(nèi)部讀取FIFO數(shù)據(jù)之后,報(bào)文計(jì)數(shù)器會(huì)自減,我們通過狀態(tài)寄存器可獲知報(bào)文計(jì)數(shù)器的值,而通過前面主控制寄存器的RFLM位,可設(shè)置鎖定模式,鎖定模式下FIFO溢出時(shí)會(huì)丟棄新報(bào)文,非鎖定模式下FIFO溢出時(shí)新報(bào)文會(huì)覆蓋舊報(bào)文。

跟發(fā)送郵箱類似,每個(gè)接收FIFO中包含有標(biāo)識符寄存器CAN_RIxR、數(shù)據(jù)長度控制寄存器CAN_RDTxR及2個(gè)數(shù)據(jù)寄存器CAN_RDLxR、CAN_RDHxR,它們的功能見表?405。

表?405?發(fā)送郵箱的寄存器

寄存器名

功能

標(biāo)識符寄存器CAN_RIxR

存儲(chǔ)收到報(bào)文的ID、擴(kuò)展ID、IDE位及RTR位

數(shù)據(jù)長度控制寄存器CAN_RDTxR

存儲(chǔ)收到報(bào)文的DLC段

低位數(shù)據(jù)寄存器CAN_RDLxR

存儲(chǔ)收到報(bào)文數(shù)據(jù)段的Data0-Data3這四個(gè)字節(jié)的內(nèi)容

高位數(shù)據(jù)寄存器CAN_RDHxR

存儲(chǔ)收到報(bào)文數(shù)據(jù)段的Data4-Data7這四個(gè)字節(jié)的內(nèi)容

通過中斷或狀態(tài)寄存器知道接收FIFO有數(shù)據(jù)后,我們再讀取這些寄存器的值即可把接收到的報(bào)文加載到STM32的內(nèi)存中。

4.????驗(yàn)收篩選器

圖?245中的CAN外設(shè)框圖,在標(biāo)號?處的是CAN外設(shè)的驗(yàn)收篩選器,一共有28個(gè)篩選器組,每個(gè)篩選器組有2個(gè)寄存器,CAN1和CAN2共用的篩選器的。

在CAN?協(xié)議中,消息的標(biāo)識符與節(jié)點(diǎn)地址無關(guān),但與消息內(nèi)容有關(guān)。因此,發(fā)送節(jié)點(diǎn)將報(bào)文廣播給所有接收器時(shí),接收節(jié)點(diǎn)會(huì)根據(jù)報(bào)文標(biāo)識符的值來確定軟件是否需要該消息,為了簡化軟件的工作,STM32的CAN外設(shè)接收報(bào)文前會(huì)先使用驗(yàn)收篩選器檢查,只接收需要的報(bào)文到FIFO中。

篩選器工作的時(shí)候,可以調(diào)整篩選ID的長度及過濾模式。根據(jù)篩選ID長度來分類有有以下兩種:

(1)????檢查STDID[10:0]、EXTID[17:0]、IDE?和RTR?位,一共31位。

(2)????檢查STDID[10:0]、RTR、IDE?和EXTID[17:15],一共16位。

通過配置篩選尺度寄存器CAN_FS1R的FSCx位可以設(shè)置篩選器工作在哪個(gè)尺度。

而根據(jù)過濾的方法分為以下兩種模式:

(1)????標(biāo)識符列表模式,它把要接收報(bào)文的ID列成一個(gè)表,要求報(bào)文ID與列表中的某一個(gè)標(biāo)識符完全相同才可以接收,可以理解為白名單管理。

(2)????掩碼模式,它把可接收報(bào)文ID的某幾位作為列表,這幾位被稱為掩碼,可以把它理解成關(guān)鍵字搜索,只要掩碼(關(guān)鍵字)相同,就符合要求,報(bào)文就會(huì)被保存到接收FIFO。

通過配置篩選模式寄存器CAN_FM1R的FBMx位可以設(shè)置篩選器工作在哪個(gè)模式。

不同的尺度和不同的過濾方法可使篩選器工作在圖?4015的4種狀態(tài)。

圖?4015?篩選器的4種工作狀態(tài)

每組篩選器包含2個(gè)32位的寄存器,分別為CAN_FxR1和CAN_FxR2,它們用來存儲(chǔ)要篩選的ID或掩碼,各個(gè)寄存器位代表的意義與圖中兩個(gè)寄存器下面”映射”的一欄一致,各個(gè)模式的說明見表?406。

表?406?篩選器的工作狀態(tài)說明

模式

說明

32位掩碼模式

CAN_FxR1存儲(chǔ)ID,CAN_FxR2存儲(chǔ)哪個(gè)位必須要與CAN_FxR1中的ID一致,2個(gè)寄存器表示1組掩碼。

32位標(biāo)識符模式

CAN_FxR1和CAN_FxR2各存儲(chǔ)1個(gè)ID,2個(gè)寄存器表示2個(gè)篩選的ID

16位掩碼模式

CAN_FxR1高16位存儲(chǔ)ID,低16位存儲(chǔ)哪個(gè)位必須要與高16位的ID一致;

CAN_FxR2高16位存儲(chǔ)ID,低16位存儲(chǔ)哪個(gè)位必須要與高16位的ID一致

2個(gè)寄存器表示2組掩碼。

16位標(biāo)識符模式

CAN_FxR1和CAN_FxR2各存儲(chǔ)2個(gè)ID,2個(gè)寄存器表示4個(gè)篩選的ID

例如下面的表格所示,在掩碼模式時(shí),第一個(gè)寄存器存儲(chǔ)要篩選的ID,第二個(gè)寄存器存儲(chǔ)掩碼,掩碼為1的部分表示該位必須與ID中的內(nèi)容一致,篩選的結(jié)果為表中第三行的ID值,它是一組包含多個(gè)的ID值,其中x表示該位可以為1可以為0。

ID

1

0

1

1

1

0

1

掩碼

1

1

1

0

0

1

0

篩選的ID

1

0

1

x

x

0

x

而工作在標(biāo)識符模式時(shí),2個(gè)寄存器存儲(chǔ)的都是要篩選的ID,它只包含2個(gè)要篩選的ID值(32位模式時(shí))。

如果使能了篩選器,且報(bào)文的ID與所有篩選器的配置都不匹配,CAN外設(shè)會(huì)丟棄該報(bào)文,不存入接收FIFO。

5.????整體控制邏輯

回到圖?245結(jié)構(gòu)框圖,圖中的標(biāo)號…處表示的是CAN2外設(shè)的結(jié)構(gòu),它與CAN1外設(shè)是一樣的,他們共用篩選器且由于存儲(chǔ)訪問控制器由CAN1控制,所以要使用CAN2的時(shí)候必須要使能CAN1的時(shí)鐘。


40.3 CAN初始化結(jié)構(gòu)體

從STM32的CAN外設(shè)我們了解到它的功能非常多,控制涉及的寄存器也非常豐富,而使用STM32標(biāo)準(zhǔn)庫提供的各種結(jié)構(gòu)體及庫函數(shù)可以簡化這些控制過程。跟其它外設(shè)一樣,STM32標(biāo)準(zhǔn)庫提供了CAN初始化結(jié)構(gòu)體及初始化函數(shù)來控制CAN的工作方式,提供了收發(fā)報(bào)文使用的結(jié)構(gòu)體及收發(fā)函數(shù),還有配置控制篩選器模式及ID的結(jié)構(gòu)體。這些內(nèi)容都定義在庫文件”stm32f4xx_can.h“及”stm32f4xx_can.c“中,編程時(shí)我們可以結(jié)合這兩個(gè)文件內(nèi)的注釋使用或參考庫幫助文檔。

首先我們來學(xué)習(xí)初始化結(jié)構(gòu)體的內(nèi)容,見代碼清單?241。

代碼清單?401 CAN初始化結(jié)構(gòu)體

1?/**

2?* @brief CAN?初始化結(jié)構(gòu)體

3?*/

4 typedef?struct?{

5?uint16_t?CAN_Prescaler;?/*配置CAN外設(shè)的時(shí)鐘分頻,可設(shè)置為1-1024*/

6?uint8_t?CAN_Mode;?/*配置CAN的工作模式,回環(huán)或正常模式*/

7?uint8_t?CAN_SJW;?/*配置SJW極限值?*/

8?uint8_t?CAN_BS1;?/*配置BS1段長度*/

9?uint8_t?CAN_BS2;?/*配置BS2段長度?*/

10?FunctionalState CAN_TTCM;?/*是否使能TTCM時(shí)間觸發(fā)功能*/

11?FunctionalState CAN_ABOM;?/*是否使能ABOM自動(dòng)離線管理功能*/

12?FunctionalState CAN_AWUM;?/*是否使能AWUM自動(dòng)喚醒功能?*/

13?FunctionalState CAN_NART;?/*是否使能NART自動(dòng)重傳功能*/

14?FunctionalState CAN_RFLM;?/*是否使能RFLM鎖定FIFO功能*/

15?FunctionalState CAN_TXFP;?/*配置TXFP報(bào)文優(yōu)先級的判定方法*/

16?} CAN_InitTypeDef;

這些結(jié)構(gòu)體成員說明如下,其中括號內(nèi)的文字是對應(yīng)參數(shù)在STM32標(biāo)準(zhǔn)庫中定義的宏,這些結(jié)構(gòu)體成員都是”40.2.1 1CAN控制內(nèi)核”小節(jié)介紹的內(nèi)容,可對比閱讀:

(1)????CAN_Prescaler

本成員設(shè)置CAN外設(shè)的時(shí)鐘分頻,它可控制時(shí)間片Tq的時(shí)間長度,這里設(shè)置的值最終會(huì)減1后再寫入BRP寄存器位,即前面介紹的Tq計(jì)算公式:

Tq = (BRP[9:0]+1) x TPCLK

等效于:Tq = CAN_Prescaler x TPCLK

(2)????CAN_Mode

本成員設(shè)置CAN的工作模式,可設(shè)置為正常模式(CAN_Mode_Normal)、回環(huán)模式(CAN_Mode_LoopBack)、靜默模式(CAN_Mode_Silent)以及回環(huán)靜默模式(CAN_Mode_Silent_LoopBack)。

(3)????CAN_SJW

本成員可以配置SJW的極限長度,即CAN重新同步時(shí)單次可增加或縮短的最大長度,它可以被配置為1-4Tq(CAN_SJW_1/2/3/4tq)。

(4)????CAN_BS1

本成員用于設(shè)置CAN位時(shí)序中的BS1段的長度,它可以被配置為1-16個(gè)Tq長度(CAN_BS1_1/2/3…16tq)。

(5)????CAN_BS2

本成員用于設(shè)置CAN位時(shí)序中的BS2段的長度,它可以被配置為1-8個(gè)Tq長度(CAN_BS2_1/2/3…8tq)。

SYNC_SEG、BS1段及BS2段的長度加起來即一個(gè)數(shù)據(jù)位的長度,即前面介紹的原來計(jì)算公式:

T1bit?=1Tq+TS1+TS2?=1+ (TS1[3:0] + 1)+ (TS2[2:0] + 1)

等效于:T1bit?= 1Tq+CAN_BS1+CAN_BS2

(6)????CAN_TTCM

本成員用于設(shè)置是否使用時(shí)間觸發(fā)功能(ENABLE/DISABLE),時(shí)間觸發(fā)功能在某些CAN標(biāo)準(zhǔn)中會(huì)使用到。

(7)????CAN_ABOM

本成員用于設(shè)置是否使用自動(dòng)離線管理(ENABLE/DISABLE),使用自動(dòng)離線管理可以在節(jié)點(diǎn)出錯(cuò)離線后適時(shí)自動(dòng)恢復(fù),不需要軟件干預(yù)。

(8)????CAN_ AWUM

本成員用于設(shè)置是否使用自動(dòng)喚醒功能(ENABLE/DISABLE),使能自動(dòng)喚醒功能后它會(huì)在監(jiān)測到總線活動(dòng)后自動(dòng)喚醒。

(9)????CAN_ABOM

本成員用于設(shè)置是否使用自動(dòng)離線管理功能(ENABLE/DISABLE),使用自動(dòng)離線管理可以在出錯(cuò)時(shí)離線后適時(shí)自動(dòng)恢復(fù),不需要軟件干預(yù)。

(10)????CAN_NART

本成員用于設(shè)置是否使用自動(dòng)重傳功能(ENABLE/DISABLE),使用自動(dòng)重傳功能時(shí),會(huì)一直發(fā)送報(bào)文直到成功為止。

(11)????CAN_RFLM

本成員用于設(shè)置是否使用鎖定接收FIFO(ENABLE/DISABLE),鎖定接收FIFO后,若FIFO溢出時(shí)會(huì)丟棄新數(shù)據(jù),否則在FIFO溢出時(shí)以新數(shù)據(jù)覆蓋舊數(shù)據(jù)。

(12)????CAN_TXFP

本成員用于設(shè)置發(fā)送報(bào)文的優(yōu)先級判定方法(ENABLE/DISABLE),使能時(shí),以報(bào)文存入發(fā)送郵箱的先后順序來發(fā)送,否則按照報(bào)文ID的優(yōu)先級來發(fā)送。


配置完這些結(jié)構(gòu)體成員后,我們調(diào)用庫函數(shù)CAN_Init即可把這些參數(shù)寫入到CAN控制寄存器中,實(shí)現(xiàn)CAN的初始化。


40.4 CAN發(fā)送及接收結(jié)構(gòu)體

在發(fā)送或接收報(bào)文時(shí),需要往發(fā)送郵箱中寫入報(bào)文信息或從接收FIFO中讀取報(bào)文信息,利用STM32標(biāo)準(zhǔn)庫的發(fā)送及接收結(jié)構(gòu)體可以方便地完成這樣的工作,它們的定義見代碼清單?402。

代碼清單?402 CAN發(fā)送及接收結(jié)構(gòu)體

1?/**

2?* @brief CAN Tx message structure definition

3?*?發(fā)送結(jié)構(gòu)體

4?*/

5 typedef?struct?{

6?uint32_t?StdId;?/*存儲(chǔ)報(bào)文的標(biāo)準(zhǔn)標(biāo)識符11位,0-0x7FF. */

7?uint32_t?ExtId;?/*存儲(chǔ)報(bào)文的擴(kuò)展標(biāo)識符29位,0-0x1FFFFFFF. */

8?uint8_t?IDE;?/*存儲(chǔ)IDE擴(kuò)展標(biāo)志?*/

9?uint8_t?RTR;?/*存儲(chǔ)RTR遠(yuǎn)程幀標(biāo)志*/

10?uint8_t?DLC;?/*存儲(chǔ)報(bào)文數(shù)據(jù)段的長度,0-8 */

11?uint8_t?Data[8];?/*存儲(chǔ)報(bào)文數(shù)據(jù)段的內(nèi)容?*/

12?} CanTxMsg;

13

14?/**

15?* @brief CAN Rx message structure definition

16?*?接收結(jié)構(gòu)體

17?*/

18 typedef?struct?{

19?uint32_t?StdId;?/*存儲(chǔ)了報(bào)文的標(biāo)準(zhǔn)標(biāo)識符11位,0-0x7FF. */

20?uint32_t?ExtId;?/*存儲(chǔ)了報(bào)文的擴(kuò)展標(biāo)識符29位,0-0x1FFFFFFF. */

21?uint8_t?IDE;?/*存儲(chǔ)了IDE擴(kuò)展標(biāo)志?*/

22?uint8_t?RTR;?/*存儲(chǔ)了RTR遠(yuǎn)程幀標(biāo)志*/

23?uint8_t?DLC;?/*存儲(chǔ)了報(bào)文數(shù)據(jù)段的長度,0-8 */

24?uint8_t?Data[8];?/*存儲(chǔ)了報(bào)文數(shù)據(jù)段的內(nèi)容?*/

25?uint8_t?FMI;?/*存儲(chǔ)了本報(bào)文是由經(jīng)過篩選器存儲(chǔ)進(jìn)FIFO的,0-0xFF */

26?} CanRxMsg;

這些結(jié)構(gòu)體成員都是”40.2.1 2CAN發(fā)送郵箱及CAN接收FIFO“小節(jié)介紹的內(nèi)容,可對比閱讀,發(fā)送結(jié)構(gòu)體與接收結(jié)構(gòu)體是類似的,只是接收結(jié)構(gòu)體多了一個(gè)FMI成員,說明如下:

(1)????StdId

本成員存儲(chǔ)的是報(bào)文的11位標(biāo)準(zhǔn)標(biāo)識符,范圍是0-0x7FF。

(2)????ExtId

本成員存儲(chǔ)的是報(bào)文的29位擴(kuò)展標(biāo)識符,范圍是0-0x1FFFFFFF。ExtId與StdId這兩個(gè)成員根據(jù)下面的IDE位配置,只有一個(gè)是有效的。

(3)????IDE

本成員存儲(chǔ)的是擴(kuò)展標(biāo)志IDE位,當(dāng)它的值為宏CAN_ID_STD時(shí)表示本報(bào)文是標(biāo)準(zhǔn)幀,使用StdId成員存儲(chǔ)報(bào)文ID;當(dāng)它的值為宏CAN_ID_EXT時(shí)表示本報(bào)文是擴(kuò)展幀,使用ExtId成員存儲(chǔ)報(bào)文ID。

(4)????RTR

本成員存儲(chǔ)的是報(bào)文類型標(biāo)志RTR位,當(dāng)它的值為宏CAN_RTR_Data時(shí)表示本報(bào)文是數(shù)據(jù)幀;當(dāng)它的值為宏CAN_RTR_Remote時(shí)表示本報(bào)文是遙控幀,由于遙控幀沒有數(shù)據(jù)段,所以當(dāng)報(bào)文是遙控幀時(shí),下面的Data[8]成員的內(nèi)容是無效的。

(5)????DLC

本成員存儲(chǔ)的是數(shù)據(jù)幀數(shù)據(jù)段的長度,它的值的范圍是0-8,當(dāng)報(bào)文是遙控幀時(shí)DLC值為0。

(6)????Data[8]

本成員存儲(chǔ)的就是數(shù)據(jù)幀中數(shù)據(jù)段的數(shù)據(jù)。

(7)????FMI

本成員只存在于接收結(jié)構(gòu)體,它存儲(chǔ)了篩選器的編號,表示本報(bào)文是經(jīng)過哪個(gè)篩選器存儲(chǔ)進(jìn)接收FIFO的,可以用它簡化軟件處理。


當(dāng)需要使用CAN發(fā)送報(bào)文時(shí),先定義一個(gè)上面發(fā)送類型的結(jié)構(gòu)體,然后把報(bào)文的內(nèi)容按成員賦值到該結(jié)構(gòu)體中,最后調(diào)用庫函數(shù)CAN_Transmit把這些內(nèi)容寫入到發(fā)送郵箱即可把報(bào)文發(fā)送出去。

接收報(bào)文時(shí),通過檢測標(biāo)志位獲知接收FIFO的狀態(tài),若收到報(bào)文,可調(diào)用庫函數(shù)CAN_Receive把接收FIFO中的內(nèi)容讀取到預(yù)先定義的接收類型結(jié)構(gòu)體中,然后再訪問該結(jié)構(gòu)體即可利用報(bào)文了。


40.5 CAN篩選器結(jié)構(gòu)體

CAN的篩選器有多種工作模式,利用篩選器結(jié)構(gòu)體可方便配置,它的定義見代碼清單?403。

代碼清單?403 CAN篩選器結(jié)構(gòu)體

1?/**

2?* @brief CAN filter init structure definition

3?* CAN篩選器結(jié)構(gòu)體

4?*/

5 typedef?struct?{

6?uint16_t?CAN_FilterIdHigh;?/*CAN_FxR1寄存器的高16位?*/

7?uint16_t?CAN_FilterIdLow;?/*CAN_FxR1寄存器的低16位*/

8?uint16_t?CAN_FilterMaskIdHigh;?/*CAN_FxR2寄存器的高16位*/

9?uint16_t?CAN_FilterMaskIdLow;?/*CAN_FxR2寄存器的低16位?*/

10?uint16_t?CAN_FilterFIFOAssignment;?/*設(shè)置經(jīng)過篩選后數(shù)據(jù)存儲(chǔ)到哪個(gè)接收FIFO */

11?uint8_t?CAN_FilterNumber;?/*篩選器編號,范圍0-27*/

12?uint8_t?CAN_FilterMode;?/*篩選器模式?*/

13?uint8_t?CAN_FilterScale;?/*設(shè)置篩選器的尺度?*/

14?FunctionalState CAN_FilterActivation;?/*是否使能本篩選器*/

15?} CAN_FilterInitTypeDef;

這些結(jié)構(gòu)體成員都是”40.2.1 4驗(yàn)收篩選器”小節(jié)介紹的內(nèi)容,可對比閱讀,各個(gè)結(jié)構(gòu)體成員的介紹如下:

(1)????CAN_FilterIdHigh

CAN_FilterIdHigh成員用于存儲(chǔ)要篩選的ID,若篩選器工作在32位模式,它存儲(chǔ)的是所篩選ID的高16位;若篩選器工作在16位模式,它存儲(chǔ)的就是一個(gè)完整的要篩選的ID。

(2)????CAN_FilterIdLow

類似地,CAN_FilterIdLow成員也是用于存儲(chǔ)要篩選的ID,若篩選器工作在32位模式,它存儲(chǔ)的是所篩選ID的低16位;若篩選器工作在16位模式,它存儲(chǔ)的就是一個(gè)完整的要篩選的ID。

(3)????CAN_FilterMaskIdHigh

CAN_FilterMaskIdHigh存儲(chǔ)的內(nèi)容分兩種情況,當(dāng)篩選器工作在標(biāo)識符列表模式時(shí),它的功能與CAN_FilterIdHigh相同,都是存儲(chǔ)要篩選的ID;而當(dāng)篩選器工作在掩碼模式時(shí),它存儲(chǔ)的是CAN_FilterIdHigh成員對應(yīng)的掩碼,與CAN_FilterIdLow組成一組篩選器。

(4)????CAN_FilterMaskIdLow

類似地,CAN_FilterMaskIdLow存儲(chǔ)的內(nèi)容也分兩種情況,當(dāng)篩選器工作在標(biāo)識符列表模式時(shí),它的功能與CAN_FilterIdLow相同,都是存儲(chǔ)要篩選的ID;而當(dāng)篩選器工作在掩碼模式時(shí),它存儲(chǔ)的是CAN_FilterIdLow成員對應(yīng)的掩碼,與CAN_FilterIdLow組成一組篩選器。

上面四個(gè)結(jié)構(gòu)體的存儲(chǔ)的內(nèi)容很容易讓人糊涂,請結(jié)合前面的圖?4014和下面的表?407理解,如果還搞不清楚,再結(jié)合庫函數(shù)CAN_FilterInit的源碼來分析。

表?407?不同模式下各結(jié)構(gòu)體成員的內(nèi)容

模式

CAN_FilterIdHigh

CAN_FilterIdLow

CAN_FilterMaskIdHigh

CAN_FilterMaskIdLow

32位列表模式

ID1的高16位

ID1的低16位

ID2的高16位

ID2的低16位

16位列表模式

ID1的完整數(shù)值

ID2的完整數(shù)值

ID3的完整數(shù)值

ID4的完整數(shù)值

32位掩碼模式

ID1的高16位

ID1的低16位

ID1掩碼的高16位

ID1掩碼的低16位

16位掩碼模式

ID1的完整數(shù)值

ID2的完整數(shù)值

ID1掩碼的完整數(shù)值

ID2掩碼完整數(shù)值

對這些結(jié)構(gòu)體成員賦值的時(shí)候,還要注意寄存器位的映射,即注意哪部分代表STID,哪部分代表EXID以及IDE、RTR位。

(5)????CAN_FilterFIFOAssignment

本成員用于設(shè)置當(dāng)報(bào)文通過篩選器的匹配后,該報(bào)文會(huì)被存儲(chǔ)到哪一個(gè)接收FIFO,它的可選值為FIFO0或FIFO1(宏CAN_Filter_FIFO0/1)。

(6)????CAN_FilterNumber

本成員用于設(shè)置篩選器的編號,即本過濾器結(jié)構(gòu)體配置的是哪一組篩選器,CAN一共有28個(gè)篩選器,所以它的可輸入?yún)?shù)范圍為0-27。

(7)????CAN_FilterMode

本成員用于設(shè)置篩選器的工作模式,可以設(shè)置為列表模式(宏CAN_FilterMode_IdList)及掩碼模式(宏CAN_FilterMode_IdMask)。

(8)????CAN_FilterScale

本成員用于設(shè)置篩選器的尺度,可以設(shè)置為32位長(宏CAN_FilterScale_32bit)及16位長(宏CAN_FilterScale_16bit)。

(9)????CAN_FilterActivation

本成員用于設(shè)置是否激活這個(gè)篩選器(宏ENABLE/DISABLE)。


配置完這些結(jié)構(gòu)體成員后,我們調(diào)用庫函數(shù)CAN_FilterInit即可把這些參數(shù)寫入到篩選控制寄存器中,從而使用篩選器。我們前面說如果不理解那幾個(gè)ID結(jié)構(gòu)體成員存儲(chǔ)的內(nèi)容時(shí),可以直接閱讀庫函數(shù)CAN_FilterInit的源代碼理解,就是因?yàn)樗苯訉拇嫫鲗懭雰?nèi)容,代碼的邏輯是非常清晰的。


40.6 CAN—雙機(jī)通訊實(shí)驗(yàn)

本小節(jié)演示如何使用STM32的CAN外設(shè)實(shí)現(xiàn)兩個(gè)設(shè)備之間的通訊,該實(shí)驗(yàn)中使用了兩個(gè)實(shí)驗(yàn)板,如果您只有一個(gè)實(shí)驗(yàn)板,也可以使用CAN的回環(huán)模式進(jìn)行測試,不影響學(xué)習(xí)的。為此,我們提供了”CAN—雙機(jī)通訊”及”CAN—回環(huán)測試”兩個(gè)工程,可根據(jù)自己的實(shí)驗(yàn)環(huán)境選擇相應(yīng)的工程來學(xué)習(xí)。這兩個(gè)工程的主體都是一樣的,本教程主要以”CAN—雙機(jī)通訊”工程進(jìn)行講解。

40.6.1?硬件設(shè)計(jì)

圖?4016?雙CAN通訊實(shí)驗(yàn)硬件連接圖

圖?4016中的是兩個(gè)實(shí)驗(yàn)板的硬件連接。在單個(gè)實(shí)驗(yàn)板中,作為CAN控制器的STM32引出CAN_Tx和CAN_Rx兩個(gè)引腳與CAN收發(fā)器TJA1050相連,收發(fā)器使用CANH及CANL引腳連接到CAN總線網(wǎng)絡(luò)中。為了方便使用,我們每個(gè)實(shí)驗(yàn)板引出的CANH及CANL都連接了1個(gè)120歐的電阻作為CAN總線的端電阻,所以要注意如果您要把實(shí)驗(yàn)板作為一個(gè)普通節(jié)點(diǎn)連接到現(xiàn)有的CAN總線時(shí),是不應(yīng)添加該電阻的!

要實(shí)現(xiàn)通訊,我們還要使用導(dǎo)線把實(shí)驗(yàn)板引出的CANH及CANL兩條總線連接起來,才能構(gòu)成完整的網(wǎng)絡(luò)。實(shí)驗(yàn)板之間CANH1與CANH2連接,CANL1與CANL2連接即可。

要注意的是,由于我們的實(shí)驗(yàn)板CAN使用的信號線與液晶屏共用了,為防止干擾,平時(shí)我們默認(rèn)是不給CAN收發(fā)器供電的,使用CAN的時(shí)候一定要把CAN接線端子旁邊的”C/4-5V“排針使用跳線帽與”5V“排針連接起來進(jìn)行供電,并且把液晶屏從板子上拔下來。

如果您使用的是單機(jī)回環(huán)測試的工程實(shí)驗(yàn),就不需要使用導(dǎo)線連接板子了,而且也不需要給收發(fā)器供電,因?yàn)榛丨h(huán)模式的信號是不經(jīng)過收發(fā)器的,不過,它還是不能和液晶屏同時(shí)使用的。

40.6.2?軟件設(shè)計(jì)

為了使工程更加有條理,我們把CAN控制器相關(guān)的代碼獨(dú)立分開存儲(chǔ),方便以后移植。在”串口實(shí)驗(yàn)”之上新建”bsp_can.c“及”bsp_can.h“文件,這些文件也可根據(jù)您的喜好命名,它們不屬于STM32標(biāo)準(zhǔn)庫的內(nèi)容,是由我們自己根據(jù)應(yīng)用需要編寫的。

1.????編程要點(diǎn)

(1)????初始化CAN通訊使用的目標(biāo)引腳及端口時(shí)鐘;

(2)????使能CAN外設(shè)的時(shí)鐘;

(3)????配置CAN外設(shè)的工作模式、位時(shí)序以及波特率;

(4)????配置篩選器的工作方式;

(5)????編寫測試程序,收發(fā)報(bào)文并校驗(yàn)。

2.????代碼分析

CAN硬件相關(guān)宏定義

我們把CAN硬件相關(guān)的配置都以宏的形式定義到”bsp_can.h“文件中,見代碼清單?242。

代碼清單?404 CAN硬件配置相關(guān)的宏(bsp_can.h文件)

1

2?/*CAN硬件相關(guān)的定義*/

3?#define CANx CAN1

4?#define CAN_CLK RCC_APB1Periph_CAN1

5?/*接收中斷號*/

6?#define CAN_RX_IRQ CAN1_RX0_IRQn

7?/*接收中斷服務(wù)函數(shù)*/

8?#define CAN_RX_IRQHandler CAN1_RX0_IRQHandler

9

10?/*引腳*/

11?#define CAN_RX_PIN GPIO_Pin_8

12?#define CAN_TX_PIN GPIO_Pin_9

13?#define CAN_TX_GPIO_PORT GPIOB

14?#define CAN_RX_GPIO_PORT GPIOB

15?#define CAN_TX_GPIO_CLK RCC_AHB1Periph_GPIOB

16?#define CAN_RX_GPIO_CLK RCC_AHB1Periph_GPIOB

17?#define CAN_AF_PORT GPIO_AF_CAN1

18?#define CAN_RX_SOURCE GPIO_PinSource8

19?#define CAN_TX_SOURCE GPIO_PinSource9

以上代碼根據(jù)硬件連接,把與CAN通訊使用的CAN號、引腳號、引腳源以及復(fù)用功能映射都以宏封裝起來,并且定義了接收中斷的中斷向量和中斷服務(wù)函數(shù),我們通過中斷來獲知接收FIFO的信息。

初始化CAN的 GPIO

利用上面的宏,編寫CAN的初始化函數(shù),見代碼清單?243。

代碼清單?405 CAN的GPIO初始化函數(shù)(bsp_can.c文件)

  1. 1 /*


  • 1

2?*?函數(shù)名:CAN_GPIO_Config

3?*?描述:CAN的GPIO?配置

4?*?輸入:無

5?*?輸出?:?無

6?*?調(diào)用:內(nèi)部調(diào)用

7?*/

8?static void?CAN_GPIO_Config(void)

9?{

10?GPIO_InitTypeDef GPIO_InitStructure;

11

12?/*?使能GPIO時(shí)鐘*/

13?RCC_AHB1PeriphClockCmd(CAN_TX_GPIO_CLK|CAN_RX_GPIO_CLK, ENABLE);

14

15?/*?引腳源*/

16?GPIO_PinAFConfig(CAN_TX_GPIO_PORT, CAN_RX_SOURCE, CAN_AF_PORT);

17?GPIO_PinAFConfig(CAN_RX_GPIO_PORT, CAN_TX_SOURCE, CAN_AF_PORT);

18

19?/*?配置?CAN TX?引腳?*/

20?GPIO_InitStructure.GPIO_Pin = CAN_TX_PIN;

21?GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

22?GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

23?GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

24?GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

25?GPIO_Init(CAN_TX_GPIO_PORT, &GPIO_InitStructure);

26

27?/*?配置?CAN RX?引腳?*/

28?GPIO_InitStructure.GPIO_Pin = CAN_RX_PIN ;

29?GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

30?GPIO_Init(CAN_RX_GPIO_PORT, &GPIO_InitStructure);

31?}

與所有使用到GPIO的外設(shè)一樣,都要先把使用到的GPIO引腳模式初始化,配置好復(fù)用功能。CAN的兩個(gè)引腳都配置成通用推挽輸出模式即可。

配置CAN的工作模式

接下來我們配置CAN的工作模式,由于我們是自己用的兩個(gè)板子之間進(jìn)行通訊,波特率之類的配置只要兩個(gè)板子一致即可。如果您要使實(shí)驗(yàn)板與某個(gè)CAN總線網(wǎng)絡(luò)的通訊的節(jié)點(diǎn)通訊,那么實(shí)驗(yàn)板的CAN配置必須要與該總線一致。我們實(shí)驗(yàn)中使用的配置見代碼清單?244。

代碼清單?406?配置CAN的工作模式(bsp_can.c文件)

1?/*

2?*?函數(shù)名:CAN_Mode_Config

3?*?描述:CAN的模式配置

4?*?輸入:無

5?*?輸出?:?無

6?*?調(diào)用:內(nèi)部調(diào)用

7?*/

8?static void?CAN_Mode_Config(void)

9?{

10?CAN_InitTypeDef CAN_InitStructure;

11?/************************CAN通信參數(shù)設(shè)置************************/

12?/* Enable CAN clock */

13?RCC_APB1PeriphClockCmd(CAN_CLK, ENABLE);

14

15?/*CAN寄存器初始化*/

16?CAN_DeInit(CAN1);

17?CAN_StructInit(&CAN_InitStructure);

18

19?/*CAN單元初始化*/

20?CAN_InitStructure.CAN_TTCM=DISABLE;?//MCR-TTCM?關(guān)閉時(shí)間觸發(fā)通信模式使能

21?CAN_InitStructure.CAN_ABOM=ENABLE;?//MCR-ABOM?使能自動(dòng)離線管理

22?CAN_InitStructure.CAN_AWUM=ENABLE;?//MCR-AWUM?使用自動(dòng)喚醒模式

23?CAN_InitStructure.CAN_NART=DISABLE;?//MCR-NART?禁止報(bào)文自動(dòng)重傳

24?CAN_InitStructure.CAN_RFLM=DISABLE;?//MCR-RFLM?接收FIFO?不鎖定

25?????????????????????????//?溢出時(shí)新報(bào)文會(huì)覆蓋原有報(bào)文

26?CAN_InitStructure.CAN_TXFP=DISABLE;?//MCR-TXFP?發(fā)送FIFO優(yōu)先級取決于報(bào)文標(biāo)示符

27?CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;?//正常工作模式

28?CAN_InitStructure.CAN_SJW=CAN_SJW_2tq;?//BTR-SJW?重新同步跳躍寬度?2個(gè)時(shí)間單元

29

30?/* ss=1 bs1=5 bs2=3?位時(shí)間寬度為(1+5+3)?波特率即為時(shí)鐘周期tq*(1+3+5) */

31?CAN_InitStructure.CAN_BS1=CAN_BS1_5tq;?//BTR-TS1?時(shí)間段1?占用了5個(gè)時(shí)間單元

32?CAN_InitStructure.CAN_BS2=CAN_BS2_3tq;?//BTR-TS1?時(shí)間段2?占用了3個(gè)時(shí)間單元

33

34?/* CAN Baudrate = 1 MBps (1MBps已為stm32的CAN最高速率) (CAN?時(shí)鐘頻率為?APB 1 = 45 MHz) */

35?BTR-BRP?波特率分頻器定義了時(shí)間單元的時(shí)間長度?45/(1+5+3)/5=1 Mbps

36?CAN_InitStructure.CAN_Prescaler =5;

37?CAN_Init(CANx, &CAN_InitStructure);

38?}

這段代碼主要是把CAN的模式設(shè)置成了正常工作模式,如果您閱讀的是”CAN—回環(huán)測試”的工程,這里是被配置成回環(huán)模式的,除此之外,兩個(gè)工程就沒有其它差別了。

代碼中還把位時(shí)序中的BS1和BS2段分別設(shè)置成了5Tq和3Tq,再加上SYNC_SEG段,一個(gè)CAN數(shù)據(jù)位就是9Tq了,加上CAN外設(shè)的分頻配置為5分頻,CAN所使用的總線時(shí)鐘fAPB1?= 45MHz,于是我們可計(jì)算出它的波特率:

1Tq = 1/(45M/5)=1/9 us

T1bit=(5+3+1) x Tq =1us

波特率=1/T1bit?=1Mbps

配置篩選器

以上是配置CAN的工作模式,為了方便管理接收報(bào)文,我們還要把篩選器用起來,見代碼清單?245。

代碼清單?407?配置CAN的篩選器(bsp_can.c文件)

1

2?/*IDE位的標(biāo)志*/

3?#define CAN_ID_STD ((uint32_t)0x00000000)?/*標(biāo)準(zhǔn)ID */

4?#define CAN_ID_EXT ((uint32_t)0x00000004)?/*擴(kuò)展ID */

5

6?/*RTR位的標(biāo)志*/

7?#define CAN_RTR_Data ((uint32_t)0x00000000)?/*數(shù)據(jù)幀?*/

8?#define CAN_RTR_Remote ((uint32_t)0x00000002)?/*遠(yuǎn)程幀*/

9

10?/************************************************************************/

11?/*

12?*?函數(shù)名:CAN_Filter_Config

13?*?描述:CAN的篩選器配置

14?*?輸入:無

15?*?輸出?:?無

16?*?調(diào)用:內(nèi)部調(diào)用

17?*/

18?static void?CAN_Filter_Config(void)

19?{

20?CAN_FilterInitTypeDef CAN_FilterInitStructure;

21

22?/*CAN篩選器初始化*/

23?CAN_FilterInitStructure.CAN_FilterNumber=0;?//篩選器組0

24?//工作在掩碼模式

25?CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;

26?//篩選器位寬為單個(gè)32位。

27?CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;

28

29?/*?使能篩選器,按照標(biāo)志符的內(nèi)容進(jìn)行比對篩選,

30?擴(kuò)展ID不是如下的就拋棄掉,是的話,會(huì)存入FIFO0。?*/

31//要篩選的ID高位,第0位保留,第1位為RTR標(biāo)志,第2位為IDE標(biāo)志,從第3位開始是EXID

32CAN_FilterInitStructure.CAN_FilterIdHigh= ((((u32)0x1314<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF0000)>>16;

33?//要篩選的ID低位

34?CAN_FilterInitStructure.CAN_FilterIdLow= (((u32)0x1314<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF;

35?//篩選器高16位每位必須匹配

36?CAN_FilterInitStructure.CAN_FilterMaskIdHigh= 0xFFFF;

37?//篩選器低16位每位必須匹配

38?CAN_FilterInitStructure.CAN_FilterMaskIdLow= 0xFFFF;

39?//篩選器被關(guān)聯(lián)到FIFO0

40?CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0 ;

41?//使能篩選器

42?CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;

43

44?CAN_FilterInit(&CAN_FilterInitStructure);

45?/*CAN通信中斷使能*/

46?CAN_ITConfig(CANx, CAN_IT_FMP0, ENABLE);

47?}

這段代碼把篩選器第0組配置成了32位的掩碼模式,并且把它的輸出連接到接收FIFO0,若通過了篩選器的匹配,報(bào)文會(huì)被存儲(chǔ)到接收FIFO0。

篩選器配置的重點(diǎn)是配置ID和掩碼,根據(jù)我們的配置,這個(gè)篩選器工作在圖?4017中的模式。

圖?4017?一個(gè)32位的掩碼模式篩選器

在該配置中,結(jié)構(gòu)體成員CAN_FilterIdHigh和CAN_FilterIdLow存儲(chǔ)的是要篩選的ID,而CAN_FilterMaskIdHigh和CAN_FilterMaskIdLow存儲(chǔ)的是相應(yīng)的掩碼。在賦值時(shí),要注意寄存器位的映射,在32位的ID中,第0位是保留位,第1位是RTR標(biāo)志,第2位是IDE標(biāo)志,從第3位起才是報(bào)文的ID(擴(kuò)展ID)。

因此在上述代碼中我們先把擴(kuò)展ID”0x1314“、IDE位標(biāo)志”宏CAN_ID_EXT“以及RTR位標(biāo)志”宏CAN_RTR_DATA“根據(jù)寄存器位映射組成一個(gè)32位的數(shù)據(jù),然后再把它的高16位和低16位分別賦值給結(jié)構(gòu)體成員CAN_FilterIdHigh和CAN_FilterIdLow。

而在掩碼部分,為簡單起見我們直接對所有位賦值為1,表示上述所有標(biāo)志都完全一樣的報(bào)文才能經(jīng)過篩選,所以我們這個(gè)配置相當(dāng)于單個(gè)ID列表的模式,只篩選了一個(gè)ID號,而不是篩選一組ID號。這里只是為了演示方便,實(shí)際使用中一般會(huì)對不要求相等的數(shù)據(jù)位賦值為0,從而過濾一組ID,如果有需要,還可以繼續(xù)配置多個(gè)篩選器組,最多可以配置28個(gè),代碼中只是配置了篩選器組0。

對結(jié)構(gòu)體賦值完畢后調(diào)用庫函數(shù)CAN_FilterInit把個(gè)篩選器組的參數(shù)寫入到寄存器中。

配置接收中斷

在配置篩選器代碼的最后部分我們還調(diào)用庫函數(shù)CAN_ITConfig使能了CAN的中斷,該函數(shù)使用的輸入?yún)?shù)宏CAN_IT_FMP0表示當(dāng)FIFO0接收到數(shù)據(jù)時(shí)會(huì)引起中斷,該接收中斷的優(yōu)先級配置如下,見代碼清單?246。

代碼清單?408?配置CAN接收中斷的優(yōu)先級(bsp_can.c文件)

1?/*接收中斷號*/

2?#define CAN_RX_IRQ CAN1_RX0_IRQn

3?/*

4?*?函數(shù)名:CAN_NVIC_Config

5?*?描述:CAN的NVIC?配置,第1優(yōu)先級組,0,0優(yōu)先級

6?*?輸入:無

7?*?輸出?:?無

8?*?調(diào)用:內(nèi)部調(diào)用

9?*/

10?static void?CAN_NVIC_Config(void)

11?{

12?NVIC_InitTypeDef NVIC_InitStructure;

13?/* Configure one bit for preemption priority */

14?NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

15?/*中斷設(shè)置*/

16?NVIC_InitStructure.NVIC_IRQChannel = CAN_RX_IRQ;?//CAN RX中斷

17?NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

18?NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

19?NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

20?NVIC_Init(&NVIC_InitStructure);

21?}

這部分與我們配置其它中斷的優(yōu)先級無異,都是配置NVIC結(jié)構(gòu)體,優(yōu)先級可根據(jù)自己的需要配置,最主要的是中斷向量,上述代碼中把中斷向量配置成了CAN的接收中斷。

設(shè)置發(fā)送報(bào)文

要使用CAN發(fā)送報(bào)文時(shí),我們需要先定義一個(gè)發(fā)送報(bào)文結(jié)構(gòu)體并向它賦值,見代碼清單?247。

代碼清單?409?設(shè)置要發(fā)送的報(bào)文(bsp_can.c文件)

1?/*IDE位的標(biāo)志*/

2?#define CAN_ID_STD ((uint32_t)0x00000000)?/*標(biāo)準(zhǔn)ID */

3?#define CAN_ID_EXT ((uint32_t)0x00000004)?/*擴(kuò)展ID */

4

5?/*RTR位的標(biāo)志*/

6?#define CAN_RTR_Data ((uint32_t)0x00000000)?/*數(shù)據(jù)幀?*/

7?#define CAN_RTR_Remote ((uint32_t)0x00000002)?/*遠(yuǎn)程幀*/

8

9?/*

10?*?函數(shù)名:CAN_SetMsg

11?*?描述:CAN通信報(bào)文內(nèi)容設(shè)置,設(shè)置一個(gè)數(shù)據(jù)內(nèi)容為0-7的數(shù)據(jù)包

12?*?輸入:無

13?*?輸出?:?無

14?*?調(diào)用:外部調(diào)用

15?*/

16?void?CAN_SetMsg(CanTxMsg *TxMessage)

17?{

18?uint8_t?ubCounter = 0;

19

20?//TxMessage.StdId=0x00;

21?TxMessage->ExtId=0x1314;?//使用的擴(kuò)展ID

22?TxMessage->IDE=CAN_ID_EXT;?//擴(kuò)展模式

23?TxMessage->RTR=CAN_RTR_DATA;?//發(fā)送的是數(shù)據(jù)

24?TxMessage->DLC=8;?//數(shù)據(jù)長度為8字節(jié)

25

26?/*設(shè)置要發(fā)送的數(shù)據(jù)0-7*/

27?for?(ubCounter = 0; ubCounter < 8; ubCounter++)

28?{

29?TxMessage->Data[ubCounter] = ubCounter;

30?}

31?}

這段代碼是我們?yōu)榱朔奖阊菔径约憾x的設(shè)置報(bào)文內(nèi)容的函數(shù),它把報(bào)文設(shè)置成了擴(kuò)展模式的數(shù)據(jù)幀,擴(kuò)展ID為0x1314,數(shù)據(jù)段的長度為8,且數(shù)據(jù)內(nèi)容分別為0-7,實(shí)際應(yīng)用中您可根據(jù)自己的需求發(fā)設(shè)置報(bào)文內(nèi)容。當(dāng)我們設(shè)置好報(bào)文內(nèi)容后,調(diào)用庫函數(shù)CAN_Transmit即可把該報(bào)文存儲(chǔ)到發(fā)送郵箱,然后CAN外設(shè)會(huì)把它發(fā)送出去:

CAN_Transmit(CANx, &TxMessage);

接收報(bào)文

由于我們設(shè)置了接收中斷,所以接收報(bào)文的操作是在中斷的服務(wù)函數(shù)中完成的,見代碼清單?248。

代碼清單?4010?接收報(bào)文(stm32f4xx_it.c)

1

2?/*接收中斷服務(wù)函數(shù)*/

3?#define CAN_RX_IRQHandler CAN1_RX0_IRQHandler

4

5 extern?__IO?uint32_t?flag ;?//用于標(biāo)志是否接收到數(shù)據(jù),在中斷函數(shù)中賦值

6 extern?CanRxMsg RxMessage;?//接收緩沖區(qū)

7?/********************************************************************/

8?void?CAN_RX_IRQHandler(void)

9?{

10?/*從郵箱中讀出報(bào)文*/

11?CAN_Receive(CANx, CAN_FIFO0, &RxMessage);

12

13?/*?比較ID是否為0x1314 */

14?if?((RxMessage.ExtId==0x1314) && (RxMessage.IDE==CAN_ID_EXT) && (RxMessage.DLC==8) )

15?{

16?flag = 1;?//接收成功

17?}

18?else

19?{

20?flag = 0;?//接收失敗

21?}

22?}

根據(jù)我們前面的配置,若CAN接收的報(bào)文經(jīng)過篩選器匹配后會(huì)被存儲(chǔ)到FIFO0中,并引起中斷進(jìn)入到這個(gè)中斷服務(wù)函數(shù)中,在這個(gè)函數(shù)里我們調(diào)用了庫函數(shù)CAN_Receive把報(bào)文從FIFO復(fù)制到自定義的接收報(bào)文結(jié)構(gòu)體RxMessage中,并且比較了接收到的報(bào)文ID是否與我們希望接收的一致,若一致就設(shè)置標(biāo)志flag=1,否則為0,通過flag標(biāo)志通知主程序流程獲知是否接收到數(shù)據(jù)。

要注意如果設(shè)置了接收報(bào)文中斷,必須要在中斷內(nèi)調(diào)用CAN_Receive函數(shù)讀取接收FIFO的內(nèi)容,因?yàn)橹挥羞@樣才能清除該FIFO的接收中斷標(biāo)志,如果不在中斷內(nèi)調(diào)用它清除標(biāo)志的話,一旦接收到報(bào)文,STM32會(huì)不斷進(jìn)入中斷服務(wù)函數(shù),導(dǎo)致程序卡死。

3.????main函數(shù)

最后我們來閱讀main函數(shù),了解整個(gè)通訊流程,見代碼清單?2414。

代碼清單?4011 main函數(shù)

1

2?_IO?uint32_t?flag = 0;?//用于標(biāo)志是否接收到數(shù)據(jù),在中斷函數(shù)中賦值

3?CanTxMsg TxMessage;?//發(fā)送緩沖區(qū)

4?CanRxMsg RxMessage;?//接收緩沖區(qū)

5

6?/**

7?* @brief?主函數(shù)

8?* @param?無

9?* @retval?無

10?*/

11?int?main(void)

12?{

13?LED_GPIO_Config();

14

15?/*初始化USART1*/

16?Debug_USART_Config();

17

18?/*初始化按鍵*/

19?Key_GPIO_Config();

20

21?/*初始化can,在中斷接收CAN數(shù)據(jù)包*/

22?CAN_Config();

23

24?printf(”\r\n歡迎使用秉火?STM32 F429?開發(fā)板。\r\n”);

25?printf(”\r\n秉火F429 CAN通訊實(shí)驗(yàn)例程\r\n”);

26

27?printf(”\r\n實(shí)驗(yàn)步驟:\r\n”);

28

29?printf(”\r\n?1.使用導(dǎo)線連接好兩個(gè)CAN訊設(shè)備\r\n”);

30?printf(”\r\n?2.使用跳線帽連接好:5v — C/4-5V?\r\n”);

31?printf(”\r\n?3.按下開發(fā)板的KEY1鍵,會(huì)使用CAN向外發(fā)送0-7的數(shù)據(jù)包,包的擴(kuò)展ID為0x1314?\r\n”);

32?printf(”\r\n?4.若開發(fā)板的CAN接收到擴(kuò)展ID為0x1314的數(shù)據(jù)包,會(huì)把數(shù)據(jù)以打印到串口。?\r\n”);

33?printf(”\r\n?5.本例中的can波特率為1MBps,為stm32的can最高速率。?\r\n”);

34

35?while?(1)

36?{

37?/*按一次按鍵發(fā)送一次數(shù)據(jù)*/

38?if?( Key_Scan(KEY1_GPIO_PORT,KEY1_PIN) == KEY_ON)

39?{

40?LED_BLUE;

41?/*設(shè)置要發(fā)送的報(bào)文*/

42?CAN_SetMsg(&TxMessage);

43?/*把報(bào)文存儲(chǔ)到發(fā)送郵箱,發(fā)送*/

44?CAN_Transmit(CANx, &TxMessage);

45

46?can_delay(10000);//等待發(fā)送完畢,可使用CAN_TransmitStatus查看狀態(tài)

47

48?LED_GREEN;

49

50?printf(”\r\n已使用CAN發(fā)送數(shù)據(jù)包!\r\n”);

51?printf(”\r\n發(fā)送的報(bào)文內(nèi)容為:\r\n”);

52?printf(”\r\n擴(kuò)展ID號ExtId:0x%x?\r\n”,TxMessage.ExtId);

53?CAN_DEBUG_ARRAY(TxMessage.Data,8);

54?}

55?if?(flag==1)

56?{

57?LED_GREEN;

58?printf(”\r\nCAN接收到數(shù)據(jù):\r\n”);

59

60?CAN_DEBUG_ARRAY(RxMessage.Data,8);

61

62?flag=0;

63?}

64?}

65?}

在main函數(shù)里,我們調(diào)用了CAN_Config函數(shù)初始化CAN外設(shè),它包含我們前面解說的GPIO初始化函數(shù)CAN_GPIO_Config、中斷優(yōu)先級設(shè)置函數(shù)CAN_NVIC_Config、工作模式設(shè)置函數(shù)CAN_Mode_Config以及篩選器配置函數(shù)CAN_Filter_Config。

初始化完成后,我們在while循環(huán)里檢測按鍵,當(dāng)按下實(shí)驗(yàn)板的按鍵1時(shí),它就調(diào)用CAN_SetMsg函數(shù)設(shè)置要發(fā)送的報(bào)文,然后調(diào)用CAN_Transmit函數(shù)把該報(bào)文存儲(chǔ)到發(fā)送郵箱,等待CAN外設(shè)把它發(fā)送出去。代碼中并沒有檢測發(fā)送狀態(tài),如果需要,您可以調(diào)用庫函數(shù)CAN_TransmitStatus檢查發(fā)送狀態(tài)。

while循環(huán)中在其它時(shí)間一直檢查flag標(biāo)志,當(dāng)接收到報(bào)文時(shí),我們的中斷服務(wù)函數(shù)會(huì)把它置1,所以我們可以通過它獲知接收狀態(tài),當(dāng)接收到報(bào)文時(shí),我們把它使用宏CAN_DEBUG_ARRAY輸出到串口。

40.6.3?下載驗(yàn)證

下載驗(yàn)證這個(gè)CAN實(shí)驗(yàn)時(shí),我們建議您先使用”CAN—回環(huán)測試”的工程進(jìn)行測試,它的環(huán)境配置比較簡單,只需要一個(gè)實(shí)驗(yàn)板,用USB線使實(shí)驗(yàn)板”USB TO UART“接口跟電腦連接起來,在電腦端打開串口調(diào)試助手,并且把編譯好的該工程下載到實(shí)驗(yàn)板,然后復(fù)位。這時(shí)在串口調(diào)試助手可看到CAN測試的調(diào)試信息,按一下實(shí)驗(yàn)板上的KEY1按鍵,實(shí)驗(yàn)板會(huì)使用回環(huán)模式向自己發(fā)送報(bào)文,在串口調(diào)試助手可以看到相應(yīng)的發(fā)送和接收的信息。

使用回環(huán)測試成功后,如果您有兩個(gè)實(shí)驗(yàn)板,需要按照”硬件設(shè)計(jì)”小節(jié)中的圖例連接兩個(gè)板子的CAN總線,并且一定要接上跳線帽給CAN收發(fā)器供電、把液晶屏拔掉防止干擾。用USB線使實(shí)驗(yàn)板”USB TO UART“接口跟電腦連接起來,在電腦端打開串口調(diào)試助手,然后使用”CAN—雙機(jī)通訊”工程編譯,并給兩個(gè)板子都下載該程序,然后復(fù)位。這時(shí)在串口調(diào)試助手可看到CAN測試的調(diào)試信息,按一下其中一個(gè)實(shí)驗(yàn)板上的KEY1按鍵,另一個(gè)實(shí)驗(yàn)板會(huì)接收到報(bào)文,在串口調(diào)試助手可以看到相應(yīng)的發(fā)送和接收的信息。


40.7 每課一問

8.????在工程中嘗試修改發(fā)送報(bào)文的ID,試驗(yàn)它能不能經(jīng)過篩選器被接收到。

9.????修改篩選器的掩碼配置,使得它能接收ID為”0x 13xx”的報(bào)文。


STM32 CAN通信詳解的評論 (共 條)

分享到微博請遵守國家法律
万全县| 通化县| 象山县| 德安县| 凤城市| 长岛县| 德安县| 宝兴县| 呼图壁县| 福州市| 高尔夫| 固始县| 阜城县| 綦江县| 会理县| 镇巴县| 西乡县| 尚志市| 牙克石市| 金平| 平果县| 宣城市| 高邮市| 凤城市| 鄱阳县| 句容市| 昌平区| 望城县| 保山市| 交口县| 汕头市| 清水县| 册亨县| 台南市| 壤塘县| 德惠市| 石渠县| 茶陵县| 双流县| 和静县| 镇江市|