天天看點

飛思卡爾16位單片機(十四)—— CAN總線子產品測試

一、CAN子產品介紹

       這個實驗我們來研究XEP100單片機内部的CAN子產品。 

       XEP100單片機的CAN的基本特性如下:

• 實施CAN協定—2.0A/B版

— 标準和擴充資料幀

— 0-8位元組資料長度

— 高達1Mbps的可程式設計比特率

— 支援遠端幀

• 5個具有FIFO存儲機制的接收緩沖器

• 3個具有使用“本地優先”概念的内部優先順序的發送緩沖器

• 靈活可掩碼辨別符濾波器支援2個全尺寸(32位)擴充辨別符濾波器或4個16位濾波器或8個8位濾波器

• 內建低通濾波器的可程式設計喚醒功能

• 可程式設計環回模式支援自測操作

• 可程式設計監聽模式用于CAN總線監控

• 可程式設計總線脫離恢複功能

• 獨立的信号和中斷功能适用于所有CAN接收器和發射器錯誤狀态(警報、錯誤嚴重狀态、總線脫離)

• 可程式設計CAN時鐘源,采用總線時鐘或振蕩器時鐘

• 内部計時器提供給接收和發送的封包的時間标簽

• 三種低功耗模式:睡眠、關機和CAN使能

• 配置寄存器的全局初始化

CAN子產品的結構圖如下:

飛思卡爾16位單片機(十四)—— CAN總線子產品測試

圖中RXCAN是CAN接收器輸入管腳。TXCAN是CAN發送器輸出管腳。

下圖顯示了一個具有CAN的典型CAN系統。每個CAN節點通過收發器實體連接配接到CAN總線線路,收發器能夠驅動CAN總線所需的大電流,并具有對故障CAN或故障節點的電流保護。

飛思卡爾16位單片機(十四)—— CAN總線子產品測試

CAN的接收器和發送器的結構如下圖所示。

飛思卡爾16位單片機(十四)—— CAN總線子產品測試
飛思卡爾16位單片機(十四)—— CAN總線子產品測試

CAN收到的封包儲存在5級輸入FIFO中。5個封包緩沖器被交替映射到單個存儲器區域。CAN有三重發送緩沖器機制,允許提前建立多條封包,進而優化了實時性能。

CAN的封包緩沖器結構見下表

Offset Address Register Access
0x00X0 Identifier Register 0
0x00X1 Identifier Register 1
0x00X2 Identifier Register 2
0x00X3 Identifier Register 3
0x00X4 Data Segment Register 0
0x00X5 Data Segment Register 1
0x00X6 Data Segment Register 2
0x00X7 Data Segment Register 3
0x00X8 Data Segment Register 4
0x00X9 Data Segment Register 5
0x00XA Data Segment Register 6
0x00XB Data Segment Register 7
0x00XC Data Length Register
0x00XD Transmit Buffer Priority Register
0x00XE Time Stamp Register (High Byte)
0x00XF Time Stamp Register (Low Byte)

有關CAN的更加詳細的資訊請參見相關的CAN協定和XEP100單片機的技術資料。

        本實驗的CAN接口晶片采用的是TJA1050晶片,電路的原理圖如下圖所示。圖中L81和L82是CAN總線專用的濾波電感。J81和J82是跳線插針,用于連接配接120歐姆的電阻。如果CAN總線上挂接多個節點,隻能保留兩個120歐姆的電阻。這時需要把多餘的電阻切斷。就要拔下相應的跳線帽。

飛思卡爾16位單片機(十四)—— CAN總線子產品測試

本實驗采用CAN0發送資料,CAN1接收資料,CAN資料的格式采用标準幀格式。在開發闆上通過自發自收實驗來模拟真實的CAN通信過程。

二、例程測試

        本實驗的例程可以從本文的資源中下載下傳。打開例程的代碼,可以發現程式有些負責,程式中将CAN子產品的驅動以及LCD的驅動封裝到獨立的檔案當中,在主檔案中進行調用。由于代碼比較多,我們隻對CAN的驅動函數進行功能性的介紹,具體細節可以對照着晶片手冊進行研究。

1、CAN初始化

CAN子產品的初始化函數如下所示。

void INIT_CANx(void); 
           

這個函數的作用是對CANx子產品進行初始化,将波特率設定為250kbit/s,禁止CAN濾波功能。

2、CAN發送函數

CAN子產品的發送函數如下所示

Bool MSCANxSendMsg(struct can_msg msg);
           

這個函數的作用是通過CANx子產品發送資料,struct can_msg msg為需要發送是資料的結構體,函數傳回值為是否成功,發送成功傳回true。struct can_msg msg結構體的定義如下。

struct can_msg     //發送封包的結構體
{
    unsigned int id;
    Bool RTR;
    unsigned char data[8];
    unsigned char len;
    unsigned char prty;
};
           

結構體中包含了資料幀的ID,RTR标志位,8個位元組的資料,資料長度和優先級。

3、CAN接收函數

CAN子產品的接收函數如下所示

Bool MSCANxGetMsg(struct can_msg *msg);
           

函數中struct can_msg *msg為指向接收到的資料結構體的指針,函數傳回接收是否成功,成功傳回true。

這個程式的主函數如下所示

void main(void) {
  DisableInterrupts;
  INIT_PLL();
  initialize_ect();
  INIT_PORT();
  INIT_CAN0();
  INIT_CAN1();
  LEDCPU_dir=1;
  LEDCPU=0;
  EnableInterrupts;

//填寫封包内容
  msg_send.id = ID; 
  for(k=0;k<data_len_TX;k++)
  {
     msg_send.data[k] = senddata[k];
  }
  msg_send.len = data_len_TX;
  msg_send.RTR = FALSE;
  msg_send.prty = 0;

  for(;;) 
  {
      delay1ms(1000);
      if(!MSCAN0SendMsg(msg_send)) //發送過程出現錯誤
      {
          for(;;);
      }
      if(datain==1) 
      {
          lcd_clear();
          lcd_string(0,0,xianshi[0]);
          lcd_string(1,0,xianshi[1]);
          play_data();
          datain=0;
      }
  } 
}
           

主函數的作用是通過CAN0發送資料,首先将需要發送的資料的ID和data指派到發送結構體中,然後在主循環中每個1秒發送一次資料。并且在接收到資料時,在lcd上顯示接收到的資料。

        CAN1負責接收資料,接收采用中斷的方式,中斷函數如下所示。

void interrupt CAN_receive(void) 
{
      if(MSCAN1GetMsg(&msg_get)) 
      {
        // 接收新資訊
         if(msg_get.id == ID && (!msg_get.RTR)) 
         {
                 LEDCPU = ~LEDCPU;
                 datain=1;       
         }
      }
      else 
      {
       for(;;);
      }
}
           

在中斷函數中,主要是通過CAN1的接收函數來接收資料,接收成功後設定标志位datain。

将程式下載下傳到單片機中,并将單片機的CAN0和CAN1接口連接配接在一起,運作程式,可以看到液晶上顯示接收到的資料。

繼續閱讀