【江科大CAN】2.1 STM32 CAN外設(上)

2.1 STM32 CAN外設(上)

      • 2.1.1 STM32 CAN外設簡介
      • 2.1.2 外圍電路設計
      • 2.1.3 STM32 CAN內部結構
      • 2.1.4 發送流程詳解
      • 2.1.5 接收流程詳解
      • 2.1.6 關鍵配置位總結

STM32 CAN外設講解

大家好,歡迎繼續觀看CAN總線入門教程。本節開始,我們正式進入本套課程的第二部分:STM32 CAN外設的講解。經過前面五個視頻的學習,相信大家已經對CAN總線的基本知識有了扎實的理解 [修改] (更嚴謹,“了如指掌”略顯絕對)。接下來,我們就在實踐中驗證所學的知識吧!

第二部分我們以STM32F103C8T6這款芯片為例,介紹其內部的CAN外設原理。學會了硬件原理,下一部分我們就可以寫程序來解決實際項目的需求,完成從理論到實踐的全過程

:本節課內容來源于STM32手冊中對CAN外設的介紹。請打開資料鏈接(已更新部分資料):

  • 新增STM32相關資料:參考文檔、部分程序源碼。
  • 新增CAN收發器模塊商家資料:參考文檔、模塊原理圖、源代碼(供參考)。

學習建議:學完視頻后,請再詳細查閱STM32F10xxx參考手冊中文版中的第22章:控制器局域網 (bxCAN) 補充細節。

學習基礎:后續內容需要STM32基礎(了解基本概念、會編寫下載程序、掌握GPIO輸入輸出、使用OLED調試工具)。相關基礎可參考我之前的STM32入門教程。

2.1.1 STM32 CAN外設簡介

在這里插入圖片描述

  • 內置bxCAN外設:支持CAN 2.0ACAN 2.0B(即支持標準格式擴展格式)。
  • 功能核心:硬件自動完成CAN報文發送按照過濾器自動接收指定報文。程序只需處理報文數據,無需關注總線電平細節(幀格式、位同步、仲裁、錯誤處理等均由硬件完成),使用便捷。
  • 關鍵參數
    • 波特率:最高 1 Mbps(完美支持高速CAN)。
    • 發送:3個可配置優先級的發送郵箱(發送緩沖區)。
    • 接收:2個三級深度的接收FIFO(接收緩沖區,可緩存6個報文)。
    • 14個過濾器組(互聯型有28個):用于按ID過濾接收報文(只接收需要的報文)。
  • 特色功能(了解即可):時間觸發通信、自動離線恢復、自動喚醒、禁止自動重傳、接收FIFO溢出方式可配置、發送優先級可配置、雙CAN模式(互聯型)等。
  • STM32F103C8T6資源:內置 CAN1(僅一個CAN外設)。

2.1.2 外圍電路設計

在這里插入圖片描述

  1. CAN拓撲結構

    • 節點 = CAN控制器 (STM32內部) + CAN收發器 (如TJA1050)。
    • STM32引腳:CAN_TX -> PA12, CAN_RX -> PA11
    • 注意:如果CAN與USB需要同時使用,需要將CAN引腳重映射到PB8和PB9 。
  2. 收發器電路
    在這里插入圖片描述

    • 核心芯片:TJA1050
    • 關鍵連接:收發器 TXD -> STM32 CAN_TX (PA12), 收發器 RXD -> STM32 CAN_RX (PA11)
    • 供電:收發器 VCC 必須接5V(以滿足總線電平規范)。
    • 終端電阻:總線物理兩端各接一個120Ω電阻。實驗模塊自帶120Ω電阻。
      • 實驗說明:實驗中(如三設備)未移除中間模塊電阻(三個電阻)也能工作,但實際項目應嚴格按規范(僅保留總線物理兩端的電阻)。
      • 如果正常使用下,多設備連接,只需在總線物理兩端各保留一個電阻。
    • 模塊附加電路:部分模塊在 CAN_H/CAN_L 上串聯10Ω電阻(抗噪)并接30pF電容(濾波),手冊參考電路無此設計。

2.1.3 STM32 CAN內部結構

在這里插入圖片描述
該框圖可分為兩個主要部分:

  1. 主 CAN (CAN1):位于框圖上半部分。這是我們當前芯片 STM32F103C8T6 所擁有的唯一 CAN 外設資源,也是我們學習的核心。
  2. 從 CAN (CAN2):位于框圖下半部分
    • 僅存在于互聯型 (Connectivity Line) STM32 芯片中(如 STM32F107/STM32F105)。
    • STM32F103C8T6 屬于基本型,沒有 CAN2,因此這部分無需關注
    • 互聯型芯片特性:在互聯型芯片中,CAN1 和 CAN2 并非完全獨立CAN2 主要作為 CAN1 的輔助兩者共同管理同一個 CAN 總線。這種設計主要是為了分擔負載或提供冗余等高級功能。此處僅作了解。

