⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 canbus_sja1000.c

📁 CAN控制器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 + -