1.CAN是控制器局域網絡(Controller Area Network, CAN)的簡稱
(理論知識不做講解了,太多了)
2.芯片選用:TJA1050

差分信號輸入,
這里的顯性電平CANH和CANL壓差是2V左右,邏輯上表示“0”
兩線之間沒有壓差CANH和CANL都是2.5V左右,表示邏輯“1”
(二)實現代碼
1.
/* 配置CAN模塊*/ CAN_Config();
void CAN_Config(void)
{
①CAN_GPIO_Config(); //此處用PB8/PB9
CAN_NVIC_Config();
CAN_Mode_Config();
CAN_Filter_Config();
}
②對於CAN_NVIC_Config();
看下CAN 的中斷分類

static void CAN_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure one bit for preemption priority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/*中斷設置*/
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn; //CAN1 RX0中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //搶占優先級0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子優先級0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
③CAN_Mode_Config(); //CAN不像I2C那樣有片選,他背身有許多協議,也要進行選擇,所以對應代碼的結構體也多(集體可看CAN手冊)
④CAN_Filter_Config(); 過濾器程序
看下CAN的主要框圖(M3里面的CAN)

M3里面有三個發送郵箱,把要發送的數據打包成報文,然后把它發送到CAN網絡總線上;
接收器 先經過濾器,M3里面有14個過濾器,過濾的時候是根據報文的ID來過濾的,ID相同的話,才能過去(相當於一個閘門)
接收到數據后(這里有兩個FIFO ,0、1 ),我們的實驗用的是 放到FIFO 的Mailbox 0;
代碼寫法根基三部分:
1.Tx Mailboxes 2.Acceptance Filters 3.Receive FIFO

STM32 的 ID 過濾方式有兩種,一種為標識符列表模式,它把要接收報文
的 ID 列成一個表,要求報文 ID 與列表中的某一個標識符完全相同才可以接
收,可以理解為白名單管理。(說白了就是有一個標志位相同,然后就聯通了)
另一種稱為標識符屏蔽模式,它把可接收報文 ID 的某幾位作為列表,這幾
位被稱為屏蔽位,可以把它理解成關鍵字搜索,只要屏蔽位(關鍵字)相同,就
符合要求。即這種模式只要求報文 ID 的屏蔽位與列表中標識符相應屏蔽位相
同 ,報文就被保存到接收 FIFO。(標志位的某幾位檢驗,相同的話就通過了)
2.什么叫做報文(就是幀)
在原始數據段的前面加上傳輸起始標簽、片選(識別)標簽、控制標簽,在
數據的尾段加上 CRC 校驗標簽、應答標簽和傳輸結束標簽。把這些內容按特定
的格式打包好,就可以用一個通道表達各種信號了,各種各樣的標簽就如同
SPI 中各種通道上的信號,起到了協同傳輸的作用。當整個數據包被傳輸到其
它設備時,只要這些設備按格式去解讀,就能還原出原始數據。類似這樣的數
據包就被稱為 CAN的數據幀。

看下數據幀

擴展與標准 仲裁段不一樣,擴展11+18 = 29位
仲裁段:告訴是發還是收(幾個同時通信的時候,那那根的信號,拉低了就是誰的了)如:

總電平接收了節點2的^_^(can的神奇之處)
CRC:發送與接收的對應
IDE:用於區分標准幀與擴展幀
r0、r1 都是顯性位
3.CAN通信報文內容設置
void CAN_SetMsg(void)
4.發送消息,“ABCD”
CAN_Transmit(CAN1, &TxMessage);
總體流程圖(例程對應):

while( flag == 0xff ); //flag =0 ,success ,此時產生一個中斷(CAN中斷)
對於從機的CAN_Config(); 是一模一樣
不一樣的是從機先上電
中斷函數時一樣的
CAN線接的時候 CANH接CANH, CANL接CANL, 不能對接
