can總線-stm32

1、什麼是can總線?html

can總線由於使用電壓差表示邏輯1和0,因此抗干擾性強,傳播距離遠(500kbps 時130M),比特率越小越遠編程

1.can有幾根線?函數

  2根,can_H ,can_Lui

2.can怎麼表示1,0?編碼

  can_H - can_L > 0.9V ,爲邏輯 0,也稱爲顯性電平。spa

  can_H - can_L < 0.5v ,爲邏輯1,也稱爲隱性電平。3d

通常can_H爲3.5V , 2.5Vorm

通常can_L爲2.5V ,1.5Vhtm

2、stm32 怎麼使用can總線blog

1.can接口在哪?

  

  stm32有can總線控制器,以及有庫函數stm32f10x_can.c能夠驅動該控制器

  但stm32只是有can總線控制器,要真正鏈接can總線,她還要外接can總線收發器,才能分出來can_H ,can_L,例如以下芯片:

  這個芯片的主要做用是發送時根據TXD的電平來決定can_H 和can_L的電平,以及接收時根據can_H 和 can_L的電平差來決定RXD的電平。

 

2.can概念入門比較好的文檔

https://wenku.baidu.com/view/7701528a6529647d2728520f.html

這個文檔比較詳細的介紹了can幀的類型,以及各個幀每一個字節,每一個bit的含義,以及優先級仲裁機制。下面的例程是數據幀。

3.can例程。

 

複製代碼
 1 #ifndef CAN_H_
 2 #define CAN_H_
 3 #include "stm32f10x.h"
 4 #define RCC_APBxPeriph_CAN_IO RCC_APB2Periph_GPIOA
 5 #define CAN_RXD GPIO_Pin_11
 6 #define CAN_TXD GPIO_Pin_12
 7 #define CAN_IO  GPIOA
 8 
 9 enum canrate_e
10 {
11     CANRATE125K=125,
12     CANRATE250K=250,
13     CANRATE500K=500,
14     CANNOTLINK,
15 };
16 
17 enum canStdExt_e
18 {
19     CANSTD=0,
20     CANEXT=1,
21 };
22 struct canrxtx_s
23 {
24     CanRxMsg rxMessage[3];
25     u8 rx_newflag;
26     uint32_t f;
27     CanTxMsg txMessage;
28 
29 };
30 
31 /*std ID*/
32 #define CAN1_TX_STD_ID 0x7DF //11 Bits ID,Functional
33 
34 #define CAN1_TX_STD_ID_ECM 0x7E0 //11 Bits  ECM ID,physical 
35 #define CAN1_RX_STD_ID_ECM 0x7E8 //11 Bits  ECM ID,physical 
36 #define CAN1_RX_STD_Filter 0x7FF //11 bits ECM Filter
37 
38 /*extend ID*/
39 #define CAN1_TX_EXT_ID 0x18DB33F1 //29 Bits  ID,Functional
40 #define CAN_Id_Extended_HONDA 0x18DBEFF1 //29 Bits  ID,Functional   HONDA
41 #endif
複製代碼

 

