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

📄 sja1000.c

📁 CAN总线开发板源代码与原理图
💻 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 + -