📄 canapp.c
字号:
/****************************************Copyright (c)**************************************************
** 广州周立功单片机发展有限公司
** 研 究 所
** 产品一部
** http://www.zlgmcu.com
**-----------------------------------------------------------文件信息--------------------------------------------------------------------------------
** 文 件 名: CANAPP.C
** 版 本: v1.0
** 日 期: 2004年2月23日
** 描 述: CAN模块应用接口函数说明文件。该文件中的函数,如果用户有特别的需要,可以进行修改。
********************************************************************************************************/
#define _CANAPP_GLOBAL_
#include "config.h"
#include "canapp.h"
#include <math.h>
UINT32 CANReadData_29bit(eCANNUM CanNum,uint32* CANPGN, uint32* pLengthOfData, pRCV_candata pData);
uint8 can_buf[8];
/****************************************************************************
* 名称:can_xiaoyan(uint8 *buf3)
* 功能:用来对报文数据第8字节进行校验
* 入口参数:无
* 出口参数:无
****************************************************************************/
uint8 can_xiaoyan(uint8 *buf)
{
uint8 add1;
if(buf[0]+buf[1]>0xFF)
{
add1=buf[0]+buf[1]+1;
}
else add1=buf[0]+buf[1];
if(add1+buf[2]>0xFF)
{
add1=add1+buf[2]+1;
}
else add1=add1+buf[2];
if(add1+buf[3]>0xFF)
{
add1=add1+buf[3]+1;
}
else add1=add1+buf[3];
if(add1+buf[4]>0xFF)
{
add1=add1+buf[4]+1;
}
else add1=add1+buf[4];
if(add1+buf[5]>0xFF)
{
add1=add1+buf[5]+1;
}
else add1=add1+buf[5];
if(add1+buf[6]>0xFF)
{
add1=add1+buf[6]+1;
}
else add1=add1+buf[6];
add1=add1 ^ 0x7E;
buf[7]=add1;
//return add;
}
/****************************************************************************
* 名称:can_de_xiaoyan(uint8 *buf3)
* 功能:用来对报文数据进行解校验
* 入口参数:无
* 出口参数:无
****************************************************************************/
uint8 can_de_xiaoyan(void)
{
uint8 add1;
//数组前7个字节累加和计算、相与计算
if((*pcanData).Word+(*(pcanData+1)).Word>0xFF)
{
add1=(*pcanData).Word+(*(pcanData+1)).Word+1;
}
else add1=(*pcanData).Word+(*(pcanData+1)).Word;
if(add1+(*(pcanData+2)).Word>0xFF)
{
add1=add1+(*(pcanData+2)).Word+1;
}
else add1=add1+(*(pcanData+2)).Word;
if(add1+(*(pcanData+3)).Word>0xFF)
{
add1=add1+(*(pcanData+3)).Word+1;
}
else add1=add1+(*(pcanData+3)).Word;
if(add1+(*(pcanData+4)).Word>0xFF)
{
add1=add1+(*(pcanData+4)).Word+1;
}
else add1=add1+(*(pcanData+4)).Word;
if(add1+(*(pcanData+5)).Word>0xFF)
{
add1=add1+(*(pcanData+5)).Word+1;
}
else add1=add1+(*(pcanData+5)).Word;
if(add1+(*(pcanData+6)).Word>0xFF)
{
add1=add1+(*(pcanData+6)).Word+1;
}
else add1=add1+(*(pcanData+6)).Word;
add1=add1 ^ 0x7E;
//校验码计算后与报文中的比较
if(add1==((*(pcanData+7)).Word))
{
return (1);
}
else
{
return(0);
}
}
/************************************************************************************************************
**函数原型 : void CANIntPrg(void)
**参数说明 : 无
**返回值 : 无
**说 明 : CAN控制器中断处理函数
************************************************************************************************************/
__irq void CANIntPrg(void)
{
UINT32 j;
uCANICR k;
if(CANLUTerr.Word != 0 ) //LUT Error Program
{
//add or modify code
j=CANLUTerrAd.Word;
}
for(j=0;j<CAN_MAX_NUM;j++)
{
k=CANICR(j);
if(k.Bits.RI_BIT != 0)
{
//add code
WriteCANRcvCyBuf(j);
rec_flag=1;
}
if(k.Bits.TI1_BIT != 0)
{
//add code
}
if(k.Bits.TI2_BIT != 0)
{
//add code
}
if(k.Bits.TI3_BIT != 0)
{
//add code
}
if(k.Bits.BEI_BIT != 0)
{
//add code
CanBufOffLinePrg(j);
}
if(k.Bits.ALI_BIT != 0)
{
//add code
}
if(k.Bits.EPI_BIT != 0)
{
//add code
}
if(k.Bits.WUI_BIT != 0)
{
//add code
}
if(k.Bits.DOI_BIT != 0)
{
//add code
ClrCanDataOver(j);
}
}
VICVectAddr = 0;
}
/****************************************************************************************
*
*Filename :different_boud.c
*date :20050707
*author :zhangjia
*
*unsigned int boud_caculate(unsigned int boud_kbps)
*description :基于ZLG ARM 2119 开发板的CAN总线波特率计算函数
* :给定3种波特率: 250
100
20
:方法对于有: 不改变前3个参数,只改变最后的分频就可以。
*input :unsigned int boud_kbps
* ----需要设定的波特率。单位Kbps
*return :UINT32 为所需波特率对应的BTR value
****************************************************************************************/
UINT32 boud_caculate_1(unsigned int boud_kbps_1)
{
// uCANBTR boud_BTR;
switch(boud_kbps_1)
{
case 250 :
return 0x00174003;
break;
case 125:
return 0x00174007;
break;
case 100 :
return 0x00174009;
break;
case 20:
return 0x00974032;
default:
return 0;
break;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//add different boud_kpbs
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
return 0x00174009;
}
/************************************************************************************************************
**函数原型 : void InitCAN_byd(eCANNUM CanNum,unsigned int boud)
**参数说明 : CanNum -->> CAN控制器,值不能大于CAN_MAX_NUM 规定的值
* unsigned int boud_k -->> CAN的初始化波特率值.unit:kbps
**返回值 : 无
**说 明 ; 在初始化CAN函数的基础上增加设定波特率的功能
* : 对于波特率的使用只需要在主函数中修改就行,此出无须改动
* : 给定特定的波特率的值就行了
*********************************************************************************/
void InitCAN_byd(eCANNUM CanNum,unsigned int boud_kbps_1)
{
HwEnCAN(CanNum);
SoftRstCAN(CanNum);
CANEWL(CanNum).Bits.EWL_BIT = USE_EWL_CAN[CanNum];
//初始化波特率
//CANBTR(CanNum).Word = USE_BTR_CAN[CanNum];
CANBTR(CanNum).Word = boud_caculate_1(boud_kbps_1);
//初始化中断为非向量中断
VICDefVectAddr =(UINT32)CANIntPrg;
VICIntEnable |=(1<<19)|(1<<(20+ CanNum))|(1<<(26+ CanNum));
CANIER(CanNum).Word= USE_INT_CAN[CanNum];
//配置验收滤波器(旁路状态)
CANAFMR.Bits.AccBP_BIT =1;
//初始化模式
CANMOD(CanNum).Bits.TPM_BIT = USE_TPM_CAN[CanNum];
CANMOD(CanNum).Bits. LOM_BIT = USE_MOD_CAN[CanNum];
//初始化接收环形缓冲区
CANRcvBufApp.FullFlag1=CANRcvBufApp.FullFlag2=CANRcvBufApp.FullFlag3=CANRcvBufApp.FullFlag4=0;
CANRcvBufApp.ReadPoint1=CANRcvBufApp.ReadPoint2=CANRcvBufApp.ReadPoint3=CANRcvBufApp.ReadPoint4=0;
CANRcvBufApp.WritePoint1=CANRcvBufApp.WritePoint2=CANRcvBufApp.WritePoint3=CANRcvBufApp.WritePoint4=0;
//启动CAN
SoftEnCAN(CanNum);
}
/************************************************************************************************************
**函数原型 : UINT32 CANSendData(eCANNUM CanNum,UINT32 Cmd,P_stcTxBUF Buf)
**参数说明 : CanNum -->> CAN控制器,值不能大于CAN_MAX_NUM 规定的值
Cmd --> 发送命令字
Buf --> 要发送的数据
**返回值 : 无
**说 明 : 本函数用于将数据发送到CAN总线
************************************************************************************************************/
UINT32 CANSendData(eCANNUM CanNum,UINT32 Cmd,P_stcTxBUF Buf)
{
UINT32 i,status=0;
if(0 != CANSR(CanNum).Bits.TBS1_BIT)
{
i=SEND_TX_BUF1;
}
else if(0 != CANSR(CanNum).Bits.TBS2_BIT)
{
i=SEND_TX_BUF2;
}
else if(0 != CANSR(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(CANMOD(CanNum).Bits.SM_BIT != 0)
{
CanQuitSM(CanNum);
}
#endif
CanSendCmd(CanNum,Cmd,i);
}
return (status);
}
/************************************************************************************************************
**函数原型 : UINT32 ReadCANRcvCyBuf(eCANNUM CanNum,stcRxBUF *Buf)
**参数说明 : CanNum --> CAN控制器,值不能大于CAN_MAX_NUM 规定的值
Buf --> 使用驱动接收到的缓冲区数据
**返回值 : =0,驱动接收到数据。
!=0,驱动没接收到数据。
**说 明 : 本函数用于用户调用使用CAN驱动接收到的数据。
************************************************************************************************************/
UINT32 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;
case CAN3:
if((0 != CANRcvBufApp.FullFlag3) ||
(CANRcvBufApp.ReadPoint3 != CANRcvBufApp.WritePoint3))
{
*Buf=CANRcvBufApp.RcvBuf[CAN3][CANRcvBufApp.ReadPoint3];
if(++CANRcvBufApp.ReadPoint3 >= USE_CAN_RCV_BUF_SIZE)
{
CANRcvBufApp.ReadPoint3 =0;
}
CANRcvBufApp.FullFlag3=0;
}
else
{
status=1;
}
break;
case CAN4:
if((0 != CANRcvBufApp.FullFlag4) ||
(CANRcvBufApp.ReadPoint4 != CANRcvBufApp.WritePoint4))
{
*Buf=CANRcvBufApp.RcvBuf[CAN4][CANRcvBufApp.ReadPoint4];
if(++CANRcvBufApp.ReadPoint4 >= USE_CAN_RCV_BUF_SIZE)
{
CANRcvBufApp.ReadPoint4 =0;
}
CANRcvBufApp.FullFlag4=0;
}
else
{
status=1;
}
break;
default:
status=1;
break;
}
return status;
}
/************************************************************************************************************
**函数原型 : void WriteCANRcvCyBuf(eCANNUM CanNum)
**参数说明 : CanNum -->> CAN控制器,值不能大于CAN_MAX_NUM 规定的值
**返回值 :
**说 明 : 本函数用于驱动将收到的CAN数据写入环形缓冲区
************************************************************************************************************/
void WriteCANRcvCyBuf(eCANNUM CanNum)
{
switch(CanNum)
{
case CAN1:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -