CAN通信(STM32)


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,  不能對接

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM