📄 canbus_sja1000.c
字号:
/////////////////////////////////////////////////////////////////////////////////
//canbus.c v1.0
//日期:04.9.27
#include <intrins.h>
#include <absacc.h>
/********************************************************************/
// 功能:初始化SJA1000,即初始化CANBUS总线
//
//
void ins_CANbus1(void)
{
unsigned char i,j,m;
//硬件上已设置时序为INTEL模式
m=AUXR;
AUXR=0x13; //外部XDATA
CAN_CS=1;
_WR=1;
_RD=1;
CAN_CS=0;
_nop_();_nop_();
_nop_();_nop_();
XBYTE[0]=0x01; //进入复位模式
i=XBYTE[0];
while((i&0x01)==0)
{
_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();
_nop_();_nop_();
i=XBYTE[0];
}
_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();
_nop_();_nop_();
XBYTE[31]=0x48; //CDR BsaicCAN模式、关闭CLKOUT
//XBYTE[6]=0x88; //BTR0 波特率预设值=8;同步跳转宽度=2
//XBYTE[7]=0xca; //BTR1 总线采样3次,tseg1=10,tseg2=4,
XBYTE[6]=0x42; //BTR0 波特率预设值Tscl=0.5uS;同步跳转宽度=
XBYTE[7]=0x2f; //BTR1 总线采样3次,tseg1=15,tseg2=2,
//控制器晶振频率12MHz,数据通讯波特率为100Kbps
XBYTE[8]=0xda; //OCR 正常输出模式,
XBYTE[4]=0x00; //ACR 验收代码寄存器,
XBYTE[5]=0x00; //AMR 验收屏蔽寄存器,
//XBYTE[1]=0x0c; //CMR 命令寄存器,清除数据溢出,释放接收缓冲器
XBYTE[1]=0x0e; //CMR 命令寄存器,清除数据溢出,释放接收缓冲器,中止发送
//XBYTE[0]=0x1e; //回到工作模式
XBYTE[0]=0x00; //回到工作模式
i=XBYTE[0];
while(i&0x01)
{
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
i=XBYTE[0];
}
for(j=0;j<=20;j++);
CAN_CS=1;
//AUXR=0x11; //内部XDATA
AUXR=m;
}
/********************************************************************/
// 功能:设置接收滤波器,BasicCAN方式
//入口参数:
//
//注意:
/********************************************************************/
// 功能:将一组数据写入发送缓冲器,并启动发送,以BasicCAN方式发送
//入口参数:RTR:帧类型,==0为数据帧,==1为远程帧,
// *dp:指向要发送数据的开始地址,前1个字节为数据长度代码(取值0---8),后继为数据代码(远程帧时无)
//id:为帧的识别符id
//返回值:如果返回1表示操作成功,返回2表示前次数据还未发送完,返回3表示出错或总线关闭。
//注意:确保SJA1000已正确初始化。
//注意:传递给入口参数的变量不能为xdata型变量
unsigned char CAN_send(unsigned char RTR,unsigned int id,unsigned char* dp)
{
unsigned char i,rd,m,n,k;
m=AUXR;
AUXR=0x13;//外部XDATA
CAN_CS=1;//
_WR=1;
_RD=1;
rd=0;
CAN_CS=0;//
_nop_();_nop_();_nop_();_nop_();
i=XBYTE[2]; //读状态 SR
if((i&0xc0)!=0)
{
//出错或总线关闭
rd=3;
}
else if((i&0x2c)==0x0c)
{
//没有要发送的信息,最近一次发送请求被成功处理,CPU可以向发送缓冲器写信息
rd=1;
//填写相关单元
i=id>>3;
XBYTE[10]=i; //写ID10--ID3
i=id<<5;
i=i&0xe0;
if(RTR==1)
{
//远程帧处理
i=i+0x10; //为远程帧
AUXR=0x11;
i=i+((*dp)&0x0f); //加上数据长度
AUXR=0x13;
XBYTE[11]=i; //写ID2--ID0+RTR+DLC
XBYTE[1]=0x01; //发送请求
}
else if(RTR==0)
{
//数据帧处理
AUXR=0x11;
n=*dp;
i=i+((*dp)&0x0f); //加上数据长度
AUXR=0x13;
XBYTE[11]=i; //写ID2--ID0+RTR+DLC
for(i=0;i<n;i++)
{
AUXR=0x11;
k=*(dp+1+i);
AUXR=0x13;
XBYTE[12+i]=k; //写入数据代码
}
XBYTE[1]=0x01; //发送请求
}
}
else
{
rd=2;
}
CAN_CS=1;//
_nop_();_nop_();_nop_();_nop_();
//AUXR=0x11; //内部XDATA
AUXR=m;
return(rd);
}
/********************************************************************/
// 功能:从接收缓冲器中读取有效数据,以BasicCAN方式
//入口参数:
// *dp:指向接收数据缓冲区的开始地址,格式为:前两个字节帧识别符id(第一个字节为ID10---ID3)+1字节帧
//类型(==0为数据帧,==1为远程帧)+1字节数据长度代码(取值0---8)+后继为数据代码(远程帧时无)
//
//返回值:如果返回1表示操作成功,返回2表示出现数据溢出,返回3表示当前没有可用信息
// 返回4表示出错或总线关闭
//注意:传递给入口参数的变量不能为xdata型变量
unsigned char CAN_receive(unsigned char* dp)
{
unsigned char i,rd,m,k;
m=AUXR;
AUXR=0x13; //外部XDATA
CAN_CS=1;
_WR=1;
_RD=1;
rd=0;
CAN_CS=0;
_nop_();_nop_();_nop_();_nop_();
i=XBYTE[2]; //读状态 SR
if((i&0xc0)!=0)
{
//出错或总线关闭
rd=4;
}
else if((i&0x03)==0x01)
{
//RXFIFO中有可用信息,而且数据未溢出
//取ID
k=XBYTE[20]; //读id10---id3
AUXR=0x11;
*dp=k;
AUXR=0x13;
i=XBYTE[21]; //读
rd=i>>5;
AUXR=0x11;
*(dp+1)=rd&0x07; //id2---id0
AUXR=0x13;
rd=i>>4;
rd=rd&0x01; //取RTR位
AUXR=0x11;
*(dp+2)=rd;
rd=i&0x0f;
*(dp+3)=rd; //取DLC
AUXR=0x13;
for(i=0;i<rd;i++)
{
//取数据
AUXR=0x13;
k=XBYTE[22+i]; //读
AUXR=0x11;
*(dp+4+i)=k;
}
//CMR 命令寄存器,清除数据溢出,释放接收缓冲器
AUXR=0x13;
XBYTE[1]=0x0c;
rd=1;
}
else if((i&0x02)==0x02)
{
//数据溢出
//CMR 命令寄存器,清除数据溢出,释放接收缓冲器
XBYTE[1]=0x0c;
rd=2;
}
else if((i&0x03)==0x00)
{
//没有可用信息
//XBYTE[1]=0x0c;//CMR 命令寄存器,清除数据溢出,释放接收缓冲器
rd=3;
}
CAN_CS=1;
_nop_();_nop_();_nop_();_nop_();
//AUXR=0x11; //内部XDATA
AUXR=m;
return(rd);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -