STM32_CAN通信

 

目錄

 

1:CAN簡介

2:CAN通信幀種類介紹

3:CAN位時序

4:STM32_CAN

5:bx_CAN控制器框圖

6:STM32_CAN發送,接受流程

7:STM32CAN通信位時序

8:STM32CAN代碼實現


1:CAN簡介

CAN是Controller Area Network,是一種串行的通信協議,有兩標準:ISO11898、ISO11519-2,其中ISO11898是針對通信速率爲125Kbps~1Mbps的高速通信標準,而ISO11519-2是針對通信速率爲123Kbps以下的低速通信標準

CAN有很多優點,比如多主控制,速度快,距離遠,具有錯誤檢測,恢復,連接節點多等功能。所以CAN協議特別適合工業過程監控設備的互聯

講下ISO11898標準,物理層特徵如下

CAN控制器根據CAN_L和CAN_H上的點位差來判斷總線電平,總線電平分爲顯性電平和隱形電平,二者必居其一,發送方通過使總線電平發生變化,將消息發送給接收方。

  • 顯性電平對應邏輯:0 CAN_H和CAN_L之差爲2V左右
  • 隱形電平對應邏輯:1 CAN_H和CAN_L之差爲0V

要注意的是,顯性電平比隱形電平強,顯性電平具有優先權,只要有一個單元輸出顯性電平,總線上即爲顯性電平,而隱形電平則具有包容的意味,只要所有單元都輸出隱形電平,總線上才爲隱形電平,

另外,在CAN總線的起止端都有一個120Ω的終端電阻,來做阻抗匹配,以減少回波反射

2:CAN通信幀種類介紹

CAN通信是以以下5鍾類型的幀進行的

數據幀、遙控幀、錯誤幀、過載幀、間隔幀

其中數據幀和遙控幀有標準格式和擴張格式兩種,標準格式有11個位標識符(ID),擴展格式有29個位ID

介紹哈數據幀

  1. 幀起始:表示數據幀開始的段
  2. 仲裁段:表示該幀優先級的段
  3. 控制端:表示數據的字節數及保留位的段
  4. 數據段:數據的內容,一幀可發送0~8·個字節的數據
  5. CRC段:檢查幀的傳輸錯誤的段
  6. ACK段:表示確認正常接受的段
  7. 幀結束:表示數據幀結束的段

3:CAN位時序

位時序:在CAN 通信中,一個位分爲4段,這每個段又由Time Quantum(簡稱Tq)的最小時間單位構成,這個就是位時序

有如下四個段:

  • 同步段(SS)
  • 傳播時間段(PTS)
  • 相位緩衝段1(PBS1)
  • 相位緩衝段2(PBS2)

位時間=1/波特率,因此,知道位時間,我們就可以知道波特率

1 位由多少個Tq 構成、每個段又由多少個Tq 構成等,可以任意設定位時序。通過設定位時序,多個單元可同時採樣,也可任意設定採樣點。

位時序各段的作用和Tq數如下

 

一個位的構成: 

4:STM32_CAN

eg:STM32F407ZGT6

前面只是對CAN通信做一個基本的描述,在STM32上,自帶了基本擴展CAN外設,稱bxCAN,

  • CAN1:主bxCAN,用於管理bxCAN與512字節SRAM存儲器之間的通信。
  • CAN2:從bxCAN,無法直接訪問SRAM存儲器,但兩個bxCAN單元共享512字節SRAM存儲器
  • 波特率最高達1Mbps
  • 支持時間觸發通信
  • 具有3個發送郵箱
  • 具有3級深度的2個接受FIFO
  • 可變的篩選器組(也稱過濾器組,最多28個)

bxCAN有三種主要的工作模式:初始化、正常、睡眠,還有測試模式和調試模式,具體看數據手冊

5:bx_CAN控制器框圖

篩選器組,可以設置你需要的數據,不需要的就不接受,就是爲降低CPU處理CAN通信的開銷

STM32 CAN控制器每個篩選器組由2個32位寄存器組成,根據位寬不同,每個篩選器組可提供1個32位的篩選器或2個16位的篩選器

篩選器可配置爲:屏蔽位模式、標識符列表模式 

通過CAN_FM1R(篩選器模式寄存器)和CAN_FS1R(篩選器尺度寄存器)可配置篩選器的位寬和模式

  • 爲了過濾出一組標識符,應該設置篩選器組工作在屏蔽位模式
  • 爲了過濾出一個標識符,應該設置過濾器工作在標識符列表模式
  • 應用程序不用的篩選器組,應該保持在禁用狀態(通過CAN_FA1R設置)。
  • 通過CAN_FFA1R的設置,可以將篩選器組關聯到FIFO0/FIFO1
  • 篩選器組中的每個篩選器,都被編號爲(即:篩選器編號)從0開始,到某個最大數值-取決於篩選器組的模式和位寬的設置。

6:STM32_CAN發送,接受流程

 報文FIFO具有鎖定功能(由CAN_MCR,RFLM位控制),鎖定後,新數據將丟失,不鎖定則新數據將替代老數據

7:STM32CAN通信位時序

 

8:STM32CAN代碼實現

1:初始化 

  	//CAN單元設置
   	CAN_InitStructure.CAN_TTCM=DISABLE;	//非時間觸發通信模式   
  	CAN_InitStructure.CAN_ABOM=DISABLE;	//軟件自動離線管理	  
  	CAN_InitStructure.CAN_AWUM=DISABLE; //睡眠模式通過軟件喚醒(清除CAN->MCR的SLEEP位)
  	CAN_InitStructure.CAN_NART=ENABLE;	//禁止報文自動傳送 
  	CAN_InitStructure.CAN_RFLM=DISABLE;	//報文不鎖定,新的覆蓋舊的  
  	CAN_InitStructure.CAN_TXFP=DISABLE;	//優先級由報文標識符決定 
  	CAN_InitStructure.CAN_Mode= mode;	//模式設置 
  	CAN_InitStructure.CAN_SJW=tsjw;	    
//重新同步跳躍寬度(Tsjw)爲tsjw+1個時間單位 CAN_SJW_1tq~CAN_SJW_4tq
  	CAN_InitStructure.CAN_BS1=tbs1;     //Tbs1範圍CAN_BS1_1tq ~CAN_BS1_16tq
  	CAN_InitStructure.CAN_BS2=tbs2;     //Tbs2範圍CAN_BS2_1tq ~	CAN_BS2_8tq
  	CAN_InitStructure.CAN_Prescaler=brp;  //分頻係數(Fdiv)爲brp+1	
  	CAN_Init(CAN1, &CAN_InitStructure);   // 初始化CAN1 
    
		//配置過濾器
 	CAN_FilterInitStructure.CAN_FilterNumber=0;	                   //過濾器0
  	CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; 
  	CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32位 
  	CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;               //32位ID
  	CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
  	CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;           //32位MASK
  	CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
   	CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//過濾器0關聯到FIFO0
  	CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;              //激活過濾器0
  	CAN_FilterInit(&CAN_FilterInitStructure);                         //濾波器初始化

相應引腳配置位複用推輓輸出加上拉模式

  1. CAN_TTCM:操作CAN_MCR主控制寄存器的位7
  2. CAN_ABOM:操作CAN_MCR主控制寄存器的位6
  3. CAN_AWU:M操作CAN_MCR主控制寄存器的位5
  4. CAN_NART:操作CAN_MCR主控制寄存器的位4
  5. CAN_RFLM:操作CAN_MCR主控制寄存器的位3
  6. CAN_TXFP:操作CAN_MCR主控制寄存器的位2
  7. CAN_Mode:操作CAN_BTR位時序寄存器的位31,30
  8. CAN_SJW:操作CAN_BTR位時序寄存器的位25,24
  9. CAN_BS1:操作CAN_BTR位時序寄存器的位19~16
  10. CAN_BS2:操作CAN_BTR位時序寄存器的位22~20
  11. CAN_Prescaler:操作CAN_BTR位時序寄存器的位9~0

配置過濾器

  1. CAN_FilterNumber:操作CAN_FA1R篩選器激活寄存器的位27:0
  2. CAN_FilterMode:操作CAN_FM1R篩選器模式寄存器的位27:0
  3. CAN_FilterScale:操作CAN_FS1R篩選器尺度寄存器的位27:0和CAN_FiRx篩選器組i寄存器
  4. CAN_FilterIdHighCAN_FilterIdLowCAN_FilterMaskIdHighCAN_FilterMaskIdLow都是配合操作CAN_FiRx篩選器組i寄存器
  5. CAN_FilterFIFOAssignment:操作CAN_FFA1R篩選器FIFO分配寄存器的位27:0
  6. CAN_FilterActivation:操作CAN_FA1R篩選器激活寄存器的位27:0

2:發送數據

u8 CAN1_Send_Msg(u8* msg,u8 len)
{	
  u8 mbox;
  u16 i=0;
  CanTxMsg TxMessage;
  TxMessage.StdId=0x12;	  // 標準標識符爲0
  TxMessage.ExtId=0x12;	  // 設置擴展標示符(29位)
  TxMessage.IDE=0;		  // 使用擴展標識符
  TxMessage.RTR=0;		  // 消息類型爲數據幀,一幀8位
  TxMessage.DLC=len;							 // 發送兩幀信息
  for(i=0;i<len;i++)
  TxMessage.Data[i]=msg[i];				 // 第一幀信息          
  mbox= CAN_Transmit(CAN1, &TxMessage);   
  i=0;
  while((CAN_TransmitStatus(CAN1, mbox)==CAN_TxStatus_Failed)&&(i<0XFFF))i++;	//等待發送結束
  if(i>=0XFFF)return 1;
  return 0;		

}
  1. StdIdIDERTR  :在IDE的基礎上,決定在CAN_TIxR發送郵箱標識符寄存器上標識符類型和幀類型
  2. ExtIdIDERTR:在IDE的基礎上,決定在CAN_TIxR發送郵箱標識符寄存器上標識符類型和幀類型
  3. len:操作CAN_TDTxR郵箱數據長度控制和時間戳寄存器的位3:0
  4. Data:操作CAN_TDL\HxR郵箱數據低\高寄存器
  5. 最後查詢CAN_TSR發送狀態寄存器,等待發送結束

 3:接受數據

u8 CAN1_Receive_Msg(u8 *buf)
{		   		   
 	u32 i;
	CanRxMsg RxMessage;
    if( CAN_MessagePending(CAN1,CAN_FIFO0)==0)return 0;		//沒有接收到數據,直接退出 
    CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);//讀取數據	
    for(i=0;i<RxMessage.DLC;i++)
    buf[i]=RxMessage.Data[i];  
	return RxMessage.DLC;	
}
  1. 先查詢CAN_RF0R接受FIFI 0寄存器的位1:0
  2. 然後去讀取CAN_RDL\HxR接受FIFO郵箱數據低\高位寄存器的數據存放在RxMessage.Data中
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章