聚焦主 CAN (CAN1) 部分:
框圖上半部分清晰地展示了 CAN1 的核心構成,主要分為三大功能模塊

  1. CAN 2.0B 主動核心 (bxCAN Core - CAN 2.0B Active) - 左側模塊
    在這里插入圖片描述

    • 這是 bxCAN 外設的“大腦”和“引擎”,包含了實現 CAN 2.0A/B 協議所需的全部核心邏輯電路(位定時、位填充/解填充、幀處理、仲裁、錯誤檢測、ACK 處理、CRC 計算/校驗等)。
    • 核心與程序的接口:核心內部包含大量控制寄存器、狀態寄存器和數據寄存器
      • 程序通過讀寫這些寄存器配置 CAN 外設的工作模式、參數(如波特率)啟動/停止操作查詢狀態(如發送/接收完成、錯誤標志)
      • 一句話總結程序通過讀寫寄存器來完全控制和監視硬件 CAN 電路的運行。這些寄存器的詳細描述可在 STM32 參考手冊的“CAN 寄存器描述”章節查閱。后續視頻中遇到關鍵寄存器時,我們會直接解釋其功能和用法。
  2. 發送郵箱 (Transmit Mailboxes) - 中間模塊
    在這里插入圖片描述

    • bxCAN 提供了 3 個獨立的發送郵箱 (Mailbox 0, 1, 2)。
    • 功能:每個郵箱都是一個存儲單元,用于臨時存放一個完整的待發送 CAN 報文(包含幀信息:ID、RTR、IDE、DLC 以及 0-8 字節數據)。
    • 發送流程
      1. 程序選擇一個空置的發送郵箱
      2. 將待發送報文的所有參數和數據寫入該郵箱對應的寄存器。
      3. 設置該郵箱的 TXRQ (Transmit Request) 寄存器位為 1請求發送
    • 后續自動化:一旦請求發送被置位,后續所有操作均由硬件自動完成,程序無需干預:
      • 等待總線空閑 (Bus Idle)。
      • 執行位同步 (Bit Synchronization)。
      • 處理總線仲裁 (Arbitration)。
      • 操作 CAN_TX 引腳輸出波形。
      • 執行位填充 (Bit Stuffing)。
      • 處理錯誤檢測與恢復 (Error Handling)。
      • 等待/處理 ACK 槽。
      • 發送 EOF 等。
    • 設計目的:使用起來非常簡單高效。程序只需“告訴”硬件發什么,硬件負責“搞定”整個發送過程。三個郵箱提供了發送緩沖,允許程序連續寫入多個待發報文,硬件按策略依次發送,減少程序等待時間。
  3. 接收部分 (Receive Section) - 右側模塊
    在這里插入圖片描述

    • 該部分包含兩個關鍵子模塊:標識符過濾器 (Identifier Filters)接收 FIFO (Receive FIFOs)
    • 基本接收流程
      • CAN 總線上出現一個數據幀或遠程幀的報文波形時,bxCAN 核心硬件電路自動捕獲并完整接收該報文。
      • 接收到的報文首先經過標識符過濾器組
        • 過濾器作用:程序可以預先在 14 個過濾器組配置過濾規則(例如,只接收特定 ID 范圍的報文,或屏蔽某些 ID 的報文)。硬件會自動將接收到的報文 ID 與所有啟用的過濾器規則進行比對
        • 過濾結果
          • 如果報文 ID 匹配任何一個啟用的過濾器規則,則該報文被視為“需要的”,允許進入下一步。
          • 如果報文 ID 無法匹配任何一個啟用的過濾器規則,則該報文直接被硬件丟棄(“扔掉”),不會通知程序。這極大地減輕了軟件處理無關報文的負擔
      • 通過過濾器的報文不會直接交給程序,而是存入接收 FIFO
    • 接收 FIFO (FIFO0 & FIFO1)
      • bxCAN 提供了 2 個獨立的接收 FIFOFIFO0FIFO1
      • FIFO 含義First-In-First-Out,先進先出緩沖區隊列。通俗地說,就是排隊
      • 功能:每個 FIFO 相當于一個隊列,隊列深度為 3 個郵箱 (Mailbox)。也就是說,每個 FIFO 最多可以暫存 3 個通過過濾器的接收報文
      • 報文存儲:通過過濾器的報文,會根據過濾器配置時指定的目標(由程序設定),自動進入 FIFO0 或 FIFO1 的隊列末尾排隊
      • 程序讀取:程序通過讀取 FIFO 對應的寄存器,可以從隊列頭部(最先進入的報文) 逐個讀取報文數據和狀態信息。讀取后需要釋放郵箱,騰出空間接收新報文。
      • 優勢
        • 緩沖作用:如果 CAN 總線報文接收速度很快,而程序未能及時讀取,報文可以在 FIFO 中排隊等待
        • 避免丟失:FIFO 的緩沖能力(每個 FIFO 最多 3 個報文)在一定程度上避免了因程序處理不及時導致的報文丟失,非常實用。
      • 雙 FIFO 設計目的:提供兩個獨立的接收隊列。程序可以配置不同優先級的報文或不同類型的報文進入不同的 FIFO(例如,重要報文進 FIFO0,普通報文進 FIFO1)。這樣,即使普通報文很多導致 FIFO1 排隊甚至溢出,重要報文仍然可以在 FIFO0 中被及時接收和處理,降低了重要報文丟失的概率。

