?? can.c
字號:
/*------------------------------------------------------------------------------
;CAN總線大壩監測系統
;底層節點
;文件名稱: can.c
;函數功能:CAN總線通信
;MCU支持: C8051F040
;上海富方軟件合肥自動化分公司
;-----------------------------------------------------------------------------*/
#include "c8051F040.h"
#include "can.h"
#include "canreg.h"
#define CAN_ID 2
////////////////////////////////////////////////////////////////////////////////
// 清零所有消息對象
////////////////////////////////////////////////////////////////////////////////
void Clr_All_Msg_Obj (void){
unsigned char i;
SFRPAGE = CAN0_PAGE;
CAN0ADR = IF1CMDMSK;
CAN0DATL = 0xF3;
// 寫消息對象,Mask,Arb,Control改變
CAN0ADR = IF1MSK1;
CAN0DAT = 0xFFFF;
CAN0DAT = 0x7FFF;
// Xtd不用,Dir濾波,所有ID或IDE位濾波
CAN0DAT = 0x0000;
CAN0DAT = 0x0000;
// 消息對象不可用,默認ID為0
for (i = 1;i < 33;i++)
{
CAN0ADR = IF1CMDRQST;
CAN0DATL = i;
// 應用到32個消息對象
}
}
////////////////////////////////////////////////////////////////////////////////
// 消息對象發送配置
////////////////////////////////////////////////////////////////////////////////
void Init_Msg_Obj_TX (unsigned char msg_num,unsigned int id){
unsigned int temp_id;
SFRPAGE = CAN0_PAGE;
CAN0ADR = IF1CMDMSK;
CAN0DAT = 0x00b3;
// WR/RD=1,Mask=0,Arb=1,Control=1,ClrIntPnd=0,TxRqst=0,DataA=1,DataB=1
CAN0ADR = IF1ARB1;
CAN0DAT = 0x0000;
// ID15-0=0
temp_id = id<<2;
// 標準id為ID28-ID18,則左移2位
temp_id &=0x1ffc;
temp_id |=0xa000;
// IF1ARB2=101(id)00b,MsgVal=1,Xtd=0,標準模式,Dir=1,發送
CAN0DAT = temp_id;
// 地址自增指向IF1ARB2
CAN0DAT = 0x1088;
// IF1MSGC=0x1088,NewDat=0,MsgLst=0,IntPnd=0,UMask=1,TxIE=0,RxIE=0,
// RmtEn=0,TxRqst=0,EoB=1,DLC3-0=1000
// 濾波使能,發送后IntPnd不變,遠程禁止,長度為8的單塊
CAN0ADR = IF1CMDRQST;
CAN0DAT = msg_num;
// 應用到msg_num號消息
}
////////////////////////////////////////////////////////////////////////////////
// 消息對象接收配置
////////////////////////////////////////////////////////////////////////////////
void Init_Msg_Obj_RX (unsigned char msg_num,unsigned int id){
unsigned int temp_id;
SFRPAGE = CAN0_PAGE;
CAN0ADR = IF2CMDMSK;
CAN0DAT = 0x00bb;
// WR/RD=1,Mask=0,Arb=1,Control=1,ClrIntPnd=1,TxRqst=0,DataA=1,DataB=1
CAN0ADR = IF2ARB1;
CAN0DAT = 0x0000;
temp_id = id<<2;
temp_id &= 0x1ffc;
temp_id |=0x8000;
CAN0DAT = temp_id;
// IF1ARB2=100(id)00b,MsgVal=1,Xtd=0,標準模式,Dir=0,接收
CAN0DAT = 0x1488;
// NewDat=0,MsgLst=0,IntPnd=0,UMask=1,TxIE=0,RxIE=1,RmtEn=0,TxRqst=0
// EoB=1,DLC3-0=1000,不是中斷源,接收后IntPnd置1
CAN0ADR = IF2CMDRQST;
CAN0DATL = msg_num;
}
////////////////////////////////////////////////////////////////////////////////
// CAN發送數據動作
////////////////////////////////////////////////////////////////////////////////
void Can_Trans_Data (unsigned char msg_num){
unsigned char num;
SFRPAGE = CAN0_PAGE;
CAN0ADR = IF1CMDMSK;
CAN0DAT = 0x0087;
// WR/RD=1,Mask=0,Arb=0,Control=0,ClrIntPnd=0,TxRqst=1,DataA=1,DataB=1
CAN0ADR = IF1DATA1;
// 將8字節數據寫入IF1DATA1
for(num = 0;num < 8;num++){
CAN0DATH = Can_sdata[num+1];
CAN0DATL = Can_sdata[num];
num++;
}
CAN0ADR = IF1CMDRQST;
CAN0DATL = msg_num;
// 指向消息號
}
////////////////////////////////////////////////////////////////////////////////
// CAN接收數據動作
////////////////////////////////////////////////////////////////////////////////
void Can_Rec_Data (unsigned char msg_num){
unsigned char num;
SFRPAGE = CAN0_PAGE;
CAN0ADR = IF2CMDMSK;
CAN0DAT = 0x007f;
// WR/RD=0,Mask=1,Arb=1,Control=1,ClrIntPnd=1,NewDat=1,DataA=1,DataB=1
CAN0ADR = IF2CMDRQST;
CAN0DATL = msg_num;
// 指向消息號
CAN0ADR = IF2DATA1;
for(num=0;num<8;num++){
Can_rdata[num+1] = CAN0DATH;
Can_rdata[num] = CAN0DATL;
num++;
}
}
////////////////////////////////////////////////////////////////////////////////
// 主節點消息對象分別初始化,設置波特率,開啟中斷,并且啟動CAN
////////////////////////////////////////////////////////////////////////////////
void Can_Msg_Init (void){
SFRPAGE = CAN0_PAGE;
CAN0CN = 0X01;
// 初始化配置時將CAN掛起
Clr_All_Msg_Obj();
Init_Msg_Obj_RX(CAN_ID,CAN_ID);
Init_Msg_Obj_RX(31,31);
// 接收ID號
Init_Msg_Obj_TX(32,32);
// 發送ID號
EIE2 |= 0x20;
// 開啟CAN中斷
SFRPAGE = CAN0_PAGE;
CAN0CN |= 0X40;
// CAN波特率配置可訪問,
CAN0ADR = BITREG;
CAN0DAT = 0x7FFF;
CAN0CN = 0x02;
// 自動重發開啟,狀態中斷禁止,IE=1,CAN模塊中斷開啟,Init清零.結束初始化操作,CAN控制器進入正常工作
}
////////////////////////////////////////////////////////////////////////////////
// CAN向上層回傳數據
////////////////////////////////////////////////////////////////////////////////
void Can_Tx_Back(unsigned char Info_Data[6]){
unsigned char i;
Can_sdata[0] = Can_rdata[1];
Can_sdata[1] = Can_rdata[2];
for(i=0; i<6 ;i++){
Can_sdata[i+2] = Info_Data[i];
}
Can_Trans_Data(0x20);
}
////////////////////////////////////////////////////////////////////////////////
// CAN中斷
////////////////////////////////////////////////////////////////////////////////
void CAN_ISR (void) interrupt 19 {
SFRPAGE_SAVE = SFRPAGE;
SFRPAGE = CAN0_PAGE;
/* 成功接收報文 */
if ( CAN0STA & 0x10 ){
CAN0STA &= 0xef;
CAN0ADR = INTPEND2;
/* 廣播 */
if( CAN0DAT & 0x4000 )
Can_Rec_Data(31);
/* 非廣播 */
else
Can_Rec_Data(CAN_ID);
Rec_From_CAN = 1;
// 標志成功收到下層信息
}
SFRPAGE = SFRPAGE_SAVE;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -