?? mscan12.c
字號:
//[MSCAN12.c]串行通信------------------------------------------------------*
//本文件包含: *
// (1)CANInit:CAN通信初始化 *
// (2)GetSNDBUF:查找空閑發送緩沖區 *
// (3)CANSND1DFRM:CAN發送1幀數據幀(數據長度<=8字節) *
// (4)CANRCV1FRM:CAN接收1幀數據幀 *
//-------------------------------------------------------------------------*
//頭文件
#include "MSCAN12.h" //CAN通信頭文件
//CANInit:CAN通信初始化----------------------------------------------------*
//功 能:CAN初始化 *
//參 數:無 *
//返 回:無 *
//說 明:在9.83M 外部晶振頻率下將總線速率設為200kbps,節點標識符為0 *
// 雙濾波方式,工作在查詢方式 *
//-------------------------------------------------------------------------*
void CANInit(void)
{
CAN0CTL1 |= (1 << CANE); //MSCAN12模塊使能
//初始化模式請求,并判斷初始化應答位,INITACK為1則CAN模塊已進入初始化
CAN0CTL0 |= (1 << INITRQ); // INITRQ=1,初始化請求
//等待應答
while ((CAN0CTL1 & (1<<INITACK)) == 0)
{
}
CAN0CTL1 &= ~(1 << CLKSRC); //MSCAN12時鐘源選擇外部晶振fmscan=9.83M
CAN0CTL1 |= (1 << LOOPB); //回環自測模式
CAN0CTL1 &= ~(1 << LISTEN); //禁止只聽模式
CAN0BTR0 = CAN0BTR0V; //同步跳轉寬度為1,預分頻因子為5
CAN0BTR1 = CAN0BTR1V; //將位速率設置成 197kbps
CAN0IDAC = CAN0IDACV; //兩個32位驗收過濾器
CAN0IDAR0 = CAN0IDAR0V; //給接收驗證碼寄存器0-1賦值
CAN0IDAR1 = CAN0IDAR1V;
CAN0IDMR0 = CAN0IDMR0V; //給接收驗證屏蔽寄存器0-1賦值
CAN0IDMR1 = CAN0IDMR1V;
CAN0TIER = CAN0TIERV; //設置中斷方式
CAN0TIER = CAN0TIERV;
CAN0CTL0 &= ~(1<<INITRQ); //INITRQ=0,退出初始化模式
//等待應答
while ((CAN0CTL1 | (1<<INITACK)) == 1)
{
}
}
//CANSND1DFRM:CAN發送1幀數據-----------------------------------------------*
//功 能:CAN發送1幀數據(數據長度<=8) *
//參 數:ID---報文標識符 *
// DataBUF---報文數據區首址 *
// LEN---報文數據長度 *
//返 回:INT8U CANsnd1DFrm --- 發送成功與否標志, *
// =0,沒有空閑發送緩沖區,發送不成功;=1,發送成功 *
//說明:在發送數據之前,先查詢是否有空閑發送緩沖區,若無則不能發送,返回0 *
//-------------------------------------------------------------------------*
INT8U CANSND1DFRM(INT16U ID,INT8U * DataBUF, INT8U LEN)
{
INT8U i;
INT8U * addr; //發送緩沖區
INT8U BufNum = 0xFF; //空閑的發送緩沖區號
BufNum = GetSNDBUF(); //查找空閑的發送緩沖區
if (BufNum == 0xFF) //若返回0xff,則沒有空閑的發送緩沖區
return 0; //沒有空閑的發送緩沖區,發送不成功,返回0
switch(BufNum)
{
case 0:
CAN0TBSEL |= (1<<TXS0); //選中發送緩沖區0
break;
case 1:
CAN0TBSEL |= (1<<TXS1); //選中發送緩沖區1
break;
case 2:
CAN0TBSEL |= (1<<TXS2); //選中發送緩沖區2
break;
default:
break;
}
addr=(INT8U *)(&CAN0TXFG); //獲得發送前臺緩沖區首地址
//---------------------------------------------------------------------
//將報文按CAN格式進行封裝并存入空閑發送緩沖區等待發送
addr[0] = (INT8U)(ID >> 8); //11位報文標識符高8位
addr[1] = ((INT8U)(ID)); //低3位
addr[1] &= ~(1 << RTR); //RTR=0,數據幀
addr[1] &= ~(1 << IDE); //IDE位=0
for(i = 0; i < LEN; i++)
addr[i+4] = DataBUF[i]; //數據賦值
addr[12] = LEN; //數據長度
//---------------------------------------------------------------------
//發送緩沖區相應TXE位寫1清除該位來通知MSCAN12發送數據
switch(BufNum)
{
case 0:
CAN0TFLG |= (1<<TXF0); //發送緩沖區0準備就緒
break;
case 1:
CAN0TFLG |= (1<<TXF1); //發送緩沖區1準備就緒
break;
case 2:
CAN0TFLG |= (1<<TXF2); //發送緩沖區2準備就緒
break;
default:
break;
}
return (1); //數據成功寫入空閑緩沖區,返回1
}
//GetSNDBUF:查找空閑發送緩沖區---------------------------------------------*
//功能:查找空閑發送緩沖區 *
//入口:無 *
//出口:空閑區號或0xFF *
//-------------------------------------------------------------------------*
INT8U GetSNDBUF(void)
{
INT8U bufbit = 0xFF; //空閑區號
//查找空閑的發送緩沖區
if ((CAN0TFLG & (1 << TXE0)) != 0)
{ //發送緩沖區0空
bufbit = 0;
}
else if ((CAN0TFLG & (1 << TXE1)) != 0)
{ //發送緩沖區1空
bufbit = 1;
}
else if ((CAN0TFLG & (1 << TXE2)) != 0)
{ //發送緩沖區2空
bufbit = 2;
}
return bufbit;//返回空閑區號
}
//CANRCV1FRM:CAN接收1幀數據------------------------------------------------*
//功 能:CAN接收1幀子程序 *
//參 數:無 *
//返 回:INT8U CANRCV1FRM---函數名,表示接收幀的情況, *
// =0xFF,未收到幀;=1,收到數據幀;=2,收到遠程幀 *
// CANRCVBUF--若收到報文,為16字節報文緩沖區的首地址 *
//說 明:無 *
//-------------------------------------------------------------------------*
INT8U CANRCV1FRM(INT8U * CANRCVBUF)
{
INT8U i;
INT8U IDEFlag; //IDE標志
INT8U RTRFlag; //RTR標志
INT8U FrameFlag; //幀標志
INT8U * addr; //接收幀首地址
if ((CAN0RFLG &(1 << RXF)) == 0)
return 0xFF; //未收到數據,返回0xFF
//RXF=1,表示收到數據,取數據處理
addr = (INT8U *)(&CAN0RXFG);
for(i = 0; i < 16; i++)
CANRCVBUF[i] = addr[i]; //將CAN接收緩沖區中的數據取到臨時緩沖區
CAN0RFLG = 0xFF; //清所有接收標志
//------判斷是標準幀還是擴展幀-----------------------------------------
IDEFlag = (CANRCVBUF[1] & (1 << IDE)); //取標識符中IDE標志
if (IDEFlag == 0) //標準幀
{
RTRFlag = (CANRCVBUF[1] & (1 << RTR)); //取標識符中RTR標志
//判斷是數據幀還是遠程幀
FrameFlag = ((RTRFlag == 0)?DataFrm:RemoteFrm);
}
else //擴展幀
{
RTRFlag = (CANRCVBUF[3] & (1 << ERTR)); //取標識符中RTR標志
//判斷是數據幀還是遠程幀
FrameFlag = ((RTRFlag == 0)?DataFrm:RemoteFrm);
}
return FrameFlag; //返回數據幀標志(1)或遠程幀(2)標志
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -