MCU開發學習記錄19* - CAN學習與實踐(HAL庫) - 定時傳輸、觸發傳輸和請求傳輸(輪詢與中斷實現) -STM32CubeMX

名詞解釋:

CAN:Controller Area Network
ISO:?International Organization for Standardization

?OSI:?Open Systems Interconnection
SOF:?Start Of Frame
EOF:?End Of Frame
??

統一文章結構(數字后加*):

? ? ? ? 第一部分: 闡述外設工作原理;第二部分:芯片參考手冊對應外設的學習;第三部分:使用STM32CubeMX進行外設初始化;第四部分:添加應用代碼;第五部分:附上本篇文章的工程代碼的下載地址。

????????本文將介紹CAN的相關概念以及STM32CubeMX生成CAN的配置函數,并實踐兩個例程:3個MCU之間的CAN通信以及通過定時傳輸、觸發傳輸和請求傳輸實現兩個MCU之間CAN通信(輪詢與中斷實現)。

一、什么是CAN?

1.1??CAN 簡介(MSB->LSB(與SPI、IIC一樣,UART為LSB先行)、串行異步半雙工

1.1.1?CAN 介紹(Controller Area Network

CAN協議是串行、異步、半雙工,適用于多節點、優先級驅動的網絡通信。通過ISO 11898(高速)和ISO 11519-2(低速)成為國際標準。
? ? ? ? · 低速CAN(ISO11519)通信速率10~125Kbps,總線長度可達1000米
? ? ? ? · 高速CAN(ISO11898)通信速率125Kbps~1Mbps,總線長度≤40米

CAN協議物理結構特點:

? ? ? ? · 雙絞線結構(CAN_High和CAN_Low),抗干擾能力強。
? ? ? ? · ?線性總線拓撲?:所有節點并聯在總線上,無主從之分(多主控制)。
? ? ? ? · ?終端電阻?:兩端需接120Ω電阻,消除信號反射。

CAN 控制器根據兩根線上的電位差來判斷總線電平。總線電平分為顯性電平和隱性電平,二者必居其一。發送方通過使總線電平發生變化,將消息發送給接收方。線與機制?:顯性電平優先,實現無沖突仲裁。

1.1.2?CAN 應用

????????CAN 的高性能和可靠性已被認同,并被廣泛地應用于工業自動化、船舶、醫療設備、工業設備等方面。

????????

1.1.3?CAN 總線架構

高速CAN:閉環網絡,CAN-H和CAN-L兩端添加120Ω的終端電阻
低速CAN:開環網絡,CAN_H和CAN_L其中一端添加2.2kΩ的終端電阻

參考正點原子ppr內容:

1.1.4?CAN 的特點

1. 多主控制與動態仲裁
? ? ? ? · 在總線空閑時,所有的單元都可開始發送消息(多主控制)。
? ? ? ? · 當多個節點同時發送時,采用CSMA/CA(載波偵聽多路訪問/沖突避免)?機制,通過ID逐位比較實現優先級仲裁(動態仲裁)。

2. 消息格式與優先級標識
????????
在CAN協議中,所有的消息都以固定的格式發送。。兩個以上的單元同時開始發送消息時,根據標識符(Identifier 以下稱為 ID)決定優先級。ID 并不是表示發送的目的地址,而是表示訪問總線的消息的優先級。兩個以上的單元同時開始發送消息時,對各消息 ID 的每個位進行逐個仲裁比較。仲裁獲勝(被判定為優先級最高)的單元可繼續發送消息,仲裁失利的單元則立刻停止發送而進行接收工作。

3. 系統擴展的靈活性
????????
新增節點時,無需修改現有節點的硬件或軟件,僅需分配唯一ID即可接入總線。例如,在汽車中添加新傳感器時,直接連接即可,無需重新配置網絡。

4. 通信速率可調
????????
同一網絡內所有節點必須設定相同速率(如125 kbps、1 Mbps),否則會引發錯誤。高速率(1 Mbps)適用于短距離、低延遲場景(如發動機控制),而低速率(125 kbps)支持更長總線(如車身控制,總線長度可達數百米)。

5. 遠程數據請求
????????遙控幀(Remote Frame)?
?:接收節點可通過發送遙控幀請求特定ID的數據幀。遙控幀不包含數據段,但包含數據長度碼(DLC),通知發送節點需返回的數據量。

6. 錯誤檢測功能·錯誤通知功能·錯誤恢復功能
? ? ? ? 所有的單元都可以檢測錯誤(錯誤檢測功能)。
????????
檢測出錯誤的單元會立即同時通知其他所有單元(錯誤通知功能)。
????????
正在發送消息的單元一旦檢測出錯誤,會強制結束當前的發送。強制結束發送的單元會不斷反復地重新發送此消息直到成功發送為止(錯誤恢復功能)。

7. 故障節點隔離
????????CAN可以判斷出錯誤的類型是總線上暫時的數據錯誤(如外部噪聲等)還是持續的數據錯誤(如單元內部故障、驅動器故障、斷線等)。由此功能,當總線上發生持續數據錯誤時,可將引起此故障的單元從總線上隔離出去。

8. 節點容量與拓撲限制
?????????理論無限,實際受限?:總線可連接節點數受電氣特性和信號延遲限制。例如:
????????????????· 高速網絡(1 Mbps)通常支持約30個節點,總線長度≤40米。
????????????????· 低速網絡(125 kbps)可支持更多節點(如100個)和更長距離(可達1公里)。

1.2 ?CAN 錯誤

1.2.1 ?CAN 錯誤狀態的種類(3種)

單元始終處于 3 種狀態之一。

1. 主動錯誤狀態
????????· 定義:主動錯誤狀態是系統能夠正常參與總線通信的狀態。
????????· 特征:在此狀態下,單元具備完整的通信能力,可以主動檢測錯誤并采取行動。
????????· 錯誤處理:當單元檢測到錯誤時,會輸出主動錯誤標志,通知其他單元發生了錯誤。
????????· 作用:這是系統運行的正常狀態,適用于錯誤較少、通信穩定的情況。

2.?被動錯誤狀態
????????· 定義:被動錯誤狀態是一種容易引起錯誤的狀態。另外,處于被動錯誤狀態的單元在發送結束后不能馬上再次開始發送。在開始下次發送前,在間隔幀期間內必須插入“延遲傳送”(8 個位的隱性位)。
????????· 特征:單元仍能參與總線通信,但采取了更為保守的策略,避免干擾其他單元的正常通信。
????????· 錯誤處理:在接收數據時,單元不能主動發送錯誤通知;若檢測到錯誤,則輸出被動錯誤標志
????????· 作用:這種狀態適用于錯誤累積較多但尚未嚴重到停止通信的情況,旨在減少對系統的整體影響。

3.?總線關閉態
????????· 定義:總線關閉態是單元完全無法參與總線通信的狀態。
????????· 特征:單元的發送和接收功能都被禁止,徹底與總線隔離。
????????· 錯誤處理:由于通信已被阻斷,此狀態下不再涉及錯誤標志的輸出。
????????· 作用:適用于錯誤極其嚴重、繼續通信可能導致更大問題的極端情況。

1.2.2 ?CAN 錯誤計數值

CAN三種錯誤狀態的轉換又兩個參數給管理:
????????· 發送錯誤計數值 (TEC):記錄單元在發送數據時發生的錯誤次數。
????????· 接收錯誤計數值 (REC):記錄單元在接收數據時發生的錯誤次數。

????????一次數據的接收和發送可能同時滿足多個條件。錯誤計數器在錯誤標志的第一個位出現的時間點上開始計數。

????????

1.2.3 ?CAN 錯誤狀態與錯誤計數值的關系

狀態依靠發送錯誤計數和接收錯誤計數來管理,根據計數值決定進入何種狀態。

????????

????????

1.3 CAN 協議基本概念

????????CAN協議涵蓋了 ISO 規定的 OSI 基本參照模型中的傳輸層、數據鏈路層及物理層。

1.3.1 OSI七層模型

????????

1.3.2 CAN的傳輸層、數據鏈路層及物理層

????????LLC : Logical Link Control (邏輯鏈路控制)
????????MAC : Medium Access Control (媒介訪問控制)

????????數據鏈路層分為MAC子層和 LLC 子層,MAC 子層是 CAN協議的核心部分。數據鏈路層的功能是將物理層 收到的信號組織成有意義的消息,并提供傳送錯誤控制等傳輸控制的流程。具體地說,就是消息的幀化、仲裁、 應答、錯誤的檢測或報告。數據鏈路層的功能通常在CAN控制器的硬件中執行。

????????在物理層定義了信號實際的發送方式、位時序、位的編碼方式及同步的步驟。但具體地說,信號電平、通信 速度、采樣點、驅動器和總線的電氣特性、連接器的形態等均未定義*1。這些必須由用戶根據系統需求自行確定。

????????

二、CAN的物理層

2.1?CAN物理接口與電平標準

2.1.1?CAN物理接口

? ? ? ? · CAN_High(邏輯0:3.5V、邏輯1:2.5V)
????????· CAN_Low(邏輯0:1.5V、邏輯1:2.5V)

2.1.2?CAN電平標準

? ? ? ? · CAN使用差分信號進行數據傳輸,根據CAN_H和CAN_L上的的電位差來判斷總線電平。? ? ? ????????· 總線電平分為顯性電平(邏輯0)和隱性電平(邏輯1),二者必居其一。
????????· 顯性電平具有優先權。發送方通過使總線電平發生變化,將消息發送給接收方。
????????· CAN_High - CAN_Low = 0 | -1.5 時候為隱性電平的,邏輯信號表現為"邏輯1",即高電平。
????????· CAN_High - CAN_Low = 2 | 3 時候為顯性電平的,邏輯信號表現為"邏輯0",即低電平。

????????

????????

2.2 CAN 標準協議及標準規格

2.2.1?ISO制定的CAN協議標準

CAN協議經 ISO標準化后有 ISO11898 標準和 ISO11519-2 標準兩種。

????????· ISO11898 是通信速度為 125kbps-1Mbps 的CAN高速通信標準。 目前,ISO11898 追加新規約后,成為 ISO11898-1 新標準。
????????· ISO11519 是通信速度為 125kbps 以下的CAN低速通信標準。 ISO11519-2 是 ISO11519-1 追加新規約后的版本。?

ISO11898 標準和 ISO11519-2 只對數據鏈路層、物理層進行定義

????????· 傳輸層?:ISO 11898/11519-2未對傳輸層標準化。CAN協議本身通過錯誤檢測與自動重傳實現傳輸可靠性,但具體重傳策略由設備廠商自定義。
????????·?數據鏈路層:(CAN協議核心定義部分?)
????????????????· ISO 11898與ISO 11519-2對數據鏈路層定義完全相同,包括:
????????????????· 幀格式(數據幀、遙控幀等)
????????????????· 非破壞性仲裁機制
????????????????· 錯誤檢測與處理邏輯
????????·?物理層:?(ISO標準差異化部分?)
? ? ? ? ? ? ? ??· ISO 11898(高速CAN):定義1Mbps速率、雙絞線電平特性、終端電阻等。
????????????????· ISO 11519-2(低速CAN):定義125kbps速率、容錯電平特性,適用于車身控制。

2.2.2?ISO11898 和 ISO11519-2 的不同點

????????

????????

2.2.3?CAN的標準規格

????????

2.3?CAN 工作模式與總線仲裁

2.3.0?CAN 兩種傳輸方式

? ? ? ? 廣播式和請求式。

2.3.1?CAN 四種工作模式

1. 正常模式(總線的正常節點)
????????可向總線發送或接收數據。
????????

2. 環回模式(可統計總線的流量)
????????只向總線發送1不能發送0,可從總線接收數據。
????????

3. 靜默模式(自檢)
????????發送的數據直接到輸入(總線可監測數據),不能從總線接收數據。
????????

4. 環回靜默模式(自檢(不影響總線))
????????發送的數據直接到輸入(總線不可監測到數據),不能從總線接收數據。
????????

2.3.1?CAN 總線仲裁

典型CAN的基本原理見圖所示,從圖中可以看出,總線邏輯狀態與驅動器輸入和接收器輸出邏輯是相反的。正常情況下,邏輯高電平為1,邏輯低電平為0,但是CAN總線卻是邏輯高電平為0,稱為顯性,邏輯低電平為1,稱為隱性。所以很多收發器的驅動器輸入端都會內置上拉電阻,在沒有任何輸入時,CAN總線就會表現為隱性(邏輯低電平)。

在總線空閑時,最先開始發送報文的節點獲得發送權。

如果多個節點同時訪問總線,CAN使用非破壞式、逐位仲裁的方式決定哪個節點使用總線:各發送節點從仲裁域(標識符和RTR域)的第1位開始進行仲裁,連續輸出顯性電平(0)最多的節點可以繼續發送。因此標識符數值越低的CAN報文,優先級越高。標識符數值為0的CAN報文,具有最高優先級,因為它輸出的顯性電平最多。

????????

三、 CAN 協議層

3.1?CAN 協議的幀類型與結構(5種)

3.1.1?CAN 協議幀種類

通信是通過以下 5 種類型的幀進行的。
???????????????數據幀;遙控幀;錯誤幀;過載幀;幀間隔

????????數據幀和遙控幀有標準格式(CAN2.0A)和擴展格式(CAN2.0B)兩種格式。標準格式有11個位的標識符(Identifier: 以下稱 ID), 擴展格式有29個位的 ID,各種幀的用途如下。

????????

3.1.2?CAN 協議幀 - 數據幀

數據幀由 7 個段構成。

????????

????????

1.?幀起始(標準、擴展格式相同):
????????
表示數據幀開始的段。1 個位的顯性位。

2.?仲裁段(標準、擴展格式有所不同):
????????
表示該幀優先級的段。ID如下:
????????
標準格式的 ID 有 11 個位。從 ID28 到 ID18 被依次發送。禁止高 7 位都為隱性。(禁止設定:ID=1111111XXXX);
????????擴展格式的 ID 有 29 個位。基本 ID 從 ID28 到 ID18,擴展 ID 由 ID17 到 ID0 表示。基本 ID 和標準格式的 ID 相同。禁止高 7 位都為隱性。(禁止設定:基本 ID=1111111XXXX)

????????RTR 位 (Remote Transmission Request Bit),譯作遠程傳輸請求位,它是用于區分數據幀和遙控幀的,當它為顯性電平時表示數據幀,隱性電平時表示遙控幀。
????????SRR 位 (Substitute Remote Request Bit),只存在于擴展格式,它用于替代標準格式中的 RTR位。由于擴展幀中的 SRR 位為隱性位,RTR 在數據幀為顯性位,所以在兩個 ID 相同的標準格式報文與擴展格式報文中,標準格式的優先級較高。

3.?控制段:
????????
控制段由 6 個位構成,表示數據段的字節數。
????????IDE 位 (Identifier ExtensionBit),譯作標識符擴展位,它是用于區分標準格式與擴展格式,當它為顯性電平時表示標準格式,隱性電平時表示擴展格式
????????r0、r1(保留位) 保留位必須全部以顯性電平發送。但接收方可以接收顯性、隱性及其任意組合的電平。
????????DLC位(數據長度碼) 數據長度碼與數據的字節數的對應關系如表所示。 數據的字節數必須為 0~8 字節。但接收方對DLC = 9~15 的情況并不視為錯誤。

????????

4.?數據段:
????????
數據的內容,數據段可包含 0~8 個字節的數據。從MSB(最高位)開始輸出。

5.?CRC段:檢查幀的傳輸錯誤的段。
???????????????CRC段是檢查幀傳輸錯誤的幀。由 15 個位的 CRC 順序*1和 1 個位的 CRC界定符(用于分隔的位)構成。CRC 部分的計算一般由 CAN 控制器硬件完成,出錯時的處理則由軟件控制最大重發數。在 CRC 校驗碼之后,有一個 DEL界定符,它為隱性位,主要作用是把 CRC 校驗碼與后面的 ACK段間隔起來。

6.?ACK段:表示確認正常接收的段。

????????發送單元的 ACK段 發送單元在 ACK段發送 2 個位的隱性位。
????????接收單元的 ACK段 接收到正確消息的單元在ACK槽(ACK Slot)發送顯性位,通知發送單元正常接收結束。這稱作“發送 ACK”或者“返回 ACK”。

7.?幀結束:表示數據幀結束的段。
????????幀結束是表示該該幀的結束的段。由 7 個位的隱性位構成。

3.1.3?CAN 協議幀 - 遙控幀

接收單元向發送單元請求發送數據所用的幀。遙控幀由 6 個段組成。遙控幀沒有數據幀的數據段。

????????

1. 幀起始:表示幀開始的段。
2. 仲裁段:表示該幀優先級的段。可請求具有相同 ID 的數據幀。
3. 控制段:表示數據的字節數及保留位的段。
4. CRC段:檢查幀的傳輸錯誤的段。
5. ACK段:表示確認正常接收的段。
6. 幀結束:表示遙控幀結束的段。

3.1.4?CAN 協議幀 - 數據幀與遙控幀補充

1.?數據幀和遙控幀的不同
? ? ? ? ·?
遙控幀的 RTR位為隱性位,沒有數據段。
? ? ? ? · 沒有數據段的數據幀和遙控幀可通過 RTR位區別開來。

2. 遙控幀沒有數據段,數據長度碼該如何表示?
????????遙控幀的數據長度碼以所請求數據幀的數據長度碼表示。

3.?沒有數據段的數據幀有何用途?
????????可用于各單元的定期連接確認/應答、或仲裁段本身帶有實質性信息的情況下。

3.1.5?CAN 協議幀 - 錯誤幀

????????用于在接收和發送消息時檢測出錯誤通知錯誤的幀。錯誤幀由錯誤標志和錯誤界定符構成。

1. 錯誤標志
????????錯誤標志包括主動錯誤標志和被動錯誤標志兩種。
????????主動錯誤標志:6 個位的顯性位。(處于主動錯誤狀態的單元檢測出錯誤時輸出的錯誤標志。)
????????被動錯誤標志:6 個位的隱性位。(處于被動錯誤狀態的單元檢測出錯誤時輸出的錯誤標志。)

2. 錯誤界定符
????????錯誤界定符由 8 個位的隱性位構成。

????????錯誤標志之后還有0~6個錯誤標志重疊部分:處于主動錯誤狀態的節點檢測到錯誤時會發送主動錯誤標志,6個連續顯性位會違反位填充規則和位場的固定形式,進而造成其它節點也檢測到錯誤并發送錯誤標志。所有節點所發送的顯性序列疊加組成錯誤標志重疊部分,錯誤標志重疊部分的長度在6-12個顯性位之間。

????????

3.1.6?CAN 協議幀 - 過載幀

過載幀是用于接收單元通知其尚未完成接收準備的幀。過載幀由過載標志和過載界定符構成。

過載幀是接收節點向總線上其它節點報告自身接收能力達到極限的幀,可以理解為:接收節點Node_A接收報文的能力達到極限了,于是Node_A就會發出過載幀來告訴總線上的其它節點(包括發送節點),我接收節點Node_A已經沒有能力處理你們發來的報文了。過載幀由過載標志和過載界定符構成。

· 過載標志
??6 個位的顯性位。
??過載標志的構成與主動錯誤標志的構成相同。
· ?過載界定符
??8 個位的隱性位。
??過載界定符的構成與錯誤界定符的構成相同。

????????

3.1.7?CAN 協議幀 - 幀間隔

幀間隔是用于分隔數據幀和遙控幀的幀。數據幀和遙控幀可通過插入幀間隔將本幀與前面的任何幀(數據幀、遙控幀、錯誤幀、過載幀)分開。

過載幀和錯誤幀前不能插入幀間隔。

1. 間隔:
????????3 個位的隱性位。

2. 總線空閑:
????????
隱性電平,無長度限制(0 亦可)。 本狀態下,可視為總線空閑,要發送的單元可開始訪問總線。

3. 延遲傳送(發送暫時停止):
???????? 8 個位的隱性位。 只在處于被動錯誤狀態的單元剛發送一個消息后的幀間隔中包含的段。

????????

3.2 CAN 協議?- 優先級

3.2.1?優先級1 - 先占先得

在總線空閑態,最先開始發送消息的單元獲得發送權。

1. 若當前已經有設備正在操作總線發送數據幀/遙控幀,則其他任何設備不能再同時發送數據幀/遙控幀(可以發送錯誤幀/過載幀破壞當前數據)

2. 任何設備檢測到連續11個隱性電平,即認為總線空閑,只有在總線空閑時,設備才能發送數據幀/遙控幀

3. 一旦有設備正在發送數據幀/遙控幀,總線就會變為活躍狀態,必然不會出現連續11個隱性電平,其他設備自然也不會破壞當前發送

4. 若總線活躍狀態其他設備有發送需求,則需要等待總線變為空閑,才能執行發送需求

3.2.1?優先級1 - 非破壞性仲裁

多個單元同時開始發送時,各發送單元從仲裁段的第一位開始進行仲裁。連續輸出顯性電平最多的單元可繼續發送。

若多個設備的發送需求同時到來或因等待而同時到來,則CAN總線協議會根據ID號(仲裁段)進行非破壞性仲裁,ID號小的(優先級高)取到總線控制權,ID號大的(優先級低)仲裁失利后將轉入接收狀態,等待下一次總線空閑時再嘗試

發送實現非破壞性仲裁需要兩個要求:
????????線與特性:總線上任何一個設備發送顯性電平0時,總線就會呈現顯性電平0狀態,只有當所有設備都發送隱性電平1時,總線才呈現隱性電平1狀態,即:0&X&X=0, 1&1&1=1
????????回讀機制:每個設備發出一個數據位后,都會讀回總線當前的電平狀態,以確認自己發出的電平是否被真實地發送出去了,根據線與特性,發出0讀回必然是0,發出1讀回不一定是1

1.?數據幀和遙控幀的優先級

????????具有相同 ID 的數據幀和遙控幀在總線上競爭時,仲裁段的最后一位(RTR)為顯性位的數據幀具有優先權,可繼續發送。

????????

2.?標準格式和擴展格式的優先級

????????標準格式 ID 與具有相同 ID 的遙控幀或者擴展格式的數據幀在總線上競爭時,標準格式的 RTR位為顯性位 的具有優先權,可繼續發送。

????????

3.3 CAN 位填充與錯誤檢測

3.3.1?CAN 位填充

????????位填充是為防止突發錯誤而設定的功能。當同樣的電平持續 5 位時則添加一個位的反型數據。

1. 發送單元的工作
????????在發送數據幀和遙控幀時,SOF~CRC段間的數據,相同電平如果持續 5 位,在下一個位(第 6 個位)則要插入 1 位與前 5 位反型的電平。

2. 接收單元的工作
????????在接收數據幀和遙控幀時,SOF~CRC段間的數據,相同電平如果持續 5 位,需要刪除下一個位(第 6 個位)再接收。如果這個第 6 個位的電平與前 5 位相同,將被視為錯誤并發送錯誤幀。

????????

????????

3.3.2?CAN 錯誤檢測(五種)- 破壞當前數據幀的數據

????????位錯誤(發送時的回讀機制)、填充錯誤、CRC錯誤、格式錯誤、ACK錯誤

1. 位錯誤
? ? ? ? · 位錯誤由向總線上輸出數據幀、遙控幀、錯誤幀、過載幀的單元和輸出 ACK 的單元、輸出錯誤的單元來 檢測。
???????? ? ? ? · 在仲裁段輸出隱性電平,但檢測出顯性電平時,將被視為仲裁失利,而不是位錯誤。
???????? ? ? ? · 在仲裁段作為填充位輸出隱性電平時,但檢測出顯性電平時,將不視為位錯誤,而是填充錯誤。
???????? ? ? ? · 發送單元在 ACK段輸出隱性電平,但檢測到顯性電平時,將被判斷為其它單元的ACK應答,而非位錯誤。
???????? ? ? ? · 輸出被動錯誤標志(6 個位隱性位)但檢測出顯性電平時,將遵從錯誤標志的結束條件,等待檢測出連續相同 6 個位的值(顯性或隱性),并不視為位錯誤。

2. 格式錯誤
???????? ? ? ? · 即使接收單元檢測出EOF(7 個位的隱性位)的最后一位(第 8 個位)為顯性電平,也不視為格式錯誤。
???????? ? ? ? · 即使接收單元檢測出數據長度碼(DLC)中 9~15 的值時,也不視為格式錯誤。

????????

3.3.3?CAN 錯誤幀的輸出

????????檢測出滿足錯誤條件的單元輸出錯誤標志通報錯誤。
????????發送單元發送完錯誤幀后,將再次發送數據幀或遙控幀。

????????

3.4 CAN 位時序與同步

3.4.1?CAN 位時序介紹

????????CAN總線以“位同步”機制,實現對電平的正確采樣。位數據都由四段組成:同步段(SS)、傳播時間段(PTS)、相位緩沖段1(PBS1)和相位緩沖段2(PBS2),每段又由多個位時序Tq組成。
????????采樣點是指讀取總線電平,并將讀到的電平作為位值的點。

????????Time Quantum(以下稱為 Tq)的最小時間單位構成。

????????

3.4.2?CAN 位時序段介紹

· SS 段(SYNC SEG):
同步段,比如當總線上出現幀起始信號(SOF)時,其它節點上的控制器根據總線上的這個下降沿,對自己的位時序進行調整,把該下降沿包含到 SS 段內,這樣根據起始幀來進行同步的方式稱為硬同步。其中 SS 段的大小為 1Tq。總線上信號的跳變沿被包含在節點的 SS 段的范圍之內,則表示節點與總線的時序是同步的,采樣點采集到的總線電平即可被確定為該位的電平。

· PTS 段(PROP SEG):
傳播時間段,這個時間段是用于補償網絡的物理延時時間,包括發送單元的輸出延遲、總線上信號的傳播延遲、接收單元的輸入延遲,這個段的時間為以上各延遲時間的和的兩倍。大小可以為 1~8Tq。

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

· PBS2 段(PHASE SEG2):
另一個相位緩沖段,也是用來補償邊沿階段誤差的,它的時間長度在重新同步時可以縮短。 PBS2 段的初始大小可以為 2~8Tq。(對于PBS段而言,當信號邊沿不能被包含于 SS 段中時,可在此段進行補償,以及可以吸收時鐘誤差)

· SJW (reSynchronization Jump Width):重新同步補償寬度,即在重新同步的時候,PBS1 和 PBS2 段的允許加長或縮短的時間長度,SJW 加大后允許誤差加大,但通信速度下降。SJW 為補償此誤差的最大值(即每一次誤差補償都不能超過這個值,1~4Tq)。

?

3.4.3?CAN 位時序 - 波特率計算

· 波特率 = 1/一個數據位的時長 = 1/(T_SS + T_PTS + T_PBS1 + T_PBS2)

· 例如:T_SS = 1Tq、 T_PTS = 3Tq、T_PBS1 = 3Tq、T_PBS2 = 3Tq、Tq = 0.5us
????????波特率 =1/(0.5us +1.5us + 1.5us + 1.5us)=200kbps

????????

3.4.4?CAN 同步 -?取得同步方法

CAN協議的通信方法為 NRZ(Non-Return to Zero)方式。各個位的開頭或者結尾都沒有附加同步信號。發送單元以與位時序同步的方式開始發送數據。另外,接收單元根據總線上電平的變化進行同步并進行接收工作。

但是,發送單元和接收單元存在的時鐘頻率誤差及傳輸路徑上的(電纜、驅動器等)相位延遲會引起同步偏差。因此接收單元通過硬件同步或者再同步的方法調整時序進行接收。

3.4.5?CAN 同步 -?硬同步

節點通過CAN總線發送數據,一開始發送幀起始信號。總線上其他節點會檢測幀起始信號在不在位數據的SS段內,判斷內部時序與總線是否同步。

假如不在SS段內,這種情況下,采樣點獲得的電平狀態是不正確的。所以,節點會使用硬件同步方式調整, 把自己的SS段平移到檢測到邊沿的地方,獲得同步,同步情況下,采樣點獲得的電平狀態才是正確的。

即每個設備都有一個位時序計時周期,當某個設備(發送方)率先發送報文,其他所有設備(接收方)收到SOF的下降沿時,接收方會將自己的位時序計時周期撥到SS段位置。

????????

????????

3.4.6?CAN 同步 - 再同步

????????· 再同步利用普通數據位的邊沿信號(幀起始信號是特殊的邊沿信號)進行同步。
????????· 再同步的方式分為兩種情況:超前和滯后,即邊沿信號與SS段的相對位置。
????????· 再同步時,PSB1和PSB2中增加或者減少的時間被稱為“再同步補償寬度(SJW)”,其范圍:1~4 Tq。
????????· ???????限定了SJW值后,再同步時,不能增加限定長度的SJW值。SJW值較大時,吸收誤差能力更強,但是通訊速度會下降。

????????

????????

四、高速CAN接口芯片 -?SIT1042AQ

4.1 芯片引腳

4.1.1?芯片引腳分布圖

????????

4.1.2 芯片引腳定義

????????

4.2 芯片內部框圖

????????

五、CAN硬件外設

5.1 CAN 外設介紹

5.1.1?CAN 外設簡介

????????支持 CAN 協議 2.0A 2.0B 主動模式
????????波特率最高達 1Mbps
????????支持時間觸發通信
????????具有 3 個發送郵箱
????????具有 3 級深度的 2 個接收 FIFO
????????可變的過濾器組(最多 28 個)
????????時間觸發通信、自動離線恢復、自動喚醒、禁止自動重傳、接收FIFO溢出處理方式可配置、? 發送優先級可配置、雙CAN模式

5.1.2?CAN 硬件框圖

1. CAN內核
????????包含各種控制/狀態/配置寄存器,可以配置模式、波特率等
2. 發送郵箱
????????用來緩存待發送的報文,最多可以緩存3個報文
3. 接收FIFO
????????緩存接收到的有效報文
4.接收過濾器
????????篩選有效報文

????????

????????

5.2 CAN 外設工作模式

5.2.1?CAN 外設低功耗

1. ???????初始化模式:用于配置CAN外設,禁止報文的接收和發送
2. 正常模式:配置CAN外設后進入正常模式,以便正常接收和發送報文
3.?睡眠模式:低功耗,CAN外設時鐘停止,可使用軟件喚醒或者硬件自動喚醒
4.?AWUM:置1,自動喚醒,一旦檢測到CAN總線活動,硬件就自動清零SLEEP,喚醒CAN外設;置0,手動喚醒,軟件清零SLEEP,喚醒CAN外設

CAN 主狀態寄存器 - CAN_MSR

CAN_MSR.INAK:初始化確認
????????硬件置 1,用于向軟件指示 CAN 硬件此時處于初始化模式。此位可確認軟件的初始化請求(CAN_MCR 寄存器的
INRQ 位置 1)。
????????CAN 硬件退出初始化模式(以在 CAN 總線上進行同步)時,此位由硬件清零。
CAN_MSR.SLAK:睡眠確認
????????此位由硬件置 1
,用于向軟件指示 CAN 硬件此時處于睡眠模式。此位可確認軟件的睡眠模式請求(CAN_MCR 寄存器的 SLEEP 位置 1)。
????????CAN
硬件退出睡眠模式(以在 CAN 總線上進行同步)時,此位由硬件清零。

CAN 主控制寄存器 -?CAN_MCR

CAN_MCR.INRQ:初始化請求
???????????????此位由軟件置
1,用于請求 CAN 硬件進入睡眠模式。此位由軟件清零時,將退出睡眠模式。???????
CAN_MCR.SLEEP:睡眠模式請求
????????軟件通過將此位置
1 來請求 CAN 硬件進入初始化模式。軟件通過將此位清零,來將硬件切換到正常模式。

1. ACK = 硬件通過將 CAN_MSR 寄存器的 INAK SLAK 位置 1 來確認請求的等待狀態
2. SYNC = bxCAN 等待
CAN 總線變為空閑(即在 CANRX 上監測到連續 11 個隱性位)的狀態

????????

5.2.2?CAN 外設物理接口模式

1.?CAN_BTR 寄存器的 SILM 位置 1,將 bxCAN 置于靜默模式。
????????

2.?CAN_BTR 寄存器的 LBKM 位置 1,將 bxCAN 置于環回模式。
????????

3.?CAN_BTR 寄存器的 LBKM SILM 位置 1,將環回模式和靜默模式組合起來。
????????

5.2.3?CAN 外設發送過程

CAN 發送狀態寄存器 -?CAN_TSR
CAN 發送郵箱標識符寄存器 -?CAN_TIxR

CAN_TSR.RQCPx郵箱 x 請求完成
????????最后一個請求(發送或中止)執行完畢時,由硬件置 1。
? ? ? ? 軟件通過寫入“1
”清零,或是在發生發送請求(CAN_TI0R 寄存器的 TXRQ0 位置 1)時 由硬件清零。
CAN_TSR.TXOKx:郵箱 x 發送成功
????????每次發送嘗試后,硬件都將更新此位。
????????0:上一次發送失敗
????????1:上一次發送成功

CAN_TSR.TMEx:發送郵箱 x 空
????????當郵箱
0 沒有掛起的發送請求時,此位由硬件置 1。
CAN_TSR.ABRQx:郵箱 x 中止請求
????????由軟件置 1,用于中止相應郵箱的發送請求。
????????郵箱變為空后,此位由硬件清零。
????????郵箱未掛起等待發送時,將此位置 1 沒有任何作用。

CAN_TIxR.TXRQ發送郵箱請求

CAN_MCR.NART:禁止自動重發送
????????0:
CAN 硬件將自動重發送消息,直到根據 CAN 標準消息發送成功。
????????1:無論發送結果如何(成功、錯誤或仲裁丟失),消息均只發送一次。

????????

5.2.4?CAN 外設接收過程

CAN 接收 FIFO x?寄存器 -?CAN_RFxR

CAN_RFxR.FMPx[1:0]:FIFO x 消息掛起
????????硬件每向 FIFO
存儲一條新消息,FMP 即會增加。軟件每次通過將 RFOM0 位置 1 來釋放輸出郵箱,FMP 即會減小。
CAN_RFxR.FOVRx:FIFO x 上溢
? ? ? ??FIFO 填滿時,如果接收到新消息并且通過篩選器,此位將由硬件置 1。
CAN_RFxR.RFOMx:釋放 FIFO x?輸出郵箱
????????由軟件置 1
,用于釋放 FIFO 的輸出郵箱。FIFO 中至少有一條消息掛起時,才能釋放輸出郵箱。FIFO 為空時,將此位置 1 沒有任何作用。如果 FIFO 中至少有兩條消息掛起,軟件必須釋放輸出郵箱,才能訪問下一條消息。輸出郵箱釋放后,此位由硬件清零。

????????

5.2.5?CAN 外設發送和接收配置位

1.?NART:
????????置1,關閉自動重傳,CAN報文只被發送1次,不管發送的結果如何(成功、出錯或仲裁丟失);?
????????置0, 自動重傳, CAN硬件在發送報文失敗時會一直自動重傳直到發送成功
2.?TXFP:
????????置1,優先級由發送請求的順序來決定,先請求的先發送;
????????置0,優先級由報文標識符來決定,標識符值小的先發送(標識符值相等時,郵箱號小的報文先發送)
3.?RFLM:
????????置1,接收FIFO鎖定,FIFO溢出時,新收到的報文會被丟棄;
????????置0,禁用FIFO鎖定,FIFO溢出時,FIFO中最后收到的報文被新報文覆蓋

5.3 CAN 外設過濾器

1. FSCx: 位寬設置
????????置0,16位;置1,32位
2.?FBMx:模式設置
????????置0,屏蔽模式;置1,列表模式
3.?FFAx:關聯設置
????????置0,FIFO 0; 置1,FIFO 1
4.?FACTx:激活設置
????????置0,禁用;置1,啟用

????????

????????

5.4 CAN 外設位時間計算

????????波特率 = APB1時鐘頻率 / 分頻系數 / 一位的Tq數量
? ? ? ? ? ? ? ? ? ? = 36MHz / (BRP[9:0]+1) / (1 + (TS1[3:0]+1) + (TS2[2:0]+1))

????????

5.5?CAN 外設中斷

CAN外設占用4個專用的中斷向量:

1.?發送中斷可由以下事件產生:
? ? ? ? · 發送郵箱 0 變為空,CAN_TSR
寄存器的 RQCP0 位置 1。
????????· 發送郵箱 1 變為空,CAN_TSR 寄存器的
RQCP1 位置 1

????????· 發送郵箱 2 變為空,CAN_TSR 寄存器的 RQCP2 位置 1

2.?FIFO 0 中斷可由以下事件產生:
? ? ? ? · 接收到新消息,CAN_RF0R 寄存器的 FMP0 位不是“
00”。
? ? ? ? · FIFO0 滿,CAN_RF0R
寄存器的 FULL0 位置 1。
? ? ? ? · FIFO0 上溢,CAN_RF0R
寄存器的 FOVR0 位置 1

3. FIFO 1 中斷可由以下事件產生:

? ? ? ? · 接收到新消息,CAN_RF1R 寄存器的 FMP1 位不是“00”。
? ? ? ? · ???????FIFO1 滿,CAN_RF1R
寄存器的 FULL1 位置 1。
? ? ? ? · ???????FIFO1 上溢,CAN_RF1R
寄存器的 FOVR1 位置 1
4.?錯誤和狀態改變中斷可由以下事件產生:

? ? ? ? · 錯誤狀況,有關錯誤狀況的更多詳細信息,請參見 CAN 錯誤狀態寄存器 (CAN_ESR)。
? ? ? ? · 喚醒狀況,CAN Rx 信號上監測到 SOF。
? ? ? ? · 進入睡眠模式

????????

5.6?CAN 外設錯誤狀態切換

????????TEC和REC根據錯誤的情況增加或減少
????????ABOM:置1,開啟離線自動恢復,進入離線狀態后,就自動開啟恢復過程;置0,關閉離線自動恢復,軟件必須先請求進入然后再退出初始化模式,隨后恢復過程才被開啟

????????

六、基于HAL庫配置CAN外設

6.1 基于STM32CubeMX配置CAN外設

6.1.1?STM32CubeMX配置CAN外設

1. TTCM:時間觸發通信模式 (Time triggered communication mode)
????????0:禁止時間觸發通信模式。
????????1:使能時間觸發通信模式。
????????
在時間觸發通信模式下,CAN硬件的內部計數器被激活。這個計數器的主要功能是為接收和發送的郵箱(mailbox)生成時間戳值,用于記錄通信事件的具體時間。這些時間戳值分別存儲在以下兩個寄存器中:
????????????????CAN_RDTxR(接收數據時間戳寄存器):記錄接收到數據幀的時間。
????????????????CAN_TDTxR(發送數據時間戳寄存器):記錄發送數據幀的時間。

2. ABOM:自動的總線關閉管理 (Automatic bus-off management)
???????????????此位控制 CAN 硬件在退出總線關閉狀態時的行為。
????????0:在軟件發出請求后,一旦監測到 128
次連續 11 個隱性位,并且軟件將 CAN_MCR 寄存 器的 INRQ 位先置 1 再清零,即退出總線關閉狀態。
????????1:一旦監測到 128
次連續 11 個隱性位,即通過硬件自動退出總線關閉狀態。

3. AWUM:自動喚醒模式 (Automatic wakeup mode)
????????此位控制 CAN 硬件在睡眠模式下接收到消息時的行為。
????????0:在軟件通過將 CAN_MCR
寄存器的 SLEEP 位清零發出請求后,退出睡眠模式。
????????1:一旦監測到 CAN
消息,即通過硬件自動退出睡眠模式。 CAN_MCR 寄存器的 SLEEP 位和 CAN_MCR 寄存器的 SLAK 位由硬件清零

4. NART禁止自動重發送 (No automatic retransmission)
????????0:CAN
硬件將自動重發送消息,直到根據 CAN 標準消息發送成功。
????????1:無論發送結果如何(成功、錯誤或仲裁丟失),消息均只發送一次。

5. RFLM接收 FIFO 鎖定模式 (Receive FIFO locked mode)
????????0:接收 FIFO
上溢后不鎖定。接收 FIFO 裝滿后,下一條傳入消息將覆蓋前一條消息。
????????1:接收 FIFO
上溢后鎖定。接收 FIFO 裝滿后,下一條傳入消息將被丟棄。

6. TXFP發送 FIFO 優先級 (Transmit FIFO priority)
????????此位用于控制在幾個郵箱同時掛起時的發送順序。
????????0:優先級由消息標識符確定
????????1:優先級由請求順序(時間順序)確定

????????

????????

6.1.2 編寫CAN 輸入過濾器

HAL_StatusTypeDef MyCAN_SetFilters(void)
{CAN_FilterTypeDef canFilter;canFilter.FilterBank = 0;canFilter.FilterMode = CAN_FILTERMODE_IDMASK;canFilter.FilterScale = CAN_FILTERSCALE_32BIT;canFilter.FilterIdHigh = 0x0000;canFilter.FilterIdLow = 0x0000;canFilter.FilterMaskIdHigh = 0x0000;canFilter.FilterMaskIdLow = 0x0000;canFilter.FilterFIFOAssignment = CAN_FILTER_FIFO0;canFilter.FilterActivation = CAN_FILTER_ENABLE;HAL_StatusTypeDef result = HAL_CAN_ConfigFilter(&hcan1, &canFilter);return result;
}

6.2 CAN外設實踐1 - 3個節點通信

6.2.1?實踐1 - 回環自測 - 輪詢

????????

????????

/** mycan.c** Created: 2025-05-11 15:02:23* Author: user*  function:  CAN通信相關驅動函數 - 自用**/#include "mycan.h"
#include "can.h"
#include "bsp_lcd_fsmc.h"
#include "stdio.h"extern CAN_HandleTypeDef hcan1;HAL_StatusTypeDef MyCAN_SetFilters(void)
{CAN_FilterTypeDef canFilter;canFilter.FilterBank = 0;canFilter.FilterMode = CAN_FILTERMODE_IDMASK;canFilter.FilterScale = CAN_FILTERSCALE_32BIT;canFilter.FilterIdHigh = 0x0000;canFilter.FilterIdLow = 0x0000;canFilter.FilterMaskIdHigh = 0x0000;canFilter.FilterMaskIdLow = 0x0000;canFilter.FilterFIFOAssignment = CAN_FILTER_FIFO0;canFilter.FilterActivation = CAN_FILTER_ENABLE;HAL_StatusTypeDef result = HAL_CAN_ConfigFilter(&hcan1, &canFilter);return result;
}uint8_t MyCAN_ReceiveFlag(void)
{if (HAL_CAN_GetRxFifoFillLevel(&hcan1, CAN_RX_FIFO0) > 0){return 1;}return 0;
}void MyCAN_Transmit(uint32_t ID, uint8_t Length, uint8_t *Data, uint8_t frameType)
{CAN_TxHeaderTypeDef TxMessage;TxMessage.StdId = ID;TxMessage.ExtId = ID;TxMessage.IDE = frameType;TxMessage.RTR = CAN_RTR_DATA;TxMessage.DLC = Length;TxMessage.TransmitGlobalTime = DISABLE;uint8_t TxData[Length];for (int i = 0; i < Length; i++){TxData[i] = Data[i];}uint32_t TxMailbox;uint32_t Timeout = 0;uint8_t tempStr[30];while (HAL_CAN_GetTxMailboxesFreeLevel(&hcan1) < 1){Timeout++;if (Timeout > 100000){break;}}if (HAL_CAN_AddTxMessage(&hcan1, &TxMessage, TxData, &TxMailbox) != HAL_OK){lcd_show_string(10, 30, 240, 16, 16, "Send to mailbox error", RED);return;}sprintf((char *)tempStr, "Send MsgID = %4X", ID);lcd_show_string(10, 30, 240, 16, 16, (char *)tempStr, RED);
}void MyCAN_Receive(uint32_t *ID, uint8_t *Length, uint8_t *Data)
{uint8_t tempStr[30];if (HAL_CAN_GetRxFifoFillLevel(&hcan1, CAN_RX_FIFO0) != 1){lcd_show_string(10, 50, 240, 16, 16, "Send to mailbox error", RED);return;}CAN_RxHeaderTypeDef RxMessage;if (HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &RxMessage, Data) == HAL_OK){if (RxMessage.IDE == CAN_ID_STD){*ID = RxMessage.StdId;}else{*ID = RxMessage.ExtId;}sprintf((char *)tempStr, "Rece MsgID = %4X", *ID);lcd_show_string(10, 50, 240, 16, 16, (char *)tempStr, RED);*Length = RxMessage.DLC;}
}

6.2.2?實踐1 - 回環自測 - 中斷

????????
????????
????????

6.2.3 實踐1 - 3個節點通信

????????

6.3?CAN外設實踐2 - 2個節點之間(定時傳輸、觸發傳輸和請求傳輸)

6.3.1 實踐2 - 發送方

// 全局變量
uint32_t TxID1 = 0x550;
uint32_t TxID2 = 0x560;
uint32_t TxID3 = 0x570;
uint32_t TxID4 = 0x580;
uint8_t TxLength = 4;
uint8_t TxData[8] = {0x11, 0x22, 0x33, 0x44};uint32_t RxID;
uint8_t RxLength;
uint8_t RxData[8];extern CAN_HandleTypeDef hcan1;
extern uint8_t can_fifo0_status;
extern uint8_t TimingFlag;// CAN外設、CAN中斷、定時器中斷使能
MyCAN_SetFilters();
HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);
HAL_CAN_Start(&hcan1);
HAL_TIM_Base_Start_IT(&htim6);// 應用代碼
// 定時發送
if (TimingFlag == 1)
{TimingFlag = 0;TxData[0]++;TxData[1]++;TxData[2]++;TxData[3]++;MyCAN_Transmit(TxID1, TxLength, TxData, CAN_ID_STD);sprintf((char *)tempstr, "1. TxData = %2X %2X %2X %2X", TxData[0], TxData[1], TxData[2], TxData[3]);lcd_show_string(10, 90, 240, 16, 16, (char *)tempstr, RED);
}// 觸發發送
key_val = key_scan(0);
if (key_val == 1)
{TimingFlag = 0;TxData[0]++;TxData[1]++;TxData[2]++;TxData[3]++;MyCAN_Transmit(TxID2, TxLength, TxData, CAN_ID_STD);sprintf((char *)tempstr, "2. TxData = %2X %2X %2X %2X", TxData[0], TxData[1], TxData[2], TxData[3]);lcd_show_string(10, 110, 240, 16, 16, (char *)tempstr, RED);
}// 請求發送
if (can_fifo0_status == 1)
{if (RxID == 0x666){RequestFlag = 1;}can_fifo0_status = 0;if (RxID == 0x777){RequestFlag = 2;}can_fifo0_status = 0;
}
if (RequestFlag == 1)
{RequestFlag = 0;TxData[0]++;TxData[1]++;TxData[2]++;TxData[3]++;MyCAN_Transmit(TxID3, TxLength, TxData, CAN_ID_STD);sprintf((char *)tempstr, "3.1 TxData = %2X %2X %2X %2X", TxData[0], TxData[1], TxData[2], TxData[3]);lcd_show_string(10, 130, 240, 16, 16, (char *)tempstr, RED);
}
if (RequestFlag == 2)
{RequestFlag = 0;TxData[0]++;TxData[1]++;TxData[2]++;TxData[3]++;MyCAN_Transmit(TxID4, TxLength, TxData, CAN_ID_STD);sprintf((char *)tempstr, "3.2 TxData = %2X %2X %2X %2X", TxData[0], TxData[1], TxData[2], TxData[3]);lcd_show_string(10, 130, 240, 16, 16, (char *)tempstr, RED);
}

6.3.2 實踐2 - 接收方

原理差不多,直接參考江科大程序如下:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Key.h"
#include "MyCAN.h"uint8_t KeyNum;CanTxMsg TxMsg_Request_Remote = {.StdId = 0x666,.ExtId = 0x00000000,.IDE = CAN_Id_Standard,.RTR = CAN_RTR_Remote,.DLC = 0,.Data = {0x00}
};CanTxMsg TxMsg_Request_Data = {.StdId = 0x777,.ExtId = 0x00000000,.IDE = CAN_Id_Standard,.RTR = CAN_RTR_Data,.DLC = 0,.Data = {0x00}
};CanRxMsg RxMsg;int main(void)
{OLED_Init();Key_Init();MyCAN_Init();OLED_ShowString(1, 1, "Rx");OLED_ShowString(2, 1, "Tim:");OLED_ShowString(3, 1, "Tri:");OLED_ShowString(4, 1, "Req:");while (1){/*請求部分*/KeyNum = Key_GetNum();if (KeyNum == 1){MyCAN_Transmit(&TxMsg_Request_Remote);}if (KeyNum == 2){MyCAN_Transmit(&TxMsg_Request_Data);}/*接收部分*/if (MyCAN_ReceiveFlag()){MyCAN_Receive(&RxMsg);if (RxMsg.RTR == CAN_RTR_Data){/*收到定時數據幀*/if (RxMsg.StdId == 0x550 && RxMsg.IDE == CAN_Id_Standard){OLED_ShowHexNum(2, 5, RxMsg.Data[0], 2);OLED_ShowHexNum(2, 8, RxMsg.Data[1], 2);OLED_ShowHexNum(2, 11, RxMsg.Data[2], 2);OLED_ShowHexNum(2, 14, RxMsg.Data[3], 2);}/*收到觸發數據幀*/if (RxMsg.StdId == 0x560 && RxMsg.IDE == CAN_Id_Standard){OLED_ShowHexNum(3, 5, RxMsg.Data[0], 2);OLED_ShowHexNum(3, 8, RxMsg.Data[1], 2);OLED_ShowHexNum(3, 11, RxMsg.Data[2], 2);OLED_ShowHexNum(3, 14, RxMsg.Data[3], 2);}/*收到請求數據幀*/if (RxMsg.StdId == 0x570 && RxMsg.IDE == CAN_Id_Standard){OLED_ShowHexNum(4, 5, RxMsg.Data[0], 2);OLED_ShowHexNum(4, 8, RxMsg.Data[1], 2);OLED_ShowHexNum(4, 11, RxMsg.Data[2], 2);OLED_ShowHexNum(4, 14, RxMsg.Data[3], 2);}if (RxMsg.StdId == 0x580 && RxMsg.IDE == CAN_Id_Standard){OLED_ShowHexNum(4, 5, RxMsg.Data[0], 2);OLED_ShowHexNum(4, 8, RxMsg.Data[1], 2);OLED_ShowHexNum(4, 11, RxMsg.Data[2], 2);OLED_ShowHexNum(4, 14, RxMsg.Data[3], 2);}}}}
}

6.3.3 實踐2 - 實驗效果

七、本文的工程文件下載鏈接

工程Github下載鏈接:https://github.com/chipdynkid/MCU-DL-STM32
(國內)工程Gitcode下載鏈接:https://gitcode.com/chipdynkid/MCU-DL-STM32

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/82076.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/82076.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/82076.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

LEED認證是什么?LEED認證難嗎?LEED認證需要準備的資料

LEED&#xff08;Leadership in Energy and Environmental Design&#xff0c;能源與環境設計先鋒&#xff09;是由美國綠色建筑委員會&#xff08;USGBC&#xff09;開發的一套全球廣泛認可的綠色建筑認證體系&#xff0c;用于評估建筑在設計、施工、運營和維護中的可持續性表…

【ffmpeg】ffprobe基本用法

ffprobe 是 FFmpeg 工具集中的一個強大命令行工具&#xff0c;主要用于分析多媒體文件&#xff08;如視頻、音頻等&#xff09;的格式和內容信息。它可以提取文件的元數據、編解碼器信息、流詳情、幀信息等&#xff0c;而無需對文件進行轉碼或修改。 基本用法 ffprobe [選項] …

暗黑科技感風格智慧工地監管系統

智慧工地監管系統作為這場變革中的關鍵力量&#xff0c;正逐漸改變著傳統工地的管理模式。今天&#xff0c;就帶大家一同領略一款用Axure精心打造的暗黑科技感風格智慧工地監管系統原型&#xff0c;感受科技與建筑碰撞出的奇妙火花。 這款智慧工地監管系統原型采用了極具魅力的…

【軟件安裝】Windows操作系統中安裝mongodb數據庫和mongo-shell工具

這篇文章&#xff0c;主要介紹Windows操作系統中如何安裝mongodb數據庫和mongo-shell工具。 目錄 一、安裝mongodb數據庫 1.1、下載mongodb安裝包 1.2、添加配置文件 1.3、編寫啟動腳本&#xff08;可選&#xff09; 1.4、啟動服務 二、安裝mongo-shell工具 2.1、下載mo…

CSS:margin的塌陷與合并問題

文章目錄 一、margin塌陷問題二、margin合并問題 一、margin塌陷問題 二、margin合并問題

PostgreSQL 數據庫備份與恢復

1 邏輯備份(單庫) postgres#pg_dump --help 使用方法: pg_dump [選項]... [數據庫名字] 一般選項: -f, --fileFILENAME 輸出文件或目錄名 -F, --formatc|d|t|p 輸出文件格式 (c 自定義壓縮格式輸出, d 目錄, tar,p 備份為文本明…

使用 LibreOffice 實現各種文檔格式轉換(支持任何開發語言調用 和 Linux + Windows 環境)[全網首發,保姆級教程,建議收藏]

以下能幫助你可以使用任何開發語言&#xff0c;在任何平臺都能使用 LibreOffice 實現 Word、Excel、PPT 等文檔的自動轉換&#xff0c;目前展示在 ASP.NET Core 中為 PDF的實戰案例&#xff0c;其他的文檔格式轉換邏輯同理。 &#x1f4e6; 1. 安裝 LibreOffice &#x1f427;…

AWS stop/start 使實例存儲lost + 注意點

先看一下官方的說明: EC2有一個特性,當執行stop/start操作(注意,這個并不是重啟/reboot,而是先停止/stop,再啟動/start)時,該EC2會遷移到其它的底層硬件上。 對于實例存儲來說,由于實例存儲是由其所在的底層硬件來提供的,此時相當于分配到了一塊全新的空的磁盤。 但是從…

跨域問題詳解

目錄 一、什么是跨域問題&#xff1f; 二、跨域問題出現的原因 三、跨域的解決方案 四、結語 在 Web 開發的世界里&#xff0c;當我們嘗試通過 AJAX 等技術獲取不同源的資源時&#xff0c;常常會遇到 “跨域問題”。這不僅是前端開發者頻繁遭遇的技術障礙&#xff0c;也是保…

VSCode 插件 GitLens 破解方法

文章目錄 1. 安裝指定版本2. 修改插件文件3. 重啟 VSCode 1. 安裝指定版本 在 VSCode 中打開擴展&#xff08;Ctrl Shift X&#xff09;&#xff0c;搜索 GitLens&#xff0c;右鍵點擊 安裝特定版本&#xff0c;在彈出的窗口中選擇 17.0.2&#xff0c;然后等待安裝完成。 2…

JavaScript的三大核心組成:ECMAScript、DOM與BOM

JavaScript的三大核心組成&#xff1a;ECMAScript、DOM與BOM 在前端開發領域&#xff0c;JavaScript是構建動態網頁和交互式應用的核心語言。然而&#xff0c;許多人對JavaScript的組成缺乏清晰的認識。實際上&#xff0c;JavaScript并非單一的語言規范&#xff0c;而是由三個…

JC/T 2490-2019 石灰基單層裝飾砂漿檢測

石灰基單層裝飾砂漿是指由石灰等無機膠凝材料、級配砂、外加劑或無機顏料制成的具有裝飾功能的干粉飾面材料。 JC/T 2490-2019石灰基單層裝飾砂漿檢測項目&#xff1a; 測試項目 測試方法 外觀 JC/T 2490 干密度 JC/T 2490 凝結時間 JGJ/T 70 抗折強度 GB/T 17671 抗…

用算法實現 用統計的方式實現 用自然語言處理的方法實現 用大模型實現 專利精益化統計分析

我們可以從算法、統計、自然語言處理&#xff08;NLP&#xff09;和大型語言模型&#xff08;LLM&#xff09;這四個方面&#xff0c;探討如何實現對專利社區、作者重要性以及共同作者貢獻度的分析。 1. 如何體現專利的社區 (社群效應) &#x1f916; 用算法實現 網絡分析算法…

深入淺出IIC協議 - 從總線原理到FPGA實戰開發 -- 第五篇:多主仲裁與錯誤恢復

第五篇&#xff1a;多主仲裁與錯誤恢復 副標題 &#xff1a;從總線沖突到故障自愈——構建高可靠I2C系統的終極指南 1. 多主仲裁機制 1.1 仲裁原理與硬件實現 仲裁流程圖解 &#xff1a; 仲裁失敗處理 &#xff1a; 立即切換為從機模式 監測總線空閑后重試&#xff08;隨機…

146. LRU Cache

題目描述 146. LRU Cache 哈希表雙向鏈表 詳見代碼和注釋&#xff1a; class LRUCache { private:int capacity_{0};int size_{0};struct Node{int key{0};int val{0};Node* pre{nullptr};Node* next{nullptr};Node(int k,int v,Node* pr,Node* nex):key(k),val(v),pre(pr),…

docker network 自定義網絡配置與管理指南

Docker 自定義網絡配置與管理指南 1. 網絡基礎概念 Docker 網絡是容器間通信和與外部世界交互的基礎。通過自定義網絡&#xff0c;可以實現容器間的隔離、靜態 IP 分配和服務發現。 關鍵術語&#xff1a; 子網(Subnet)&#xff1a;IP 地址的邏輯分組&#xff0c;例如 172.1…

linux strace調式定位系統問題

strace 的基本功能 strace 的主要功能包括&#xff1a; 跟蹤系統調用&#xff1a;顯示進程執行時調用的系統函數及其參數和返回值。監控信號&#xff1a;記錄進程接收到的信號。性能分析&#xff1a;統計系統調用的執行時間和次數。調試支持&#xff1a;幫助定位程序崩潰、性…

告別手抖困擾:全方位健康護理指南

手抖&#xff0c;醫學上稱為震顫&#xff0c;是常見的身體癥狀&#xff0c;可能由多種原因引發&#xff0c;了解其成因并采取科學護理措施&#xff0c;對改善癥狀、維護健康至關重要。 生理性手抖往往因情緒激動、過度勞累、大量飲用咖啡或酒精等引起&#xff0c;這種手抖通常較…

華為2025年校招筆試真題手撕教程(一)

一、題目 輸入&#xff1a; 第一行為記錄的版本迭代關系個數N&#xff0c;范圍是[1&#xff0c;100000]; 第二行到第N1行&#xff1a;每行包含兩個字符串&#xff0c;第一個字符串為當前版本&#xff0c;第二個字符串為前序版本&#xff0c;用空格隔開。字符串包含字符個數為…

Qt 的多線程

Qt 中的多線程主要用于處理耗時操作&#xff0c;避免阻塞主線程&#xff08;UI 線程&#xff09;&#xff0c;從而提高程序的響應性和運行效率。以下是 Qt 多線程的相關技術總結&#xff1a; 常見的多線程實現方式 繼承 QThread 類 &#xff1a;最基礎的實現方式&#xff0c;具…