框圖局限性
手冊提供的框圖清晰地展示了主要功能模塊(核心、發送郵箱、接收過濾器/FIFO)及其連接關系,但對于發送郵箱的狀態流轉、過濾器具體工作模式、FIFO 隊列管理細節等描繪得不夠詳盡。因此,在接下來的內容中,我們將通過更詳細的流程圖和文字描述來深入解析這些關鍵流程的細節。

核心框圖可劃分為:
STM32 CAN 外設核心流程詳解 (發送與接收)

為了更清晰地理解 CAN 報文在 STM32 bxCAN 外設中的具體流轉過程,我們聚焦于發送接收的核心流程。可以將 bxCAN 硬件邏輯視為一個強大的“管理員”。程序只需告訴它要發送什么報文,以及從它那里讀取已接收且需要的報文,而總線操作的底層細節(等待空閑、波形輸出、位同步、仲裁、錯誤處理等)均由管理員全權負責

1. 發送流程 (如何發出一個報文?)
在這里插入圖片描述

  1. 程序操作
    • 選擇一個空置的發送郵箱 (郵箱 0、1 或 2)。
    • 將報文的所有參數 (IDDataIDE (擴展標志)、RTR (遠程幀標志)、DLC (數據長度碼)) 寫入該郵箱對應的寄存器。
    • 設置該郵箱的 TXRQ (Transmit Request) 寄存器位為 1,發出請求發送命令。
  2. 管理員的工作
    • 收到發送請求后,自動接管后續所有操作
    • 等待總線進入 空閑 (Idle) 狀態。
    • 當總線空閑時,自動將該報文廣播到 CAN 總線上,完成整個發送流程(包含位同步、仲裁、波形輸出、位填充、錯誤檢測、ACK 處理等)。
    • 報文成功發送后,釋放該郵箱,使其恢復空置狀態
  3. 為什么需要 3 個發送郵箱?
    • 核心目的防止因總線繁忙造成 CPU 等待 (發送擁堵)
    • 場景分析
      • 程序寫入報文 A 到郵箱 0 并請求發送。
      • 管理員發現總線正忙,報文 A 在郵箱 0 中等待
      • 此時程序又想發送報文 B。如果只有一個郵箱,程序必須等待郵箱 0 空閑(即報文 A 發送完成)才能寫入報文 B,造成 CPU 等待
      • 有了三個郵箱,程序發現郵箱 0 被占用,可以立即將報文 B 寫入郵箱 1 并請求發送。管理員會在總線空閑時依次發送郵箱 0 和郵箱 1 的報文。CPU 無需等待,可以繼續執行其他任務。
      • 同理,程序還可以將報文 C 寫入郵箱 2
      • 極限情況:如果三個郵箱都寫滿總線持續繁忙,此時程序再想發送新報文 (D) 時,才需要等待某個郵箱釋放。這種情況表示總線非常擁堵,在實際應用中相對少見。
    • 優勢:三個郵箱提供了發送緩沖區,允許程序連續提交多個發送請求,顯著減少了 CPU 因等待總線空閑而產生的阻塞時間
  4. 發送策略配置 (TXFP 位)
    • 多個郵箱中都有待發報文總線變為空閑時,管理員需要決定先發送哪個郵箱的報文
    • 策略可配置:
      • TXFP = 1先請求先發送 (FIFO 模式)。嚴格按照請求發送 (TXRQ=1) 的時間順序處理郵箱(郵箱號順序是次要的)。先請求的報文先發送
      • TXFP = 0按 ID 優先級發送。管理員會比較所有待發郵箱中報文的 ID 號優先發送 ID 值最小的報文(優先級最高)。ID 值相等時,優先發送郵箱號小的報文(如郵箱 0 優于郵箱 1)。此模式允許高優先級報文“插隊”。

2. 接收流程 (如何接收想要的報文?)
在這里插入圖片描述

  1. 管理員的工作 (第一步:捕獲與過濾)
    • CAN 總線上出現任何數據幀或遠程幀時,管理員都會自動捕獲并完整接收該報文。
    • 接收到的報文首先經過 14 個標識符過濾器組
      • 過濾器作用:程序預先在過濾器組中配置規則(例如:只接收特定 ID 或 ID 范圍的報文,屏蔽某些 ID 的報文)。硬件自動進行 ID 比對
      • 過濾結果
        • 報文 ID 匹配任何一個啟用的過濾器規則 -> 報文是**“需要的”** -> 允許進入下一步
        • 報文 ID 無法匹配任何啟用的過濾器規則 -> 報文是**“不需要的”** -> 管理員直接丟棄該報文,不會通知程序
    • 過濾器意義硬件級過濾極大地減輕了軟件負擔,軟件無需處理海量的無關報文 ID 比對
  2. 管理員的工作 (第二步:排隊存儲)
    • 通過過濾器的報文(即“需要的”報文)不會直接交給程序
    • 它們會根據配置過濾器時指定的目標 FIFO (由程序設定),自動存入接收 FIFO0 或 FIFO1 的隊列中排隊等待
      • FIFO (先進先出隊列):每個 FIFO (FIFO0, FIFO1) 都是一個隊列,深度為 3 個郵箱。意味著每個 FIFO 最多可暫存 3 個報文
      • 報文存儲規則
        • 新報文總是排在隊列的末尾
        • 示例:配置 Filter0 通過的報文進 FIFO0Filter1 通過的報文進 FIFO1
          • 報文 A (通過 Filter0) -> 存入 FIFO0 郵箱 0 (隊首)。
          • 報文 B (通過 Filter0) -> 存入 FIFO0 郵箱 1。
          • 報文 C (通過 Filter1) -> 存入 FIFO1 郵箱 0 (隊首)。
          • 報文 D (通過 Filter0) -> 存入 FIFO0 郵箱 2。
          • 此時 FIFO0 已滿 (3個報文)
  3. 程序操作 (讀取)
    • 程序通過輪詢或中斷方式,檢查 FIFO0FIFO1 的隊列狀態 (FMPx 寄存器位指示隊列中報文數量)。
    • 當檢測到某個 FIFO 隊列長度大于 0 (有報文排隊) 時:
      • 程序讀取該 FIFO 隊列頭部 (最先存入,郵箱 0) 的報文數據。
      • 讀取后,程序必須顯式釋放該郵箱 (RFOMx=1)。
      • 隊列管理:釋放隊首郵箱后:
        • 郵箱 1 的報文前移到郵箱 0 (成為新隊首)。
        • 郵箱 2 的報文前移到郵箱 1。
        • 隊尾郵箱 (郵箱 2) 變為空置,可接收新報文。
      • 這個過程模擬了現實中排隊新來者排到隊尾,處理者從隊首開始,處理完隊首后后面的人依次前移。這就是 FIFO (先進先出) 名稱的由來。
  4. FIFO 滿溢處理 (RFLM 位)
    • 當某個 FIFO 隊列已滿 (3 個郵箱均占用) 時,如果又收到一個需存入該 FIFO 的報文:
      • RFLM = 1 (鎖定模式)新報文直接丟棄
      • RFLM = 0 (非鎖定模式 - 默認)新報文覆蓋該 FIFO 隊列中最后接收的報文 (即郵箱 2 中的報文)。原郵箱 2 的報文丟失
    • 隊列滿溢必然導致報文丟失:要么丟棄新報文 (RFLM=1),要么覆蓋最舊的排隊報文 (RFLM=0)。
  5. 為什么需要 2 個接收 FIFO? (分流策略)
    • 核心目的降低重要報文在接收擁堵時的丟失概率
    • 類比:食堂設學生窗口教師窗口。即使學生窗口排長隊擁堵,教師仍能在教師窗口快速打飯,保證教師(重要角色)能準時吃飯
    • 應用
      • 重要、緊急或數量較少的報文 (如關鍵控制指令、報警信號) 配置到 FIFO0
      • 普通、非關鍵或數量較大的報文 (如常規狀態更新) 配置到 FIFO1
    • 優勢
      • 即使 FIFO1 因大量普通報文涌入而頻繁滿溢重要報文仍然可以在 FIFO0 中被可靠接收(除非 FIFO0 自己也滿了)。
      • 相比于所有報文擠在單一 FIFO 隊列中(容易導致重要報文排在后面被覆蓋或丟棄),雙 FIFO 分流顯著提高了重要報文的接收可靠性
    • 注意:STM32 硬件本身并未賦予 FIFO0FIFO1 不同的優先級,它們是平級的。程序可以根據自身需求(報文重要性、類型、接收頻率)靈活配置分流規則

發送郵箱 vs. 接收 FIFO (本質都是緩沖隊列)

  • 共同點:兩者都在數據寫入速率 (CPU 提交發送請求 / 管理員 存入接收報文) 大于數據處理速率 (管理員 實際發送 / CPU 讀取接收報文) 時,提供緩沖能力,避免數據丟失或 CPU 阻塞
  • 差異點
    • 接收 FIFO:只支持嚴格的先進先出 (FIFO) 排隊策略。
    • 發送郵箱:排隊策略可配置 (TXFP 位),支持 FIFO (TXFP=1) 或 ID 優先級 (TXFP=0)。
  • 理想情況:如果數據處理速率遠高于寫入速率(發送:總線總是很快空閑;接收:CPU 總是及時讀取),隊列基本不會堆積,緩沖作用不明顯。但在實際應用中,緩沖隊列對于應對突發流量和短暫擁堵至關重要

通過以上詳細流程解析,STM32 CAN 外設 (bxCAN) 處理報文發送與接收的核心機制就非常清晰了。


2.1.4 發送流程詳解

在這里插入圖片描述

好的,這是按照您要求的格式(保留加粗,無省略知識點,無引用符號)校正優化后的文本,詳細描述了 STM32 CAN 發送郵箱的狀態流轉及其寄存器標志位

STM32 CAN 發送郵箱狀態流轉詳解

接下來,我們深入探討 發送郵箱在報文發送過程中經歷的各種狀態及其狀態寄存器標志位的變化。理解這個狀態機對于掌握發送流程和控制至關重要。

核心狀態寄存器標志位 (需關注):

  • TME (Transmit mailbox empty)發送郵箱空1 表示郵箱空閑可用0 表示郵箱已被占用(有報文待發或正在發送)。
  • TXRQ (Transmit request)發送請求。由程序置 1請求發送該郵箱中的報文。硬件在發送完成或失敗后清除此位。
  • RQCP (Request completed)請求完成1 表示對該郵箱的發送請求已完成(無論成功或失敗);0 表示請求未完成/正在進行中
  • TXOK (Transmission OK)發送成功1 表示報文成功發送(收到有效 ACK 且無錯誤);0 表示發送未成功尚未完成
  • ABRQ (Abort request)中止請求。由程序置 1請求中止該郵箱的發送。
  • NART (No automatic retransmission)禁止自動重傳(全局配置位)。0 啟用自動重傳;1 禁止自動重傳。

發送郵箱狀態機 (單個郵箱視角):

  1. 空置狀態 (Empty)

    • 標志位TME = 1, RQCP = X (任意), TXOK = X (任意)。
    • 含義:郵箱空閑,程序可向其寫入新報文
    • 進入條件:初始狀態,或發送完成/失敗/中止后。
    • 操作:程序寫入報文參數 (ID, Data, IDE, RTR, DLC) 并設置 TXRQ = 1
  2. 掛號狀態 (Pending)

    • 標志位TME = 0, TXRQ = 1, RQCP = 0, TXOK = 0
    • 含義:報文已寫入郵箱,發送請求 (TXRQ=1) 已發出,等待參與發送調度
    • 進入條件:在空置狀態寫入報文并設置 TXRQ=1
    • 狀態行為
      • 該郵箱的報文已準備好發送
      • 由于存在多個郵箱 (0, 1, 2),且可能都有待發報文,因此需要確定發送順序
    • 后續狀態:當該郵箱的報文根據 TXFP 配置的發送策略被確定為當前最高優先級時,進入預定狀態
  3. 預定狀態 (Scheduled)

    • 標志位TME = 0, TXRQ = 1, RQCP = 0, TXOK = 0。(標志位與掛號狀態相同,由內部邏輯區分)。
    • 含義:該郵箱的報文已被管理員調度為“下一個發送”一旦總線空閑 (IDLE),即開始發送。
    • 進入條件:從掛號狀態提升而來,前提是該郵箱報文的優先級是當前所有掛號郵箱中最高的
      • 優先級決定方式 (TXFP)
        • TXFP = 1 (FIFO 模式 - 先請求先發送):優先級僅由請求發送 (TXRQ=1) 的時間順序決定一旦進入預定狀態,不會退回掛號狀態(先來者不會“被插隊”)。
        • TXFP = 0 (ID 優先級模式):優先級由報文 ID 值決定(ID 值小者優先級高;ID 相等時郵箱號小者優先)。在這種模式下,如果一個具有更高優先級 (更小 ID) 的報文被寫入另一個郵箱并請求發送 (TXRQ=1),當前處于預定狀態的郵箱可能被“搶占”退回掛號狀態等待。
    • 后續狀態:當檢測到總線空閑 (IDLE) 時,進入發送狀態
  4. 發送狀態 (Transmit)

    • 標志位TME = 0, TXRQ = 1, RQCP = 0, TXOK = 0。(標志位仍與掛號/預定狀態相同,由內部邏輯區分)。
    • 含義:該郵箱的報文正在被管理員實際發送到 CAN 總線上(進行位同步、驅動 TX 引腳、仲裁、填充、錯誤檢測、等待 ACK 等操作)。
    • 進入條件:從預定狀態進入,當總線空閑時。
    • 后續狀態 (發送結束)
      • 發送成功 (收到有效 ACK 且未檢測到錯誤):
        • 狀態回到空置狀態
        • 設置標志位:TME = 1, RQCP = 1, TXOK = 1
      • 發送失敗 (仲裁丟失、未收到 ACK、檢測到位錯誤等):
        • 取決于 NART
          • NART = 0 (啟用自動重傳):狀態回到預定狀態 (TME=0, TXRQ=1, RQCP=0, TXOK=0)。硬件將自動嘗試重發該報文,直到成功。
          • NART = 1 (禁止自動重傳):狀態直接回到空置狀態
            • 設置標志位:TME = 1, RQCP = 1, TXOK = 0 (表示請求已完成但發送失敗)。
      • 程序中止 (ABRQ = 1)
        • 狀態回到空置狀態
        • 設置標志位:TME = 1, RQCP = 1, TXOK = 0 (表示請求被中止,發送未成功)。

關鍵狀態轉換補充:

  • 中止發送 (ABRQ):程序可以在郵箱處于掛號狀態 (TME=0, TXRQ=1, RQCP=0, TXOK=0)預定狀態 (TME=0, TXRQ=1, RQCP=0, TXOK=0) 時(即報文尚未實際開始驅動總線波形),通過設置 ABRQ = 1主動終止該次發送請求。效果與 NART=1 時的發送失敗相同:直接進入空置狀態,RQCP=1, TXOK=0
  • 預定狀態回退僅發生在 TXFP=0 (ID 優先級模式)有更高優先級報文加入并請求發送時。該郵箱會從預定狀態退回到掛號狀態 (TME=0, TXRQ=1, RQCP=0, TXOK=0),等待再次被調度。

2.1.5 接收流程詳解

接下來,我們聚焦于 接收 FIFO (FIFO0 或 FIFO1) 在報文接收、存儲和讀取過程中經歷的狀態及其狀態寄存器標志位的變化。理解這個狀態機對于掌握接收流程和管理 FIFO 隊列至關重要。在這里插入圖片描述
STM32 CAN 接收 FIFO 狀態流轉詳解

核心狀態寄存器標志位 (需關注):

  • FMPx (FIFO message pending - x=0 or 1)FIFO 中掛起的報文數量。這是一個 2 位字段:
    • 00b0 個報文 (FIFO 空)。
    • 01b1 個報文
    • 10b2 個報文
    • 11b3 個報文 (FIFO 滿)。
  • FOVRx (FIFO overrun - x=0 or 1)FIFO 溢出標志1 表示自上次該標志被清除以來,該 FIFO 曾發生過溢出(即 FIFO 滿時又收到新報文);0 表示未發生溢出。
  • FULLx (FIFO full - x=0 or 1)FIFO 滿標志1 表示該 FIFO 的 3 個郵箱已全部占用0 表示 FIFO 未滿(有至少一個空郵箱)。(注:此標志位在手冊提供的流程圖中未明確標出,但實際存在且重要)
  • RFOMx (Release FIFO output mailbox - x=0 or 1)釋放 FIFO 輸出郵箱。程序通過1 此位釋放當前位于 FIFO 隊列頭部的郵箱(即 FIFOx 郵箱 0),使隊列后續報文前移。

接收 FIFO 狀態機 (單個 FIFO 視角):

  1. 空狀態 (Empty)

    • 標志位FMPx = 00b (0), FOVRx = 0, FULLx = 0
    • 含義FIFO 隊列為空,無任何報文等待處理。所有 3 個郵箱均空閑。
    • 進入條件:初始狀態,或所有報文被讀取釋放后。
    • 操作:等待有效報文存入。
  2. 掛號一狀態 (Pending 1)

    • 標志位FMPx = 01b (1), FOVRx = 0, FULLx = 0
    • 含義FIFO 隊列中有 1 個報文(位于郵箱 0),等待程序讀取。FIFO 未滿未溢出
    • 進入條件:從空狀態接收到第 1 個有效報文(通過過濾器且目標為此 FIFO)。
    • 操作:程序可讀取 FIFOx 郵箱 0 的數據。
  3. 掛號二狀態 (Pending 2)

    • 標志位FMPx = 10b (2), FOVRx = 0, FULLx = 0
    • 含義FIFO 隊列中有 2 個報文(郵箱 0 和 郵箱 1),按接收順序排隊。FIFO 未滿未溢出
    • 進入條件:從掛號一狀態接收到第 2 個有效報文
    • 操作:程序可讀取 FIFOx 郵箱 0 (隊首) 的數據。
    • 手冊勘誤說明:手冊流程圖此處將 FMPx 寫作 0x10 (十六進制 16),這是錯誤的。正確應為 10b (二進制 2) 或明確表示為 2
  4. 掛號三狀態 (Pending 3 / Full)

    • 標志位FMPx = 11b (3), FOVRx = 0, FULLx = 1
    • 含義FIFO 隊列已滿3 個郵箱均已占用(郵箱 0, 1, 2)。FIFO 已滿 (FULLx=1),但尚未溢出 (FOVRx=0)。這是 FIFO 的最大容量狀態
    • 進入條件:從掛號二狀態接收到第 3 個有效報文
    • 操作:程序可讀取 FIFOx 郵箱 0 (隊首) 的數據。
  5. 溢出狀態 (Overrun)

    • 標志位FMPx = 11b (3), FOVRx = 1, FULLx = 1
    • 含義FIFO 隊列已滿 (FMPx=11b, FULLx=1) 的狀態下,又收到了一個需存入該 FIFO 的有效報文。此時發生了溢出 (FOVRx=1)。
    • 進入條件:在掛號三狀態 (已滿) 時,接收到第 4 個 (及更多) 有效報文
    • 溢出處理 (取決于 RFLM 配置位)
      • RFLM = 1 (鎖定模式)新報文被直接丟棄。FIFO 內容 (FMPx=11b) 保持不變。
      • RFLM = 0 (非鎖定模式 - 默認)新報文覆蓋隊列中最后接收的報文(即郵箱 2 中的舊報文)。FMPxFULLx 保持 11b1,表示隊列仍滿,但內容已更新(郵箱 2 被替換)。
    • 狀態維持:只要 FIFO 保持滿狀態 (FMPx=11b) 且不斷有新的目標報文到來,FOVRx 將保持為 1,狀態維持為溢出狀態。每次新報文到來都會根據 RFLM 執行丟棄或覆蓋操作。

FIFO 讀取與釋放操作:

  • 操作前提:當 FMPx > 00b (FIFO 非空) 時,程序可以讀取 FIFOx 郵箱 0 的報文數據。
  • 關鍵操作 - 釋放郵箱 (RFOMx=1):讀取完郵箱 0 的數據后,程序必須置 RFOMx=1釋放該郵箱
  • 釋放后的隊列管理
    • 釋放操作觸發隊列前移
      • 郵箱 1 的報文 -> 移動到郵箱 0 (成為新隊首)。
      • 郵箱 2 的報文 -> 移動到郵箱 1
      • 原郵箱 2 的位置變為空閑 (可接收新報文)。
    • FMPx減 1
    • 如果 FOVRx=1,它不會被自動清除,需要軟件在適當時機手動清除。
  • 狀態轉換 (釋放后)
    • 溢出狀態 (FMPx=11b, FOVRx=1, FULLx=1) 釋放郵箱:
      • FMPx 變為 10b (2)。
      • FULLx 變為 0 (隊列未滿)。
      • 狀態直接進入掛號二狀態 (FMPx=10b, FOVRx=1, FULLx=0)
      • 重要說明不需要經過掛號三狀態。溢出狀態和掛號三狀態的主要區別在于 FOVRx 標志位。釋放郵箱后,FMPx 從 3 減為 2,隊列未滿,故直接進入掛號二狀態。FOVRx=1 仍然有效,指示曾發生過溢出。
    • 掛號三狀態 (FMPx=11b, FOVRx=0, FULLx=1) 釋放郵箱:
      • FMPx 變為 10b (2).
      • FULLx 變為 0.
      • 狀態進入掛號二狀態 (FMPx=10b, FOVRx=0, FULLx=0)
    • 掛號二狀態 (FMPx=10b, FOVRx=0, FULLx=0) 釋放郵箱:
      • FMPx 變為 01b (1).
      • 狀態進入掛號一狀態 (FMPx=01b, FOVRx=0, FULLx=0)
    • 掛號一狀態 (FMPx=01b, FOVRx=0, FULLx=0) 釋放郵箱:
      • FMPx 變為 00b (0).
      • 狀態回到空狀態 (FMPx=00b, FOVRx=0, FULLx=0)

2.1.6 關鍵配置位總結

在這里插入圖片描述

  1. NART (No automatic retransmission)
    • 1禁止自動重傳。報文只發送一次(無論成功失敗)。
    • 0啟用自動重傳 (默認)。發送失敗會重試直至成功。
  2. TXFP (Transmit FIFO priority)
    • 1:發送優先級由請求順序決定 (先請求先發送)。
    • 0:發送優先級由報文標識符(ID) 決定 (ID小者優先)。
  3. RFLM (Receive FIFO locked mode)
    • 1:接收FIFO 鎖定模式。FIFO滿時新報文丟棄
    • 0:接收FIFO 非鎖定模式 (默認)。FIFO滿時新報文覆蓋FIFO末尾舊報文

本節總結
我們詳細講解了 STM32 bxCAN外設的核心結構、發送郵箱的狀態流轉、接收過濾器雙FIFO的工作機制以及關鍵配置位(NART, TXFP, RFLM)。掌握了這些硬件原理,為下一部分編寫實際通信程序奠定了堅實基礎。

下一節預告:我們將深入探討 CAN外設的標識符過濾器配置 及更多功能。

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

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

相關文章

人工智能技術革命:AI工具與大模型如何重塑開發者工作模式與行業格局

引言:AI技術爆發的時代背景過去五年間,人工智能領域經歷了前所未有的爆發式增長。從2020年GPT-3的橫空出世到2023年多模態大模型的全面突破,AI技術已經從實驗室走向了產業應用的前沿。開發者作為技術生態的核心推動者,其工作模式正…

傅里葉變換

傅里葉變換:運用頻域的出發點就是能夠將波形從時域變換到頻域,用傅里葉變換可以做到這一點。有如下3種傅里葉變換類型:1.傅里葉積分(FI); 2.離散傅里葉變換(DFT); 3.快速傅里葉變換(FFT)。傅里葉積分是一種將時域的理想數學表達變換成頻域描述的數學技術…

【IQA技術專題】紋理相似度圖像評價指標DISTS

紋理一致性圖像評價指標: Image Quality Assessment: Unifying Structure and Texture Similarity(2020 PAMI)專題介紹一、研究背景二、方法總覽2.1 初始變換2.2 紋理表示和結構表示2.3 DISTS指標2.4 優化DISTS指標三、實驗結果四、總結本文將對統一圖像…

windows下Docker安裝路徑、存儲路徑修改

一、命令行指定安裝路徑? ??下載安裝包??:從Docker官網獲取安裝程序(如Docker Desktop Installer.exe)。??運行PowerShell??: & "H:\Docker Desktop Installer.exe" install --installation-dir"F:…

thingsboard 自定義動作JS編程

在 ThingsBoard 中實現 自定義動作(Custom Action)的 JavaScript 編程,主要通過“Custom action (with HTML template)”方式完成,適用于創建彈窗、編輯實體、控制設備等交互行為。 實現步驟(以添加設備或資…

Spring Boot 簡單接口角色授權檢查實現

一、背景與目標在Spring Boot應用開發中,接口級別的權限控制是系統安全的重要組成部分。本文將介紹一種簡單直接的接口角色授權檢查實現方案,適合快速開發和安全合規檢查場景。二、技術方案概述本方案采用自定義注解攔截器的方式實現,具有以下…

PytorchLightning最佳實踐日志篇

在 PyTorch Lightning(PL)中,日志系統是 “煉丹” 過程中復現實驗、對比效果、排查問題的核心工具。結合實際工程經驗,總結以下最佳實踐和技巧,幫助提升實驗效率: 一、日志工具的選擇與配置 PL 通過統一的s…

基于JavaWeb的兼職發布平臺的設計與實現

開發語言:Java框架:springbootJDK版本:JDK1.8服務器:tomcat7數據庫:mysql 5.7數據庫工具:Navicat12開發軟件:eclipse/myeclipse/ideaMaven包:Maven3.6系統展示系統首頁用戶登錄招聘信…

Linux學習--C語言(指針3)

1.指針函數和函數指針1.1 指針函數指針函數是函數&#xff0c;函數的返回值是指針不能返回局部變量的地址指針函數返回的地址可以作為下一個函數調用的參數1.2 函數指針函數指針是指針&#xff0c;指針指向一個函數#include <stdio.h>int Add(int x, int y) {return x y…

【JAVA EE初階】多線程(上)

目錄 1.預備知識 1.1 馮諾依曼體系結構&#xff1a; 1.2 現代CPU主要關心指標&#xff08;和日常開發密切相關的&#xff09; 1.3 計算機中&#xff0c;一個漢字占幾個字節&#xff1f; 1.4 Windows和Linux的區別 1.5 PCB的一些關鍵要點 2.線程和進程 2.1 創建線程的寫法…

用互聯網思維擴展電商后臺的 CRUD 功能

一、自定義實現MyBatis-Plus逆向工程 多數據源的問題解決了&#xff0c;接下來開始進行實際開發時&#xff0c;你會發現&#xff0c;最麻煩的一件事情就是要創建與數據庫表對應的POJO了。這些沒什么難度&#xff0c;但是繁瑣的內容會占據大量的開發時間。比如一個PmsProducr對…

無代碼測試平臺ATECLOUD全場景測試方案

ATECLOUD 智能云測試平臺是有納米軟件開發的一款以無代碼架構與彈性擴展體系為核心的自動化測試平臺&#xff0c;通過數據模型驅動的創新設計&#xff0c;為研發、產線等多場景提供高效可控的測試解決方案。?無代碼架構 ATECLOUD 打破傳統技術壁壘&#xff0c;構建完全可視化的…

當 AI 重構審計流程,CISA 認證為何成為破局關鍵

在南京審計大學最新發布的《面向審計行業 DeepSeek 大模型操作指南》中&#xff0c;一組數據引發行業深思&#xff1a;通過自動化數據處理、智能風險識別和定制化報告生成&#xff0c;AI 大模型能幫助審計人員降低 40% 以上的人工成本&#xff0c;同時將風險識別準確率提升至 9…

NAT技術、代理服務器

NAT/NAPT技術NAT的全稱是network address translation&#xff0c;網絡地址轉換。NAT 能在對外通信時夠將源 IP 轉為新源 IP&#xff0c;對內通信時將目的ip轉換成新目的ip&#xff0c;實現這個操作&#xff0c;靠的是地址轉換表但NAT的說法其實是不準確的&#xff0c;因為多個…

【硬件-筆試面試題】硬件/電子工程師,筆試面試題-45,(知識點:負反饋的作用,基礎理解,干擾和噪聲的抑制)

目錄 1、題目 2、解答 步驟一&#xff1a;明確負反饋的作用原理 步驟二&#xff1a;逐一分析選項 3、相關知識點 一、負反饋的基本原理 二、負反饋對干擾和噪聲的抑制機制 三、選項分析與答案 四、擴展思考&#xff1a;如何抑制不同位置的干擾&#xff1f; 總結 題目…

Flutter藍牙BLE開發完全指南(內含高級功能擴展)

Flutter藍牙BLE開發完全指南 我將為您提供一個完整的Flutter藍牙BLE實現方案,包含UI設計、權限處理、設備掃描、連接通信等完整功能。 完整實現方案 1. 添加依賴與權限配置 pubspec.yaml dependencies:flutter:sdk: flutterflutter_blue_plus: ^1.10.0permission_handler…

使用 Canvas 替代 <video> 標簽加載并渲染視頻

在部分瀏覽器環境或業務場景下&#xff0c;直接使用 <video> 標簽加載視頻會出現首幀延遲的情況。以下方法通過 WebGPU Canvas 2D 將視頻幀繪制到自定義 Canvas 上&#xff0c;讓 <video> 只做解碼&#xff0c;WebGPU 接管渲染&#xff0c;通過最小化對象創建 精…

基于Flask的智能停車場管理系統開發實踐

在現代城市中&#xff0c;停車難已成為一個普遍問題。為了解決這一問題&#xff0c;我開發了一個基于Python Flask框架的智能停車場管理系統。該系統集成了車牌識別、車位狀態監控、收費管理等多項功能&#xff0c;為停車場的智能化管理提供了完整的解決方案。系統功能概述該停…

【C#獲取高精度時間】

在C#中&#xff0c;有幾種方法可以獲取高精度時間&#xff08;高分辨率時間戳&#xff09;&#xff0c;適用于性能測量、計時等需要高精度的場景。以下是幾種常用方法&#xff1a; 1. 使用 Stopwatch 類&#xff08;推薦&#xff09; Stopwatch 類提供了最高精度的時間測量&…

Spring Boot + React 打造現代化高校成績管理系統實戰記錄

作者: 笙囧同學 發布時間: 2025年7月 技術棧: Spring Boot 3.2.3 React 18 TypeScript 華為云GaussDB 項目類型: 全棧Web應用 開發周期: 30天 代碼量: 15000 行 &#x1f4d6; 前言 大家好&#xff0c;我是笙囧同學&#xff01;&#x1f64b;?♂? 作為一名計算機科學與技…