CAN 總線使用兩根線來連接各個(gè)單元:CAN_H 和 CAN_L,CAN 控制器通過判斷這兩根線上的電位差來得到總線電平,CAN總線電平分為顯性電平和隱性電平兩種。
顯性電平表示邏輯“0”,此時(shí) CAN_H 電平比 CAN_L 高,分別為 3.5V 和 1.5V,電位差為2V。隱形電平表示邏輯“1”,此時(shí) CAN_H 和 CAN_L 電壓都為 2.5V 左右,電位差為 0V。CAN總線就通過顯性和隱形電平的變化來將具體的數(shù)據(jù)發(fā)送出去,如圖所示:
CAN 總線上沒有節(jié)點(diǎn)傳輸數(shù)據(jù)的時(shí)候一直處于隱性狀態(tài),也就是說總線空閑狀態(tài)的時(shí)候一直處于隱性。CAN 網(wǎng)絡(luò)中的所有單元都通過 CAN_H 和CAN_L 這兩根線連接在一起,如圖所示:
途中所有的 CAN 節(jié)點(diǎn)單元都采用 CAN_H 和 CAN_L 這兩根線連接在一起,CAN_H 接CAN_H、CAN_L 接 CAN_L,CAN總線兩端要各接一個(gè) 120Ω的端接電阻,用于匹配總線阻抗,吸收信號(hào)反射及回?fù)?,提高?shù)據(jù)通信的抗干擾能力以及可靠性。
CAN 總線傳輸速度可達(dá) 1Mbps/S,最新的 CAN-FD 最高速度可達(dá) 5Mbps/S,甚至更高,感興趣的可以自行查閱相關(guān)資料。CAN傳輸速度和總線距離有關(guān),總線距離越短,傳輸速度越快。
uint32_tFilterScale;/*設(shè)置篩選器的尺度*/
uint32_tFilterActivation;/*是否使能本篩選器*/
uint32_tSlaveStartFilterBank;
}CAN_FilterTypeDef;
這些結(jié)構(gòu)體成員都是“41.2.14 驗(yàn)收篩選器”小節(jié)介紹的內(nèi)容,可對(duì)比閱讀,各個(gè)結(jié)構(gòu)體成員的介紹如下:
(1) FilterIdHigh
FilterIdHigh 成員用于存儲(chǔ)要篩選的 ID,若篩選器工作在 32 位模式,它存儲(chǔ)的是所篩選 ID 的高 16 位;若篩選器工作在 16 位模式,它存儲(chǔ)的就是一個(gè)完整的要篩選的 ID。
(2) FilterIdLow
類似地,F(xiàn)ilterIdLow 成員也是用于存儲(chǔ)要篩選的 ID,若篩選器工作在 32 位模式,它存儲(chǔ)的是所篩選 ID 的低 16 位;若篩選器工作在 16 位模式,它存儲(chǔ)的就是一個(gè)完整的要篩選的 ID。
(3) FilterMaskIdHigh
FilterMaskIdHigh 存儲(chǔ)的內(nèi)容分兩種情況,當(dāng)篩選器工作在標(biāo)識(shí)符列表模式時(shí),它的功能與 FilterIdHigh 相同,都是存儲(chǔ)要篩選的 ID;而當(dāng)篩選器工作在掩碼模式時(shí),它存儲(chǔ)的是 FilterIdHigh 成員對(duì)應(yīng)的掩碼,與 FilterIdLow 組成一組篩選器。
(4) FilterMaskIdLow
類似地, FilterMaskIdLow 存儲(chǔ)的內(nèi)容也分兩種情況,當(dāng)篩選器工作在標(biāo)識(shí)符列表模式時(shí),它的功能與 FilterIdLow 相同,都是存儲(chǔ)要篩選的 ID;而當(dāng)篩選器工作在掩碼模式時(shí),它存儲(chǔ)的是 FilterIdLow 成員對(duì)應(yīng)的掩碼,與 FilterIdLow 組成一組篩選器。上面四個(gè)結(jié)構(gòu)體的存儲(chǔ)的內(nèi)容很容易讓人糊涂,請(qǐng)結(jié)合前面的圖 39_0_15 和下面的表 39?7 理解,如果還搞不清楚,再結(jié)合庫(kù)函數(shù) FilterInit 的源碼來分析。
表不同模式下各結(jié)構(gòu)體成員的內(nèi)容
對(duì)這些結(jié)構(gòu)體成員賦值的時(shí)候,還要注意寄存器位的映射,即注意哪部分代表 STID,哪部分代表 EXID 以及 IDE、RTR 位。
(5) FilterFIFOAssignment
本成員用于設(shè)置當(dāng)報(bào)文通過篩選器的匹配后,該報(bào)文會(huì)被存儲(chǔ)到哪一個(gè)接收 FIFO,它的可選值為 FIFO0 或 FIFO1(宏 CAN_FILTER_FIFO0/1)。
(6) FilterBank
本成員用于設(shè)置篩選器的編號(hào),即本過濾器結(jié)構(gòu)體配置的是哪一組篩選器,CAN 一共有 28 個(gè)篩選器,所以它的可輸入參數(shù)范圍為 0-27。
(7) FilterMode
本 成 員 用 于 設(shè) 置 篩 選 器 的 工 作 模 式, 可 以 設(shè) 置 為 列 表 模 式 (宏CAN_FILTERMODE_IDLIST) 及掩碼模式 (宏 CAN_FILTERMODE_IDMASK)。
(8) FilterScale
本成員用于設(shè)置篩選器的尺度,可以設(shè)置為 32 位長(zhǎng) (宏 CAN_FILTERSCALE_32BIT)及 16 位長(zhǎng) (宏 CAN_FILTERSCALE_16BIT)。
(9) FilterActivation
本成員用于設(shè)置是否激活這個(gè)篩選器 (宏 ENABLE/DISABLE)。
三、CAN Cubemx配置我們通過問題來熟悉下cubemx配置,你熟悉了這些問題基本就知道怎么配置了!
問題:Parameter Settings分別都是設(shè)置什么的?答案:如圖
問題:怎么配置波特率呢?
答案:用我上面貼的工具(CAN波特率計(jì)算 f103AHP1_36M f407AHP1_42M 采樣點(diǎn)軟件有說明.rar)直接配置,舉兩個(gè)個(gè)例子
例子1:我們要配置成500KHz,那么我們這樣配置
我們用采集點(diǎn)為80%,所以BS1為4tq,BS2為2tq,分頻系數(shù)為12,代進(jìn)公式Fpclk1/((CAN_BS1+CAN_BS2+1)*CAN_Prescaler)=42M/(4+2+1)/12=500kHz
例子2:我們要配置成1M Hz,那么我們這樣配置
我們用采集點(diǎn)為75%,所以BS1為3tq,BS2為2tq,分頻系數(shù)為7,代進(jìn)公式Fpclk1/((CAN_BS1+CAN_BS2+1)*CAN_Prescaler)=42M/(3+2+1)/7=1MHz
問題:Basic Parameter分別是啥意思呢?
Timer Triggered Communication Mode:否使用時(shí)間觸發(fā)功能 (ENABLE/DISABLE),時(shí)間觸發(fā)功能在某些CAN 標(biāo)準(zhǔn)中會(huì)使用到。
Automatic Bus-Off Management:用于設(shè)置是否使用自動(dòng)離線管理功能 (ENABLE/DISABLE),使用自動(dòng)離線管理可以在出錯(cuò)時(shí)離線后適時(shí)自動(dòng)恢復(fù),不需要軟件干預(yù)。
Automatic Wake-Up Mode:用于設(shè)置是否使用自動(dòng)喚醒功能 (ENABLE/DISABLE),使能自動(dòng)喚醒功能后它會(huì)在監(jiān)測(cè)到總線活動(dòng)后自動(dòng)喚醒。
Automatic Retransmission:用于設(shè)置是否使用自動(dòng)重傳功能 (ENABLE/DISABLE),使用自動(dòng)重傳功能時(shí),會(huì)一直發(fā)送報(bào)文直到成功為止。
Receive Fifo Locked Mode:用于設(shè)置是否使用鎖定接收 FIFO(ENABLE/DISABLE),鎖定接收 FIFO 后,若FIFO 溢出時(shí)會(huì)丟棄新數(shù)據(jù),否則在 FIFO 溢出時(shí)以新數(shù)據(jù)覆蓋舊數(shù)據(jù)。
Transmit Fifo Priority:用于設(shè)置發(fā)送報(bào)文的優(yōu)先級(jí)判定方法 (ENABLE/DISABLE),使能時(shí),以報(bào)文存入發(fā)送郵箱的先后順序來發(fā)送,否則按照?qǐng)?bào)文 ID 的優(yōu)先級(jí)來發(fā)送。配置完這些結(jié)構(gòu)體成員后,我們調(diào)用庫(kù)函數(shù) HAL_CAN_Init 即可把這些參數(shù)寫入到 CAN 控制寄存器中,實(shí)現(xiàn) CAN 的初始化
問題:為啥CAN分為RX0,RX1中斷呢?
答案:STM32有2個(gè)3級(jí)深度的接收緩沖區(qū):FIFO0和FIFO1,每個(gè)FIFO都可以存放3個(gè)完整的報(bào)文,它們完全由硬件來管理。如果是來自FIFO0的接收中斷,則用CAN1_RX0_IRQn中斷來處理。如果是來自FIFO1的接收中斷,則用CAN1_RX1_IRQn中斷來處理,如圖:
問題:CAN SCE中斷時(shí)什么?
答案:status chanege error,錯(cuò)誤和狀態(tài)變化中斷!
四、CAN分析工具的使用下面我們會(huì)用到CAN分析工具,還是比較好用的,此部分使用作為自己使用
五、實(shí)驗(yàn)https://www.zhcxgd.com/h-col-112.html
1.Normal模式測(cè)試500K 波特率(定時(shí)發(fā)送,輪詢接收)
1.1 CubeMx配置
1.2 設(shè)置Filter過濾,我們只使能FIFO0,并且不過濾任何消息
uint8_tbsp_can1_filter_config(void)
{
CAN_FilterTypeDeffilter={0};
filter.FilterActivation=ENABLE;
filter.FilterMode=CAN_FILTERMODE_IDMASK;
filter.FilterScale=CAN_FILTERSCALE_32BIT;
filter.FilterBank=0;
filter.FilterFIFOAssignment=CAN_FILTER_FIFO0;
filter.FilterIdLow=0;
filter.FilterIdHigh=0;
filter.FilterMaskIdLow=0;
filter.FilterMaskIdHigh=0;
HAL_CAN_ConfigFilter(&hcan1,&filter);
returnBSP_CAN_OK;
}
1.3 開啟CAN(注意,默認(rèn)Cubemx生成的代碼并沒有can start)
HAL_CAN_Start(&hcan1);
1.4 編寫發(fā)送函數(shù)
我們開出了幾個(gè)參數(shù),id_type是擴(kuò)展幀還是標(biāo)準(zhǔn)幀,basic_id標(biāo)準(zhǔn)幀ID(在標(biāo)準(zhǔn)幀中有效),ex_id擴(kuò)展幀ID(在擴(kuò)展幀中有效),data要發(fā)送的數(shù)據(jù),data_len要發(fā)送的數(shù)據(jù)長(zhǎng)度
uint8_tbsp_can1_send_msg(uint32_tid_type,uint32_tbasic_id,uint32_tex_id,uint8_t*data,uint32_tdata_len)
{
uint8_tindex=0;
uint32_t*msg_box;
uint8_tsend_buf[8]={0};
CAN_TxHeaderTypeDefsend_msg_hdr;
send_msg_hdr.StdId=basic_id;
send_msg_hdr.ExtId=ex_id;
send_msg_hdr.IDE=id_type;
send_msg_hdr.RTR=CAN_RTR_DATA;
send_msg_hdr.DLC=data_len;
send_msg_hdr.TransmitGlobalTime=DISABLE;
for(index=0;indexreturnBSP_CAN_OK;
}
我們?cè)趍ain函數(shù)中1s發(fā)送一幀,標(biāo)準(zhǔn)幀跟擴(kuò)展幀交叉調(diào)用,代碼如下:
send_data[0]++;
send_data[1]++;
send_data[2]++;
send_data[3]++;
send_data[4]++;
send_data[5]++;
send_data[6]++;
send_data[7]++;
if(id_type_std==1)
{
bsp_can1_send_msg(CAN_ID_STD,1,2,send_data,8);
id_type_std=0;
}
else
{
bsp_can1_send_msg(CAN_ID_EXT,1,2,send_data,8);
id_type_std=1;
}
HAL_Delay(1000);
我們通過CAN協(xié)議分析儀來抓下結(jié)果
1.5 編寫輪詢接收函數(shù)
uint8_tbsp_can1_polling_recv_msg(uint32_t*basic_id,uint32_t*ex_id,uint8_t*data,uint32_t*data_len)
{
uint8_tindex=0;
uint8_trecv_data[8];
CAN_RxHeaderTypeDefheader;
while(HAL_CAN_GetRxFifoFillLevel(&hcan1,CAN_RX_FIFO0)!=0)
{
if(__HAL_CAN_GET_FLAG(&hcan1,CAN_FLAG_FOV0)!=RESET)
printf("[CAN]FIFO0overrun!
");
HAL_CAN_GetRxMessage(&hcan1,CAN_RX_FIFO0,&header,recv_data);
if(header.IDE==CAN_ID_STD)
{
printf("StdIdID:%d
",header.StdId);
}
else
{
printf("ExtIdID:%d
",header.ExtId);
}
printf("CANIDE:0x%x
",header.IDE);
printf("CANRTR:0x%x
",header.RTR);
printf("CANDLC:0x%x
",header.DLC);
printf("RECVDATA:");
for(index=0;indexprintf("0x%x",recv_data[index]);
}
printf("
");
}
}
實(shí)驗(yàn)一總結(jié):
1.沒用調(diào)用HAL_CAN_Start(&hcan1);使能CAN
2.沒有編寫Filter函數(shù),我開始自認(rèn)為不設(shè)置就默認(rèn)不過濾,現(xiàn)在看來是我想多了,其實(shí)想想也合理,你如果不過濾分配FIFO,STM32怎么決定把收到的放到哪個(gè)FIFO中
待提升:
1.目前只用到FIFO0,待把FIFO1使用起來2.Normal模式測(cè)試500K 波特率(定時(shí)發(fā)送,中斷接收)
2.1 CubeMx配置
步驟2,3,4跟polling完全一致,我們來直接說下中斷怎么用(主要是使能notifity就行了)
staticvoidMX_CAN1_Init(void)
{
/*USERCODEBEGINCAN1_Init0*/
/*USERCODEENDCAN1_Init0*/
/*USERCODEBEGINCAN1_Init1*/
/*USERCODEENDCAN1_Init1*/
hcan1.Instance=CAN1;
hcan1.Init.Prescaler=12;
hcan1.Init.Mode=CAN_MODE_NORMAL;
hcan1.Init.SyncJumpWidth=CAN_SJW_1TQ;
hcan1.Init.TimeSeg1=CAN_BS1_4TQ;
hcan1.Init.TimeSeg2=CAN_BS2_2TQ;
hcan1.Init.TimeTriggeredMode=DISABLE;
hcan1.Init.AutoBusOff=ENABLE;
hcan1.Init.AutoWakeUp=ENABLE;
hcan1.Init.AutoRetransmission=DISABLE;
hcan1.Init.ReceiveFifoLocked=DISABLE;
hcan1.Init.TransmitFifoPriority=DISABLE;
if(HAL_CAN_Init(&hcan1)!=HAL_OK)
{
Error_Handler();
}
/*USERCODEBEGINCAN1_Init2*/
bsp_can1_filter_config();
HAL_CAN_Start(&hcan1);
HAL_CAN_ActivateNotification(&hcan1,CAN_IT_RX_FIFO0_MSG_PENDING);
/*USERCODEENDCAN1_Init2*/
}
下面我們來編寫下中斷函數(shù)
voidHAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef*hcan) { uint8_tindex=0; uint8_trecv_data[8]; CAN_RxHeaderTypeDefheader; HAL_CAN_GetRxMessage(&hcan1,CAN_RX_FIFO0,&header,recv_data); if(header.IDE==CAN_ID_STD) { printf("StdIdID:%d ",header.StdId); } else { printf("ExtIdID:%d ",header.ExtId); } printf("CANIDE:0x%x ",header.IDE); printf("CANRTR:0x%x ",header.RTR); printf("CANDLC:0x%x ",header.DLC); printf("RECVDATA:"); for(index=0;indexprintf("0x%x",recv_data[index]); } printf(" ");
-
CAN
+關(guān)注
關(guān)注
57文章
2762瀏覽量
464014 -
電氣
+關(guān)注
關(guān)注
18文章
1169瀏覽量
53205 -
總線
+關(guān)注
關(guān)注
10文章
2894瀏覽量
88224
原文標(biāo)題:CAN電氣特性屬性
文章出處:【微信號(hào):智能汽車電子與軟件,微信公眾號(hào):智能汽車電子與軟件】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論