无主之地2配置高吗|看真人裸体BBBBB|秋草莓丝瓜黄瓜榴莲色多多|真人強奷112分钟|精品一卡2卡3卡四卡新区|日本成人深夜苍井空|八十年代动画片

網易首頁 > 網易號 > 正文 申請入駐

CAN總線位定時與同步:深度解析與代碼實現

0
分享至


一、位時間的基本概念 1.1 核心時間單位

如您所述,CAN位時間由多個時間份額(Time Quantum, TQ)構成。關鍵公式:

TQ = BRP × Tclk

其中:

  • Tclk:CAN控制器外設時鐘周期(通常來自系統時鐘分頻)

  • BRP:波特率預分頻器值(寄存器值,通常為5~10位寬)

關于BRP+1的說明:不同芯片廠商的實現有差異。例如: STM32的BTR寄存器中 BRP 字段值為0~1023,實際分頻 = BRP+1 某些老式獨立CAN控制器(如SJA1000)的 BRP 寄存器直接等于分頻值 本文后續代碼采用實際分頻值 = BRP寄存器值 + 1的方式(最通用)。
1.2 位時間的四段結構

一個標準CAN位時間分為四個連續段:

段名稱

長度(TQ)

作用

同步段(SS)

1

固定,用于檢測邊沿

傳播段(PROP)

1~8

補償物理延遲

相位緩沖段1(PBS1)

1~8

采樣點前緩沖,可延長

相位緩沖段2(PBS2)

1~8

采樣點后緩沖,可縮短

采樣點位置 = (SS + PROP + PBS1) / 總TQ數。推薦范圍為70%~80%。

總位時間TQ數= 1 + PROP + PBS1 + PBS2,典型值8~25。

二、同步機制深度解析 2.1 硬同步(Hard Synchronization)

  • 觸發時機:僅在幀起始(SOF)的隱性→顯性跳變沿

  • 動作:接收節點將自己的SS段對齊到這個邊沿

  • 調整幅度:無限制(可以大幅移動)

2.2 重同步(Resynchronization)
  • 觸發時機:SOF之后的任何隱性→顯性跳變沿(需滿足跳變沿在PBS1或PBS2內)

  • 動作:通過延長PBS1縮短PBS2來補償相位誤差

  • 限制:調整量不超過SJW(同步跳轉寬度)

重同步規則

  • 若邊沿發生在PBS1內→ 相位誤差e > 0(接收端慢),延長PBS1

  • 若邊沿發生在PBS2內→ 相位誤差e < 0(接收端快),縮短PBS2

  • 調整量 = min(|e|, SJW)

2.3 為什么SJW取值范圍通常為1~4 TQ?(解答您的疑惑)

這是CAN控制器硬件實現的限制,根源在于:

  1. 采樣點穩定性要求:SJW過大(如≥5)會導致采樣點在位時間內過度漂移,降低噪聲容限。

  2. 振蕩器容差計算:CAN協議標準(ISO 11898-1)根據最大允許振蕩器誤差推導出SJW上限為4。公式如下:

    振蕩器容差 ≤ SJW / (20 × NBT)
    其中NBT為一個位時間的TQ總數。當SJW=4時,可支持±1.58%的晶振誤差(常見晶振為±0.5%~±1.5%)。
  3. 主流控制器事實標準:Bosch CAN 2.0規范建議SJW為1~4,所有主流芯片(STM32、SJA1000、MCP2515)均遵循此范圍。

如果您看到某些文獻中SJW取值可到8,那通常是指CAN FD(可變速率模式)下的擴展配置,經典CAN僅支持1~4。
三、代碼實現示例 3.1 位定時參數計算器(C語言)

以下代碼根據目標波特率、時鐘頻率自動計算BRP和段長度。

#include  

#include
#include

typedef struct {
uint16_t brp; // 波特率分頻器 (實際分頻 = brp+1)
uint8_t prop_seg; // 傳播段長度 (1~8 TQ)
uint8_t pbs1_seg; // 相位緩沖段1 (1~8 TQ)
uint8_t pbs2_seg; // 相位緩沖段2 (1~8 TQ)
uint8_t sjw; // 同步跳轉寬度 (1~4 TQ)
uint8_t sample_point_percent; // 采樣點百分比
} CAN_BitTiming_TypeDef;

/**
* @brief 計算CAN位定時參數
* @param clk_khz CAN控制器時鐘頻率 (kHz)
* @param baud_kbps 目標波特率 (kbps)
* @param target_sp 目標采樣點百分比 (例如 75 表示75%)
* @param timing 輸出參數結構體
* @return 1:成功, 0:失敗
*/
uint8_t CAN_ComputeBitTiming(uint32_t clk_khz, uint32_t baud_kbps,
uint8_t target_sp, CAN_BitTiming_TypeDef *timing)
{
uint32_t best_error = 0xFFFFFFFF;
uint8_t best_brp = 0, best_prop = 1, best_pbs1 = 2, best_pbs2 = 1;
uint32_t actual_baud;
int32_t error;
// 總TQ數范圍: 8~25
for (uint8_t tq_num = 8; tq_num <= 25; tq_num++)
{
// 計算理論TQ時間 (us)
double tq_us = 1000.0 / (baud_kbps * tq_num);
double clk_t_us = 1.0 / clk_khz;
// 計算所需BRP (取整)
uint16_t brp_calc = (uint16_t)(tq_us / clk_t_us + 0.5) - 1;
if (brp_calc < 0 || brp_calc > 1023) continue;
// 實際波特率
actual_baud = clk_khz * 1000 / ((brp_calc+1) * tq_num);
error = (int32_t)actual_baud - (int32_t)(baud_kbps * 1000);
if (error < 0) error = -error;
// 誤差小于0.5%才考慮
if (error * 1000 <= (int32_t)(baud_kbps * 1000 * 5))
{
// 分配段長度: SS=1固定, PROP=1~8, PBS1=1~8, PBS2=1~8
for (uint8_t prop = 1; prop <= 8 && (1+prop+2+1) <= tq_num; prop++)
{
for (uint8_t pbs1 = 1; pbs1 <= 8; pbs1++)
{
uint8_t pbs2 = tq_num - 1 - prop - pbs1;
if (pbs2 < 1 || pbs2 > 8) continue;
if (pbs1 < pbs2) continue; // 要求PBS1 >= PBS2
uint8_t sp = (1 + prop + pbs1) * 100 / tq_num;
if (abs(sp - target_sp) > 5) continue; // 采樣點偏差±5%
// 選擇最優組合 (優先采樣點準確,次選誤差小)
uint32_t current_error = abs(sp - target_sp) * 1000 + error;
if (current_error < best_error) {
best_error = current_error;
best_brp = brp_calc;
best_prop = prop;
best_pbs1 = pbs1;
best_pbs2 = pbs2;
}
}
}
}
}
if (best_error == 0xFFFFFFFF) return 0;
timing->brp = best_brp;
timing->prop_seg = best_prop;
timing->pbs1_seg = best_pbs1;
timing->pbs2_seg = best_pbs2;
timing->sjw = (best_pbs1 < 4) ? best_pbs1 : 4; // SJW不超過PBS1和4
timing->sample_point_percent = (1 + best_prop + best_pbs1) * 100 /
(1 + best_prop + best_pbs1 + best_pbs2);
return 1;
}

// 使用示例
int main(void)
{
CAN_BitTiming_TypeDef timing;
// 假設CAN外設時鐘40MHz,目標波特率500kbps,采樣點75%
if (CAN_ComputeBitTiming(40000, 500, 75, &timing)) {
printf("BRP = %d (實際分頻 %d)\n", timing.brp, timing.brp+1);
printf("PROP_SEG = %d TQ\n", timing.prop_seg);
printf("PBS1 = %d TQ\n", timing.pbs1_seg);
printf("PBS2 = %d TQ\n", timing.pbs2_seg);
printf("SJW = %d TQ\n", timing.sjw);
printf("采樣點 = %d%%\n", timing.sample_point_percent);
printf("總TQ數 = %d\n", 1+timing.prop_seg+timing.pbs1_seg+timing.pbs2_seg);
} else {
printf("未找到合適的位定時參數\n");
}
return 0;
}
3.2 STM32 HAL庫配置示例

#include "stm32f4xx_hal.h"

CAN_HandleTypeDef hcan1;

void CAN1_Config(void)
{
hcan1.Instance = CAN1;
hcan1.Init.Mode = CAN_MODE_NORMAL;
// 手動計算好的參數 (假設APB1=42MHz, 波特率500k, 采樣點75%)
// 總TQ=16, BRP=5 (實際分頻6), 則TQ=6/42M≈142.86ns, 位時間=16*142.86ns≈2.2857us -> 437.5kbps
// 調整為BRP=4 (分頻5), TQ=5/42M≈119ns, 位時間=16*119ns=1.904us -> 525kbps
// 實際更精確的配置:BRP=3(分頻4), TQ=4/42M≈95.24ns, 位時間=20*95.24ns=1.9048us -> 525kbps
// 為了500kbps,需要位時間=2us,TQ=100ns,BRP分頻=42M*100ns=4.2->取4,BRP=3
// 總TQ=20,SS=1,PROP=7,PBS1=6,PBS2=6,采樣點=(1+7+6)/20=70%
hcan1.Init.TimeTriggeredMode = DISABLE;
hcan1.Init.AutoBusOff = DISABLE;
hcan1.Init.AutoWakeUp = DISABLE;
hcan1.Init.AutoRetransmission = ENABLE;
hcan1.Init.ReceiveFifoLocked = DISABLE;
hcan1.Init.TransmitFifoPriority = DISABLE;
// 位定時寄存器 BTR 配置
// STM32的BS1 = PROP + PBS1, BS2 = PBS2, 且BS1/BS2長度=位長-3
// 這里需要根據芯片手冊轉換
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ; // SJW=1
hcan1.Init.TimeSeg1 = CAN_BS1_13TQ; // 13TQ (包含SS)
hcan1.Init.TimeSeg2 = CAN_BS2_6TQ; // 6TQ
hcan1.Init.Prescaler = 4; // BRP=4 (實際分頻=4+1=5)
if (HAL_CAN_Init(&hcan1) != HAL_OK) {
Error_Handler();
}
}
3.3 同步過程模擬(偽代碼)