複製代碼
  1 #include "can.h"
  2 #include <string.h>
  3 u8 std_or_ext;
  4 struct canrxtx_s canrxtx;
  5 void CAN1_init(enum canrate_e canrate)
  6 {
  7     
  8     GPIO_InitTypeDef GPIO_InitStructure;
  9     CAN_InitTypeDef  CAN_InitStructure;
 10     
 11     RCC_APB2PeriphClockCmd(RCC_APBxPeriph_CAN_IO | RCC_APB2Periph_AFIO,ENABLE);
 12     RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,ENABLE);
 13     GPIO_InitStructure.GPIO_Pin = CAN_RXD;
 14     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
 15     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 16     GPIO_Init(CAN_IO, &GPIO_InitStructure);
 17 
 18     GPIO_InitStructure.GPIO_Pin = CAN_TXD;
 19     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
 20     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 21     GPIO_Init(CAN_IO, &GPIO_InitStructure);
 22 
 23     CAN_DeInit(CAN1);
 24     CAN_StructInit(&CAN_InitStructure);
 25 
 26     CAN_InitStructure.CAN_TTCM = DISABLE;
 27     CAN_InitStructure.CAN_ABOM = DISABLE;
 28     CAN_InitStructure.CAN_AWUM = DISABLE;
 29     CAN_InitStructure.CAN_NART = DISABLE;
 30     CAN_InitStructure.CAN_RFLM = DISABLE;
 31     CAN_InitStructure.CAN_TXFP = DISABLE;
 32     CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
 33     CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;  
 34     CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;
 35     CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq;
 36      //CAN BaudRate = 72MHz/(CAN_SJW+CAN_BS1+CAN_BS2)/CAN_Prescaler 
 37      if(canrate==CANRATE125K) /* 125KBps */
 38          CAN_InitStructure.CAN_Prescaler =96;
 39      else if(canrate==CANRATE250K) /* 250KBps */
 40          CAN_InitStructure.CAN_Prescaler =48;
 41      else  /* 500KBps */
 42          CAN_InitStructure.CAN_Prescaler = 24;
 43     
 44     CAN_Init(CAN1, &CAN_InitStructure);
 45 }
 46 
 47 void CAN1_ConfigFilter(u32 id1, u32 id2, u32 mask1, u32 mask2, u8 std_or_ext)                                                                             
 48 { 
 49     CAN_FilterInitTypeDef  CAN_FilterInitStructure;                                                                       
 50     NVIC_InitTypeDef  NVIC_InitStructure;
 51      
 52     CAN_FilterInitStructure.CAN_FilterNumber=1; //use which filter,0~13                                                                          
 53     CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
 54     if(std_or_ext == CANSTD)
 55     {
 56         CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;
 57         CAN_FilterInitStructure.CAN_FilterIdHigh=id1<<5;                                                                   
 58         CAN_FilterInitStructure.CAN_FilterIdLow=id2<<5;                                                                       
 59         CAN_FilterInitStructure.CAN_FilterMaskIdHigh=mask1<<5;                                                                    
 60         CAN_FilterInitStructure.CAN_FilterMaskIdLow=mask2<<5;    
 61     
 62     }
 63     else 
 64     {
 65         CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
 66         CAN_FilterInitStructure.CAN_FilterIdHigh=(u16) (id1>>13);                                                                       
 67         CAN_FilterInitStructure.CAN_FilterIdLow=(u16) (((id1&0x00001FFF)<<3)|CAN_Id_Extended|CAN_RTR_DATA);                                                                       
 68         CAN_FilterInitStructure.CAN_FilterMaskIdHigh=(u16) (mask1>>13);                                                                    
 69         CAN_FilterInitStructure.CAN_FilterMaskIdLow=(u16) ((mask1&0x00001FFF)<<3);
 70         
 71     }        
 72                                                             
 73     CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;                                                           
 74     CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;                                                                                                                                                                                       
 75     CAN_FilterInit(&CAN_FilterInitStructure);
 76     
 77     NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX1_IRQn; 
 78 
 79     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
 80     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
 81     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
 82     NVIC_Init(&NVIC_InitStructure);
 83 
 84     CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
 85 }
 86 /************************init******************************/
 87 void init_demo()
 88 {
 89     std_or_ext = CANEXT;
 90     CAN1_init(CANRATE500K);
 91     CAN1_ConfigFilter(0x18DAF110,0x18DAF110,0x1FFFF100,0x1FFFF100,std_or_ext);//extend ID
 92 }
 93 /************************tx******************************/
 94 /*datalen<=8*/
 95 int CAN1_TransASerialData(u8* pdata,u8 datalen)
 96 {
 97     u8 i=0;
 98 
 99     Delay_ms(20);
100 
101     if(std_or_ext == CANEXT)
102     {
103         canrxtx.txMessage.StdId=0x00;
104         canrxtx.txMessage.ExtId=CAN_Id_Extended_HONDA;//bentian 
105         canrxtx.txMessage.RTR=CAN_RTR_DATA;        
106         canrxtx.txMessage.IDE=CAN_Id_Extended;// 29 bits
107         
108     }
109     if(std_or_ext== CANSTD)
110     {
111         canrxtx.txMessage.StdId=CAN1_TX_STD_ID;
112         canrxtx.txMessage.ExtId=0x00;
113         canrxtx.txMessage.RTR=CAN_RTR_DATA;        
114         canrxtx.txMessage.IDE=CAN_Id_Standard;//11 bits 
115     }
116 
117     canrxtx.txMessage.DLC=0x08;
118     canrxtx.txMessage.Data[0]=datalen;
119     memcpy(&(canrxtx.txMessage.Data[1]),pdata,datalen);
120 
121 
122     while(((i++)<3)&&(CAN_TxStatus_NoMailBox==CAN_Transmit( CAN1,&canrxtx.txMessage)))
123         
124     if(i>=3)    //timeout
125     {
126         return (-1);
127     }
128 
129     canrxtx.rx_newflag=0;
130     return (0);
131     
132 }
133 /************************rx******************************/
134 void CAN1_RX1_IRQHandler(void)
135 {
136     memset(&canrxtx.rxMessage,0,sizeof(CanRxMsg));
137     if(CAN_MessagePending(CAN1,CAN_FIFO0))
138         {
139             CAN_Receive(CAN1,CAN_FIFO0,&canrxtx.rxMessage[0]);    
140         }
141     canrxtx.rx_newflag=1;
142 }
複製代碼

 3、標識符過濾器的解釋

