📄 sja1000.c
字号:
#include "SJA1000.h"
#include "stdio.h"
/********************************************************************************************
** 函数名称: void delay(unsigned int k)
** 功能描述: 延时函数 22.1184Mhz
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
*********************************************************************************************/
static void DelayMs(unsigned int t)
{
uint i;
while(t--)
for(i=1000;i>0;i--);
}
/********************************************************************************************
** 函数名称: void CAN_Init(void)
** 功能描述: SJA1000复位
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
*********************************************************************************************/
void CanInit(void)
{
CanRst = 0;
DelayMs(100);
CanRst = 1;
DelayMs(10);
CanConfigNormal();
bCAN_RecSuccFlag = 0;
}
/********************************************************************************************
** 函数名称: CanTestt()
** 功能描述: 测试SJA1000
** 输 入: 无
** 输 出: 成功返回1,失败返回0
** 全局变量: 无
** 调用模块: 无
*********************************************************************************************/
bit CanTest()
{
uchar temp;
SJA_ADD = REG_CAN_TEST;/*test register*/
*SJA_ADD = 0x66;
temp = *SJA_ADD;
if(temp == 0x66)
{
return 1;
}
else
{
return 0;
}
}
/********************************************************************************************
** 函数名称: void CanConfigNormal()
** 功能描述: SJA1000进入正常模式
** 输 入: 无
** 输 出:
** 全局变量: 无
** 调用模块: 无
*********************************************************************************************/
void CanConfigNormal()
{
uchar temp;
SJA_ADD = REG_CAN_MOD; /*方式寄存器*/
*SJA_ADD = 0x09; /*in reset mode*/
SJA_ADD = REG_CAN_CDR; /*时钟分频寄存器*/
*SJA_ADD = 0x88; /*PeliCAN mode ,clock ouput off*/
SJA_ADD = REG_CAN_IER; /*中断允许寄存器*/
*SJA_ADD = 0x0D; /*开放 发送 溢出 错误警告中断*/
SJA_ADD = REG_CAN_AMR0; /*屏蔽寄存器*/
*SJA_ADD = CAN_AMR_Data[0];
SJA_ADD = REG_CAN_AMR1;
*SJA_ADD = CAN_AMR_Data[1];
SJA_ADD = REG_CAN_AMR2;
*SJA_ADD = CAN_AMR_Data[2];
SJA_ADD = REG_CAN_AMR3;
*SJA_ADD = CAN_AMR_Data[3];
SJA_ADD = REG_CAN_ACR0; /*接收代码寄存器*/
*SJA_ADD = CAN_ACR_Data[0];
SJA_ADD = REG_CAN_ACR1;
*SJA_ADD = CAN_ACR_Data[1];
SJA_ADD = REG_CAN_ACR2;
*SJA_ADD = CAN_ACR_Data[2];
SJA_ADD = REG_CAN_ACR3;
*SJA_ADD = CAN_ACR_Data[3];
/***********************************************************************/
SJA_ADD = REG_CAN_BTR0;/*总线定时寄存器*/
*SJA_ADD = CAN_BTR_Data[0];
SJA_ADD = REG_CAN_BTR1;
*SJA_ADD = CAN_BTR_Data[1];
/******************************************************************/
SJA_ADD = REG_CAN_OCR;/*输出控制寄存器*/
*SJA_ADD = 0xAA;
SJA_ADD = REG_CAN_RBSA;/*接收缓冲起始地址寄存器*/
*SJA_ADD = 0x00; /*设置起始地址为0*/
SJA_ADD = REG_CAN_TXERR;/*发送错误计数寄存器*/
*SJA_ADD = 0x00;/*清除发送错误计数寄存器*/
SJA_ADD = REG_CAN_ECC;/*错误代码捕捉寄存器*/
temp =*SJA_ADD;/*清除发送错误计数寄存器*/
/*********************************************************************/
SJA_ADD = REG_CAN_MOD;/*方式寄存器*/
*SJA_ADD = 0x08; /*设置单滤波模式 退出reset mode*/
}
/********************************************************************************************
** 函数名称: CanConfigSelf(uchar *pMessage)
** 功能描述: SJA1000进入自收发模式
** 输 入: 无
** 输 出:
** 全局变量: 无
** 调用模块: 无
*********************************************************************************************/
/* void CanConfigSelf(uchar *pMessage)
{
SJA_ADD = REG_CAN_MOD; //方式寄存器
*SJA_ADD = 0x01; //in reset mode
SJA_ADD = REG_CAN_MOD;//方式寄存器
*SJA_ADD = 0x04; //进入自检模式
CanTransmitMessage(pMessage);
SJA_ADD = REG_CAN_CMR; //指向TX缓冲区
*SJA_ADD = 0x10;//自接收请求
} */
/********************************************************************************************
** 函数名称: CanTransmitMessage(uchar *pMessage)
** 功能描述: SJA1000发送一帧数据
** 输 入: pMessage
** 输 出: 成功:返回1,失败:返回0////////////////////////////
** 全局变量: 无
** 调用模块: 无
*********************************************************************************************/
bit CanTransmitMessage(uchar *pMessage)
{
bit bFF,bTansOk; //bFF=0标准帧,bFF=1扩展帧
uchar cLen,temp,i; //CAN数据长度和 下标
SJA_ADD = REG_CAN_SR;
temp = *SJA_ADD;
if((temp&TBS_BIT)==TBS_BIT) //发送缓冲区状态 = 释放?
{
bFF = pMessage[0] & 0x80; // 取帧模式
cLen = pMessage[0] & 0x0F;//取帧数据长度
SJA_ADD = REG_CAN_TXFMINFO;
*SJA_ADD = pMessage[0];
SJA_ADD ++;
*SJA_ADD = pMessage[1]; //标识码 1
SJA_ADD ++;
*SJA_ADD = pMessage[2]; //标识码 2
if (bFF)
{ //扩展帧报文
SJA_ADD++;
*SJA_ADD = pMessage[3]; //标识码 3
SJA_ADD++;
*SJA_ADD = pMessage[4]; //标识码 4
}
for(i=0;i<cLen;i++) //写入数据
{
if(bFF)
{
SJA_ADD++;
*SJA_ADD = pMessage[i+5];
}
else
{
SJA_ADD++;
*SJA_ADD = pMessage[i+3];
}
}
SJA_ADD = REG_CAN_CMR; //启动发送
*SJA_ADD = TR_BIT;
bTansOk = 1;
}
else
{
bTansOk = 0; //发送缓冲未释放,运行其他任务或再次调用函数
}
return bTansOk;
}
/********************************************************************************************
** 函数名称: void CanReciveMessage(uchar *pMessage)
** 功能描述: 接收一个报文
** 输 入: pMessage
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
*********************************************************************************************/
void CanReciveMessage(uchar *pMessage)
{
bit bFF; /*bFF=0标准帧,bFF=1扩展帧*/
uchar cLen,i;/*CAN数据长度和 下标*/
SJA_ADD = REG_CAN_RXFMINFO; /*从接收缓冲区读新报文并保存*/
pMessage[0]=*SJA_ADD;
bFF = pMessage[0] & 0x80;
cLen = pMessage[0] & 0x0F;
SJA_ADD ++;
pMessage[1]= *SJA_ADD;
SJA_ADD ++;
pMessage[2]= *SJA_ADD;
if(bFF)
{
SJA_ADD++;
pMessage[3]= *SJA_ADD;
SJA_ADD++;
pMessage[4]= *SJA_ADD;
}
for(i=0;i<cLen;i++) /*读取并保存数据*/
{
if(bFF)
{ SJA_ADD++;
pMessage[i+5] = *SJA_ADD;
}
else
{
SJA_ADD++;
pMessage[i+3] = *SJA_ADD;
}
}
SJA_ADD= REG_CAN_CMR; /*释放接收缓冲区*/
*SJA_ADD = RRB_BIT;
}
/********************************************************************************************
** 函数名称: void Ex0_int(void) interrupt 2
** 功能描述: SJA1000中断处理
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
*********************************************************************************************/
void Ex1_int(void) interrupt 2 //SJA中断使用CPU外部中断1
{
uchar SJAIntType,ff;
SJA_ADD = REG_CAN_IR;
SJAIntType = *SJA_ADD; //读中断标志寄存器(读中断标志寄存器除了接收中断位外其他标志均被清除)
switch(SJAIntType)
{
case RI_BIT: //接收中断
{
CanReciveMessage(CAN_ReBuf);
ff = CAN_ReBuf[0] & 0x80;
if(ff == 0)cCanRecLen = (CAN_ReBuf[0] & 0x0f) + 3; //标准帧的长度
else cCanRecLen = (CAN_ReBuf[0] & 0x0f) + 5; //扩展帧的长度 */
bCAN_RecSuccFlag = 1;
break;
}
case TI_BIT:
{
break;
}
case BEI_BIT: //总线错误中断
{
SJA_ADD = REG_CAN_MOD;
*SJA_ADD = 0x08; //恢复总线
break;
}
case DOI_BIT: //数据溢出中断
{
SJA_ADD = REG_CAN_CMR;
*SJA_ADD = 0x0c; //清除溢出位并释放接收缓冲区
break;
}
default:
{
SJA_ADD = REG_CAN_MOD;
*SJA_ADD = 0x08; //恢复总线
DelayMs(50);
break;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -