摘 要:本文針對整車對電池管理系統(tǒng)提出雙can通信的要求,設計了由cpld、tms320lf2407與sja1000構成的雙can控制器。文中介紹了其硬件電路和軟件流程。原文位置 關鍵詞:混合動力電動汽車;電池管理系統(tǒng);雙can控制器 電池管理系統(tǒng)是混合動力汽車中重要的電子控制單元,具有保障電池正常、可靠和高效工作的作用,是電池與用電設備之間的橋梁。在研制以及批量生產過程中都需要對其內部控制參數進行離線或在線匹配標定,而電池管理系統(tǒng)需要采集和處理大量的數據,本文選用tms320lf2407作為標定用can控制器。作為電動汽車上的一個can節(jié)點,需要接收整車發(fā)來的can消息來執(zhí)行對外部繼電器、風扇以及電池等器件的控制命令,本文選用sja1000。 雙can硬件電路和 cpld邏輯設計 雙can硬件電路設計 tms320lf2407基于增強的哈佛結構,是地址線和數據線分離的微處理器,對晶振倍頻后,頻率高達40mhz。而sja1000的地址線和數據線復用,增加了dsp與sja1000之間讀寫數據的難度,這也是本系統(tǒng)設計的難點。常規(guī)的設計方式是在dsp與sja1000之間加一個電平轉換雙向緩沖驅動,其結構框圖如圖1所示。按這種方式設計的電路,當對sja1000進行讀寫操作時,先配置dsp的i/o端口,將ale拉高,鎖存地址,然后通過dsp的i/o端口將和()拉低,進行讀(寫)數據,最后拉高()和。按此方式每次讀寫sja1000寄存器中的值,均需通過程序對ale、和()信號進行設置, 增加了程序源代碼。如果控制器的閃存空間比較緊張,采取這種硬件連接方式顯然是不可取的。而且,為使狀態(tài)寄存器的狀態(tài)位讀寫正確,can報文讀寫時需在程序中加一定延時,這將影響電池管理系統(tǒng)的實時性?! ?
圖1 一般雙can控制器的硬件結構圖 為了盡量減少程序源代碼,節(jié)省寶貴的存儲資源并提高電池管理系統(tǒng)的實時性,本文采用cpld連接雙can控制器的接口電路,實現can報文收發(fā)。其硬件結構如圖2所示。
圖2 基于cpld的雙can控制器硬件結構圖 cpld的邏輯設計原文位置 cpld具有速度快、體積小、驅動能力強、可在線編程等優(yōu)點?;赾pld的邏輯控制電路適合完成譯碼任務,本文選用epm7064芯片,通過譯碼電路的軟件設計,完成sja1000輸入信號的邏輯選通控制。 cpld的輸入信號是dsp發(fā)送的信號,由高位地址a[15…13]、i/o空間選通引腳以及寫/讀信號組成。其中,地址線a13作為sja1000的地址和數據的選擇線,地址線a14和a15經譯碼后作為片選信號。地址線a13和i/o空間選通信號產生sja1000的地址鎖存信號sja_ale,地址線a13和讀寫信號產生sja1000的數據和地址讀寫信號。其cpld的輸入/輸出信號邏輯關系如表1所示。原文位置 雙can軟件程序設計 該can控制器的收發(fā)程序包括兩部分:dsp的can收發(fā)程序和sja1000的can收發(fā)程序。每個can收發(fā)程序主要由三個函數組成:can初始化程序、can報文接收程序和can報文發(fā)送程序。由于dsp的can收發(fā)程序比較容易設計,只需設置can控制器寄存器中的相應位,就可實現can報文的收發(fā)。所以,本文主要介紹sja1000的can報文收發(fā)程序設計?! 谋?中可以看到,sja1000的寄存器映射到dsp的i/o空間。本文選擇0x8000作為sja1000地址輸入端口,0xa000作為sja1000數據輸入/輸出端口。其程序主要由sja1000初始化、sja1000接收報文和sja1000發(fā)送報文三個子函數組成。其收發(fā)函數的流程如圖3所示。
圖3 sja1000發(fā)送報文程序流程圖 sja1000初始化 通過向can控制器sja1000模式寄存器寫0x01,讓其進入復位模式,然后分別對sja1000的時鐘分頻寄存器、錯誤報警限額寄存器、中斷使能寄存器、接收代碼和接收屏蔽寄存器、總線時序寄存器和輸出控制寄存器設置,最后向模式寄存器寫0x08,進入正常工作模式。初始化程序如下: #define sja1000_data_port porta000原文位置 ioport unsigned int porta000; //定義數據輸入/輸出端口 #define sja1000_address_port port8000原文位置 ioport unsigned int port8000; //定義地址輸入端口 …… sja1000_write(reg_mode, 0x01); tempdata= sja1000_read(reg_mode); //向模式寄存器寫0x01,進入復位模式 while((tempdata & 0x01) != 0x01); //等待sja1000復位