過濾器只是用於接收,判斷某個報文是否能經過過濾器,過濾器初始化以下:
 53     CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; 
 56         CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;  57 CAN_FilterInitStructure.CAN_FilterIdHigh=id1<<5;  58 CAN_FilterInitStructure.CAN_FilterIdLow=id2<<5;  59 CAN_FilterInitStructure.CAN_FilterMaskIdHigh=mask1<<5;  60 CAN_FilterInitStructure.CAN_FilterMaskIdLow=mask2<<5; 
stm32有0~13個過濾器組,每一個過濾器組有兩個32位的寄存器,經過設置下面兩個結構體成員的值能夠有四種組合:
CAN_FilterModeCAN_FilterScale 

 

 

 4、關於郵箱

以下圖,發送3個郵箱,接收每一個FIFO 3個郵箱,這是硬件自動管理的,軟件不用管,只要判斷髮送成不成功,中斷接收哪一個FIFO就好了(要接收過濾器初始化時綁定的那個FIFO)。

每一個郵箱均可以存儲一個獨立的報文,發送調度器(下圖紅圈)會根據標識符(ID)的優先級來決定先發送哪一個報文(好比發送時3個郵箱都有報文,標識符不同),PS:標識符數值越小,優先級越高,這是由CAN總線仲裁機制決定的(線與,0能夠與掉1)。

5、can中容易理解錯的概念

1.CAN總線中是沒有地址這個概念的,每一個報文都是羣發。

全部節點均可以發送和接收,先發送的有優先權,此時其它節點處於監聽模式,看是否有能經過本身過濾器的報文。

當同時有多個節點須要同時發送時,can總線將實行仲裁,標識符小的優先發送,被仲裁下去想要發送的節點當即轉入監聽狀態,等待下次機會。

標識符是報文的一部分,以下圖所示:

2.無論是標準幀或者擴展幀,最多隻能攜帶8字節數據,用戶能夠根據這8個字節私立協議。

SOF:幀起始信號,顯性電平,即can_H和can_L相差很小,小於0.5V,庫函數作了賦值,無論。

標識符:11bit或者29bits,表明着本條報文的優先級

RTR:幀類型,是遠程幀仍是數據幀

IDE:標準幀仍是擴展幀

R0:保留位,庫函數作了,無論

DLC:數據域長度

數據域:具體攜帶的數據,最長8字節

CRC:對CRC前全部字節進行校驗,獲得的結果,庫函數進行了這一步,不須要咱們本身計算,無論。

CRC分隔符:1個隱性電平,庫函數作了,無論

ACK Field:庫函數作了,

EOF:幀結束標誌,至少連續7位的隱性電平。無論。

 3.位填充的概念

在CAN消息幀中,幀起始,仲裁場。控制場,數據場和CRC段,均以位填充方法進行編碼。當發送器在發送流中檢測到5個極性相同的連續位時,自動插入一個部補位碼。

我以爲這個只要瞭解就好了,實際編程中庫函數已經幫咱們作了。

相關文章
相關標籤/搜索