在現場總線概念的出現到現在的近20年時間里,已經出現了好幾種現場總線技術并走向成熟。其中CAN總線已被公認為幾種最有前途的現場總線之一。 CAN是一種由帶有CAN控制器組成的高性能串行數據局域通信網絡,是國際上應用最廣泛的現場總線之一。最初,CAN被設計作為汽車環境中的微控制器通信,在車載各電子控制裝置ECU之間交換信息,形成汽車電子控制網絡。由于其具有通信速度快、可靠性高和性能價格比好等突出優點,它正越拉越廣泛地應用于汽車、機械工業、紡織機械、農業用機械、機器人、數控機床、醫療器械、家用電器及傳感器等領域。圖1所示是典型的CAN總線節點的系統框圖。
系統硬件設計
SJA1000獨立CAN控制器是PHILIPS公司PCA82C200CAN控制器的替代產品,它是在完全兼容PCA82C200的基礎上,增加了一種新的工作模式PeliCAN,SJA1000完全支持具有很多新特性的CAN2.0B協議。SJA1000的工作模式通過其內部的時鐘分頻寄存器中的CAN模式為來選擇。SJA1000可以支持多種為處理器的時序特性,如Intel模式或Motorla模式,SJA1000與微處理器的接口非常簡單,微處理器以訪問外部存儲器的方式來訪問SJA1000。
TJA1050是控制器局域網CAN協議控制器和物理總線之間的接口,TJA1050可以為總線提供不同的發送性能,為CAN控制器提供不同的接收性能。TJA1050主要有以下特征:完全符合ISO 11898標準,最高速到達1Mb/s,輸入級3.3V以及5V器件兼容,至少可以連接110個節點。本設計的微處理器為89C51負責初始化 SJA1000及通過控制SJA1000實現數據的接收和發送等通信任務,系統電路圖如圖2所示。
CAN控制器SJA1000的數據線AD0~AD7連接到51單片機的P0口,連接到基址為0xFA00的外部存儲器片選信號,當訪問地址 0xFA00~0xFA31時,CPU可對SJA1000執行相應的讀寫操作。SJA1000的、、分別與51對應的引腳相連,接51的使51可以通過中斷方式訪問SJA1000。
系統軟件設計
本設計的系統由4個節點組成,一個節點由上位機通過并口轉CAN總線的數據收發器構成,另外3個節點由圖2所示的單片機CAN總線收發系統構成。單片機系統每秒發送一幀(8個字節)數據。連接上位機的CAN總線收發器有相應的上位機測試軟件支持,本文主要介紹單片機CAN總線收發器的程序設計。圖3是下位機軟件的流程圖。
系統設計的部分代碼如下:
main()
{
Sja_1000_Init(); //初始化SJA1000
Init_Cpu(); //初始化CPU
Init_T0(); //初始化定時器
flag_init=0x00;
while(1)
{
if(rcv_flag) //rcv_flag為接受標志位,有接收則單片機進行處理
{
rcv_flag=0; BCAN_DATA_RECEIVE(rcv_data);
BCAN_CMD_PRG(0X04);
disp_rec();
}
if(flag_sec) //定時中斷標志為,定時時間到則發送數據幀
{ flag_sec=0; send_data[0]=0xaa; send_data[1]=0x08; send_data[2]=DA1;
send_data[3]=DA2;
send_data[4]=DA3;
send_data[5]=DA4;
send_data[6]=DA5;
send_data[7]=DA6;
send_data[8]=DA7;
send_data[9]=DA8; BCAN_DATA_WRITE(send_data); BCAN_CMD_PRG(0X01);
}
if(err_flag)
{
err_flag=0;
disp_err();
Sja_1000_Init();
}
display(a); //循環顯示接受數據
SJA1000的初始化過程包括申請進入復位狀態,設置總線波特率,設置輸出方式,開放錯誤中斷、接受和發送中斷。在進行數據發送時數據包前兩個字節0Xaa、0X08為描述符,包括11位長的ID(標志符)\1位RTR\4位描述數據長度的DLC共16 位。BCAN_DATA_RECEIVE(rcv_data),為89C51對SJA1000的讀數據函數其具體函數定義:
bit BCAN_DATA_RECEIVE(unsigned char *RcvDataBuf)
{
unsigned char TempCount;
SJA_BCANAdr = REG_STATUS; //訪問地址指向狀態寄存器
if((*SJA_BCANAdr&0x01)==0) //判斷報文是否有效
{
return 1;
}
SJA_BCANAdr = REG_RxBuffer2; //訪問地址指向接收緩沖區2
if((*SJA_BCANAdr&0x10)==0) //如果是數據幀
{
TempCount=(*SJA_BCANAdr& 0x0f)+2; //計算報文中數據的個數
}
else
{
TempCount="2";
}
SJA_BCANAdr = REG_RxBuffer1; //訪問地址指向接收緩沖區1
memcpy(RcvDataBuf, SJA_BCANAdr,TempCount);//讀取接收緩沖區的報文
return 0;
}
此函數僅限于CAN控制器接受數據,返回值如果為0表示接受成功,如果為1表示接受失敗。
BCAN_DATA_WRITE(send_data)函數是89C51對SJA1000的寫數據函數其具體定義如下:
bit BCAN_DATA_WRITE(unsigned char *SendDataBuf)
{
unsigned char TempCount;
SJA_BCANAdr = REG_STATUS; //訪問地址指向狀態寄存器
if((*SJA_BCANAdr&0x08) == 0) //判斷上次發送是否完成
{
return 1;
}
if((*SJA_BCANAdr&0x04)==0) //判斷發送緩沖區是否鎖定
{
return 1;
}
SJA_BCANAdr = REG_TxBuffer1; //訪問地址指向發送緩沖區1
if((SendDataBuf[1]&0x10)==0) //判斷RTR,從而得出是數據幀還是遠程幀
{
TempCount =(SendData Buf[1]&0x0f)+2; //輸入數據幀
}
else
{
TempCount =2; //遠程幀
memcpy(SJA_BCANAdr,SendDataBuf,TempCount);
return 0;
}
此函數將待發送的特定幀各式的數據,送入SJA1000發送緩存區中,然后啟動,函數返回0表示將數據成功的送至發送緩沖區,返回1表示上一次的數據正在發送。
系統組網相對容易只需把各個節點掛在同一條雙絞線上即可,啟動上位機的CAN收發器,用來監視總線數據狀態。每當啟動一個下位機CAN收發器,上位機的測試軟件就可以每隔一秒鐘收到由同一CAN收發器發送的數據幀。實驗結果顯示當3臺下位機CAN總線同時發數時數據接收端沒有數據丟失和總線沖突現象。
結語
現場總線有著巨大的發展潛力,它將給自動控制領域的變革帶來深遠的影響。我們設計的CAN總線收發器具有通用性,在本系統設計的基礎上只需要相應的修改數據傳輸協議即可應用于各個CAN總線的數傳系統。
參考文獻:
1. 陳立元主編. Visual Basic實現串并行通信技術. 清華大學出版社,2001
2. 張學忠,王福成主編. Visual Basic控件應用編程實例教程. 北京希望電子出版社,2002
3. 馬希榮主編. Visual Basic 6.0 程序設計. 機械工業出版社,2004
4. 彭禹皓. 基于單片機和CAN控制器的嵌入式系統. 微計算機信息,2007,4-2:33-35