以下演示接收節點如何根據邊沿誤差調整PBS1/PBS2:

// 接收節點位流處理狀態機
typedef enum {
IDLE,
WAITING_SOF,
RECEIVING_BITS
} CAN_RxState;

CAN_RxState rx_state = WAITING_SOF;
int16_t tq_counter = 0; // 當前位內的TQ計數
int16_t phase_error = 0; // 相位誤差 (TQ單位)

void CAN_Rx_Tick(void) // 每個TQ調用一次
{
if (detect_falling_edge()) { // 隱性->顯性跳變
if (rx_state == WAITING_SOF) {
// 硬同步:直接對齊到SS起點
tq_counter = 0;
rx_state = RECEIVING_BITS;
}
else if (rx_state == RECEIVING_BITS && tq_counter > 0) {
// 重同步:計算相位誤差
if (tq_counter < (ss_len + prop_len + pbs1_len)) {
// 邊沿在PBS1內 -> 節點慢,需要延長PBS1
phase_error = tq_counter - (ss_len + prop_len);
if (phase_error > sjw) phase_error = sjw;
pbs1_extend = phase_error;
pbs2_shorten = 0;
}
else if (tq_counter < total_tq) {
// 邊沿在PBS2內 -> 節點快,需要縮短PBS2
phase_error = (total_tq - tq_counter);
if (phase_error > sjw) phase_error = sjw;
pbs2_shorten = phase_error;
pbs1_extend = 0;
}
}
}
// 采樣點判斷 (位于PBS1結束時刻)
if (tq_counter == (ss_len + prop_len + pbs1_len - 1 + pbs1_extend)) {
sample_bit(); // 讀取總線電平
}
// 位結束,準備下一個位
if (tq_counter >= (total_tq + pbs1_extend - pbs2_shorten - 1)) {
tq_counter = 0;
pbs1_extend = 0;
pbs2_shorten = 0;
} else {
tq_counter++;
}
}
四、總結與最佳實踐

參數

推薦值/范圍

總TQ數

16~20

平衡同步精度與開銷

采樣點

70%~80%

經典CAN常用75%

SJW

1~3

晶振精度高時可取1~2

PROP

根據總線長度

每米總線約需5~10ns,轉換為TQ

BRP

盡可能小

提高采樣分辨率,但注意寄存器范圍

同步設計要點

  • 整個網絡應采用相同的位定時參數

  • 長總線(>40m)需增加PROP段

  • 高波特率(>500k)應減少總TQ數,提高采樣點精度

希望這篇補充了代碼實例和SJW深度解析的文章能對您有所幫助。如果您需要特定MCU(如NXP S32K、Infineon AURIX)的寄存器級配置代碼,我可以進一步提供。

特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相關推薦
熱點推薦
啥都和愛國扯到一起,就是一種病

啥都和愛國扯到一起,就是一種病

老唐有話說
2026-05-14 16:18:17
A股:剛剛,國務院國資委發布,不出意外的話,下周將迎來新變化

A股:剛剛,國務院國資委發布,不出意外的話,下周將迎來新變化

云鵬敘事
2026-05-16 00:00:09
國家發改委主任鄭柵潔會見波音公司總裁奧特伯格

國家發改委主任鄭柵潔會見波音公司總裁奧特伯格

新京報
2026-05-15 20:29:22
上海87-82戰勝北京!賽后數據一清二楚,不是王哲林 最大功臣是他

上海87-82戰勝北京!賽后數據一清二楚,不是王哲林 最大功臣是他

小火箭愛體育
2026-05-15 21:32:09
難怪黃仁勛那么積極跟著特朗普訪華,一到北京就拿下了大額訂單。

難怪黃仁勛那么積極跟著特朗普訪華,一到北京就拿下了大額訂單。

魔都姐姐雜談
2026-05-14 22:09:10
人活多久,看喝酒就知道?壽命短的人,喝酒一般有這6個特征

人活多久,看喝酒就知道?壽命短的人,喝酒一般有這6個特征

芹姐說生活
2026-05-14 23:38:55
上海奪G1但3人需總結!盧偉應變差點,白邊優勢被打沒,弗格太鐵

上海奪G1但3人需總結!盧偉應變差點,白邊優勢被打沒,弗格太鐵

籃球資訊達人
2026-05-16 01:09:21
38.98萬,夸張啊...

38.98萬,夸張啊...

放毒
2026-05-15 19:14:23
中紀委再次重拳出擊!這4個領域將被嚴查,這4種行為將被嚴肅處理

中紀委再次重拳出擊!這4個領域將被嚴查,這4種行為將被嚴肅處理

細說職場
2026-05-15 14:01:05
鄺兆鐳U17亞洲杯首秀!送助攻后或舊傷復發,只踢半場仍獲贊

鄺兆鐳U17亞洲杯首秀!送助攻后或舊傷復發,只踢半場仍獲贊

奧拜爾
2026-05-16 02:13:48
悲催!上海一母親將700萬遺產給兒子,6年后才發現被女兒徹底拉黑

悲催!上海一母親將700萬遺產給兒子,6年后才發現被女兒徹底拉黑

火山詩話
2026-05-15 06:49:15
特朗普還沒回國,就開始放狠話了

特朗普還沒回國,就開始放狠話了

利刃號
2026-05-15 17:16:39
第一次感受到“荔枝核的威力”,泡水里20天,長成“粉盆栽”

第一次感受到“荔枝核的威力”,泡水里20天,長成“粉盆栽”

美家指南
2026-05-15 15:27:43
國宴名場面刷屏:穿紅衣的服務員火了,這才是大國該有的體面

國宴名場面刷屏:穿紅衣的服務員火了,這才是大國該有的體面

娛樂洞察點點
2026-05-15 12:40:18
“錢車兩空”!男子以租代購跑網約車,三年還清13.5萬,過戶前一夜車被拖走

“錢車兩空”!男子以租代購跑網約車,三年還清13.5萬,過戶前一夜車被拖走

網約車觀察室
2026-05-14 10:00:49
張雪宣布停產!博主:雷軍出問題你建議退款 自己出問題只補償

張雪宣布停產!博主:雷軍出問題你建議退款 自己出問題只補償

念洲
2026-05-14 14:29:33
不是洛夫頓!不是古德溫!許利民贊上海隊1人,威廉姆斯傷情出爐

不是洛夫頓!不是古德溫!許利民贊上海隊1人,威廉姆斯傷情出爐

老吳說體育
2026-05-15 23:31:25
這跟不穿有啥區別?趙露思演唱會內衣外穿:被眾嘲一套比一套辣眼

這跟不穿有啥區別?趙露思演唱會內衣外穿:被眾嘲一套比一套辣眼

胡一舸南游y
2026-05-13 15:23:56
看好誰當選臺北市長?1.4萬人網絡投票結果一面倒

看好誰當選臺北市長?1.4萬人網絡投票結果一面倒

新時光點滴
2026-05-16 00:10:48
沙拉維深情告別羅馬:我即將離開,但我的一部分靈魂將永駐于此

沙拉維深情告別羅馬:我即將離開,但我的一部分靈魂將永駐于此

懂球帝
2026-05-16 02:43:35
2026-05-16 02:59:00
新能源自動駕駛 incentive-icons
新能源自動駕駛
專注于半導體行業資訊
977文章數 347關注度
往期回顧 全部

科技要聞

直降千元起步!蘋果華為率先開啟618讓利

頭條要聞

黃仁勛在北京喝豆汁痛苦皺眉 問“這是什么東西”

頭條要聞

黃仁勛在北京喝豆汁痛苦皺眉 問“這是什么東西”

體育要聞

德約科維奇買的球隊,從第6級聯賽升入法甲

娛樂要聞

方媛為何要來《桃花塢6》沒苦硬吃?

財經要聞

騰訊掉隊,馬化騰戳破真相

汽車要聞

高爾夫GTI刷新紐北紀錄 ID. Polo GTI迎全球首秀

態度原創

旅游
本地
健康
教育
公開課

旅游要聞

藏在沈陽鬧市的金色秘境!2 萬㎡油菜花全開,地鐵直達還免費

本地新聞

用蘇繡的方式,打開江西婺源

專家揭秘干細胞回輸的安全風險

教育要聞

2027英國留學費用+排名+雅思要求一篇看懂

公開課

李玫瑾:為什么性格比能力更重要?

無障礙瀏覽 進入關懷版