📄 app_can.c
字号:
/******************************************************************************
Copyright (C), 2007-2008, wanyi Tech. Co., Ltd.
FileName :app_can.c
Author :kevin
modify :
Version :1.0
Date :2008-4-25
Description :can application function
Function List :none
******************************************************************************/
#include "\inc\system.h"
//使用工作模式
const UINT32 USE_MOD_CAN[2] = {USE_MODE_CAN1,USE_MODE_CAN2};
//使用波特率
const UINT32 USE_BTR_CAN[2] = {USE_BTR_CAN1,USE_BTR_CAN2};
//使用发送缓冲区发送优先级模式选择
const UINT32 USE_TPM_CAN[2] = {USE_TPM_CAN1,USE_TPM_CAN2};
//应用中断
const UINT32 USE_INT_CAN[2] = {USE_INT_CAN1,USE_INT_CAN2};
//应用报警限制
const UINT32 USE_EWL_CAN[2] = {USE_EWL_CAN1,USE_EWL_CAN2};
canword TL;
canword TH;
unsigned char flag_can_rev = 0; //reveive flag
unsigned char flag_can_revok =0; //read ok flag
unsigned int save_can_id[10]; //save send id
unsigned int save_can_data[10][2]; //save receive data
stcRxBUF can_rev_buf[2]; //
stcTxBUF can_send_buf[10];
stcRcvCANCyBuf CANRcvBufApp;
/**************************************************************************************************
Function: // __irq void IRQ_Can(void)
Description: // for can interrupt
Calls: // none
Called By: // none
Table Accessed: // none
Table Updated: // none
Input: // void
Output: // none
Return: // void
Others: // none
***************************************************************************************************/
__irq void IRQ_Can_Rx(void)
{
volatile unsigned int i;
volatile unsigned int j;
volatile uCANICR k;
if(regCANLUTerr.Word != 0 ) //LUT Error Program
{
j=regCANLUTerrAd.Word;
}
for(j=0;j<CAN_MAX_NUM;j++)
{
k=regCANICR(j); //read can interrupt register
if(k.Bits.RI_BIT != 0) //receive interrupt
{
can_rev_buf[j] = RxBUF(j); //read rx register
i=can_rev_buf[j].RxCANID.Word; //read send id
RelCanRecBuf(j);
//release rx buffer (rrb=1)
flag_can_rev = 1; //set receive ok flag
}
if(k.Bits.BEI_BIT != 0) //bus error
{
CanBufOffLinePrg(j);
}
if(k.Bits.DOI_BIT != 0) //data flow
{
ClrCanDataOver(j); //clear data flow(CDO=1)
}
}
//-----------------------------------------------
if(flag_can_rev == 1)
{
//if((i>=1) && (i<=6)) //ID:1-6
//if(i==1)
//{
// save_can_id[i-1]=(unsigned char)(can_rev_buf[0].RxCANID.FrameFm.stcSTRFRFM.ID_BIT); //save send id
// save_can_data[2][0]=can_rev_buf[0].CANRDA.Word; //save low 4 byte data
// save_can_data[2][1]=can_rev_buf[0].CANRDB.Word; //save high 4 byte data
// i=0;
//}
switch(i)
{
case 2:
delay(DELAY_2X5US);
break;
case 3:
delay(DELAY_2X5US);
break;
case 4:
delay(DELAY_2X5US);
break;
case 5:
delay(DELAY_2X5US);
break;
case 6:
delay(DELAY_2X5US);
break;
default:
break;
}
flag_can_rev =0;
flag_can_revok=1;
}
//-----------------------------
VICVectAddr = 0;
}
//=================================================================================================
/**************************************************************************************************
Function: // void InitCAN(eCANNUM CanNum)
Description: // for init can
Calls: // none
Called By: // none
Table Accessed: // none
Table Updated: // none
Input: // CanNum-->the can controller channel,must be <=CAN_MAX_NUM
Output: // none
Return: // void
Others: // none
***************************************************************************************************/
void InitCAN(eCANNUM CanNum)
{
HwEnCAN(CanNum); //使能CAN
SoftRstCAN(CanNum); //软件复位CAN
regCANEWL(CanNum).Bits.EWL_BIT = USE_EWL_CAN[CanNum]; //
regCANBTR(CanNum).Word = USE_BTR_CAN[CanNum]; //初始化波特率
VICIntSelect = 0x00000000; //所有中断通道设置为IRQ中断
VICVectCntl4 = 0x20 | 26; //分配CAN1 rX 中断到向量中断0
VICVectAddr4 = (uint32)IRQ_Can_Rx; //设置中断服务程序地址
VICIntEnable |=(1<<26);
regCANIER(CanNum).Word= USE_INT_CAN[CanNum];
//配置验收滤波器(旁路状态)
regCANAFMR.Bits.AccBP_BIT =1;
//初始化模式
regCANMOD(CanNum).Bits.TPM_BIT = USE_TPM_CAN[CanNum];
regCANMOD(CanNum).Bits. LOM_BIT = USE_MOD_CAN[CanNum];
//启动CAN
SoftEnCAN(CanNum);
}
//=================================================================================================
/**************************************************************************************************
Function: // void WriteCANRcvCyBuf(eCANNUM CanNum)
Description: // write data recived to circle buffer
Calls: // none
Called By: // none
Table Accessed: // none
Table Updated: // none
Input: // CanNum-->the can controller channel,must be <=CAN_MAX_NUM
Output: // none
Return: // void
Others: // none
***************************************************************************************************/
void WriteCANRcvCyBuf(eCANNUM CanNum)
{
switch(CanNum)
{
case CAN1:
if((0 == CANRcvBufApp.FullFlag1))
{
CANRcvBufApp.RcvBuf[CAN1][CANRcvBufApp.WritePoint1] = RxBUF(CAN1);
if(++CANRcvBufApp.WritePoint1 >= USE_CAN_RCV_BUF_SIZE)
{
CANRcvBufApp.WritePoint1=0;
}
if(CANRcvBufApp.WritePoint1 == CANRcvBufApp.ReadPoint1)
{
CANRcvBufApp.FullFlag1 =1;
}
}
break;
case CAN2:
if((0 == CANRcvBufApp.FullFlag2))
{
CANRcvBufApp.RcvBuf[CAN2][CANRcvBufApp.WritePoint2] = RxBUF(CAN2);
if(++CANRcvBufApp.WritePoint2 >= USE_CAN_RCV_BUF_SIZE)
{
CANRcvBufApp.WritePoint2=0;
}
if(CANRcvBufApp.WritePoint2 == CANRcvBufApp.ReadPoint2)
{
CANRcvBufApp.FullFlag2 =1;
}
}
break;
default:
break;
}
// regRelCanRecBuf(CanNum);
}
//=================================================================================================
/**************************************************************************************************
Function: // unsigned int CANSendData(eCANNUM CanNum,unsigned int Cmd,P_stcTxBUF Buf)
Description: // write data to can bus
Calls: // none
Called By: // none
Table Accessed: // none
Table Updated: // none
Input: // CanNum-->the can controller channel,must be <=CAN_MAX_NUM
Cmd -->command
Buf -->data
Output: // none
Return: // void
Others: // none
***************************************************************************************************/
unsigned int CANSendData(eCANNUM CanNum,unsigned int Cmd,P_stcTxBUF Buf)
{
UINT32 i,status=0;
if(0 != regCANSR(CanNum).Bits.TBS1_BIT)
{
i=SEND_TX_BUF1;
}
else if(0 != regCANSR(CanNum).Bits.TBS2_BIT)
{
i=SEND_TX_BUF2;
}
else if(0 != regCANSR(CanNum).Bits.TBS3_BIT)
{
i=SEND_TX_BUF3;
}
else
{
i=0xFF;
}
status=WriteCanTxBuf(CanNum,i, USE_TPM_CAN[CanNum], Buf);
if(status == 0)
{
#if 1
if(regCANMOD(CanNum).Bits.SM_BIT != 0)
{
CanQuitSM(CanNum);
}
#endif
CanSendCmd(CanNum,Cmd,i);
}
return (status);
}
//=================================================================================================
/**************************************************************************************************
Function: // unsigned int ReadCANRcvCyBuf(eCANNUM CanNum,stcRxBUF *Buf)
Description: // write data to can bus
Calls: // none
Called By: // none
Table Accessed: // none
Table Updated: // none
Input: // CanNum-->the can controller channel,must be <=CAN_MAX_NUM
Buf -->receive data buffer
Output: // none
Return: // 0-->success; other-->error
Others: // none
***************************************************************************************************/
unsigned int ReadCANRcvCyBuf(eCANNUM CanNum,stcRxBUF *Buf)
{
UINT32 status=0;
switch(CanNum)
{
case CAN1:
if((0 != CANRcvBufApp.FullFlag1) || (CANRcvBufApp.ReadPoint1 != CANRcvBufApp.WritePoint1))
{
*Buf=CANRcvBufApp.RcvBuf[CAN1][CANRcvBufApp.ReadPoint1];
if(++CANRcvBufApp.ReadPoint1 >= USE_CAN_RCV_BUF_SIZE)
{
CANRcvBufApp.ReadPoint1 =0;
}
CANRcvBufApp.FullFlag1=0;
}
else
{
status=1;
}
break;
case CAN2:
if((0 != CANRcvBufApp.FullFlag2) || (CANRcvBufApp.ReadPoint2 != CANRcvBufApp.WritePoint2))
{
*Buf=CANRcvBufApp.RcvBuf[CAN2][CANRcvBufApp.ReadPoint2];
if(++CANRcvBufApp.ReadPoint2 >= USE_CAN_RCV_BUF_SIZE)
{
CANRcvBufApp.ReadPoint2 =0;
}
CANRcvBufApp.FullFlag2=0;
}
else
{
status=1;
}
break;
default:
status=1;
break;
}
return status;
}
//=================================================================================================
/**************************************************************************************************
Function: // void can_send_info(unsigned char send_id)
Description: // can send information
Calls: // none
Called By: // none
Table Accessed: // none
Table Updated: // none
Input: // send_id-->send id
Output: // none
Return: // none
Others: // none
***************************************************************************************************/
void can_send_info(unsigned char send_id)
{
can_send_buf[1].CANTDA.Word=TL.Word; //CAN信息低 WORD
can_send_buf[1].CANTDB.Word=TH.Word; //CAN信息高 WORD
can_send_buf[1].TxCANID.FrameFm.stcSTRFRFM.ID_BIT = send_id; //CAN ID号
can_send_buf[1].TxFrameInfo.Bits.FF_BIT = 0; //标准帧
can_send_buf[1].TxFrameInfo.Bits.RTR_BIT = 0; //数据帧
can_send_buf[1].TxFrameInfo.Bits.DLC_BIT = 0x08; //数据长度 8 BYTE
CANSendData(0,8,&can_send_buf[1]);
}
//=================================================================================================
/**************************************************************************************************
Function: // void test_can(void)
Description: // test can
Calls: // none
Called By: // none
Table Accessed: // none
Table Updated: // none
Input: // none
Output: // none
Return: // none
Others: // none
***************************************************************************************************/
void test_can(void)
{
TL.Bits.Data0=0;
TL.Bits.Data1=1;
TL.Bits.Data2=2;
TL.Bits.Data3=3;
TH.Bits.Data0=4;
TH.Bits.Data1=5;
TH.Bits.Data2=6;
TH.Bits.Data3=7;
while (1)
{
can_send_info(1);
TL.Bits.Data0++;
TL.Bits.Data1++;
TL.Bits.Data2++;
TL.Bits.Data3++;
TH.Bits.Data0++;
TH.Bits.Data1++;
TH.Bits.Data2++;
TH.Bits.Data3++;
delay(DELAY_100MS);
}
}
//=================================================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -