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

📄 sja1000.c

📁 基于C51的现场总线CAN转串口RS232的源码
💻 C
📖 第 1 页 / 共 2 页
字号:

#include "STC89C51RC_RD_PLUS.H"
#include  <absacc.h>       //用到XBYTE
#include <intrins.h>       //用到_nop_();



//宏定义
#define TRUE  1
#define FALSE 0


#define CAN_MODE_BASICCAN  0
#define CAN_MODE_PELICAN   1
#define CAN_CONF_TIMEOUT   10   //10ms


#define CAN_MODE CAN_MODE_PELICAN    //第一步设置CAN_MODE,选择BasicCan,还是PeliCan? 


#define CAN_CONTROL_SET_BAUDRATE  100       //在CAN_Control函数中用到
#define CAN_CONTROL_SET_ACR       101 
#define CAN_CONTROL_SET_AMR       102  
#define CAN_CONTROL_SET_SLEEP     103 


//STC内部EEPROM使用有关的宏定义
#define ISP_Byte_Read 1       
#define ISP_Byte_Program 2 
#define ISP_Sector_Erase 3
#define Wait_Time 2;          //    3 对应5M时钟 , 2 对应10M时钟 ,1 对应20M时钟, 0 对应40M时钟 
#define SECTOR1_BTR0_H   0x20  //第一扇区首地址,存放BTR0     注意不同的STC单片机首地址不一样。
#define SECTOR1_BTR0_L   0x00
#define SECTOR1_BTR1_H   0x20  //第一扇区第二个地址,存放BTR1
#define SECTOR1_BTR1_L   0x01
#define SECTOR2_ACR0_H   0x22  //第二扇区首地址,    存放ACR0    
#define SECTOR2_ACR0_L   0x00
#define SECTOR2_ACR1_H   0x22  //第二扇区第二个地址,存放ACR1
#define SECTOR2_ACR1_L   0x01
#define SECTOR2_ACR2_H   0x22  //第二扇区第三个地址,存放ACR2    
#define SECTOR2_ACR2_L   0x02
#define SECTOR2_ACR3_H   0x22  //第二扇区第四个地址,存放ACR3
#define SECTOR2_ACR3_L   0x03
#define SECTOR3_AMR0_H   0x24  //第三扇区首地址,   存放AMR0     
#define SECTOR3_AMR0_L   0x00
#define SECTOR3_AMR1_H   0x24  //第三扇区第二个地址,存放AMR1
#define SECTOR3_AMR1_L   0x01
#define SECTOR3_AMR2_H   0x24  //第三扇区第三个地址,存放AMR2    
#define SECTOR3_AMR2_L   0x02
#define SECTOR3_AMR3_H   0x24  //第三扇区第四个地址,存放AMR3
#define SECTOR3_AMR3_L   0x03



#define RX_BUFF_LEN 32  // CAN接收缓冲区大小
#define TX_BUFF_LEN 32  // CAN发送缓冲区大小


//CAN用到的缓冲区
unsigned char idata RX_BUFF[RX_BUFF_LEN];          // 接收缓冲区    0~RX_BUFF_LEN-1
unsigned char idata TX_BUFF[TX_BUFF_LEN];          // 发送缓冲区    0~TX_BUFF_LEN-1

unsigned int idata TX_Buff_Head = 0;  // 头指针,写入
unsigned int idata TX_Buff_Tail = 0;  // 尾指针,读出
unsigned int idata RX_Buff_Head = 0;  // 
unsigned int idata RX_Buff_Tail = 0;  //
 
//UART用到的缓冲区
#define UART_RX_Buff_LEN  24
#define UART_TX_Buff_LEN  24
unsigned char idata UART_RX_Buff[UART_RX_Buff_LEN];          // 接收缓冲区
unsigned char idata UART_TX_Buff[UART_TX_Buff_LEN];          // 发送缓冲区


unsigned int idata UART_RX_Buff_Head = 0;  // 头指针,写入
unsigned int idata UART_RX_Buff_Tail = 0;  // 尾指针,读出
unsigned int idata UART_TX_Buff_Head = 0;  // 
unsigned int idata UART_TX_Buff_Tail = 0;  // 





#define SJA_REG_BaseADD  0x1000        //这么选择的原因?   P2^6=1? 应该与片选有关

#define REG_MODE	XBYTE[SJA_REG_BaseADD + 0x00]    //内部控制寄存器
#define REG_CMR		XBYTE[SJA_REG_BaseADD + 0x01]     //命令寄存器
#define REG_SR		XBYTE[SJA_REG_BaseADD + 0x02]      //状态寄存器
#define REG_IR		XBYTE[SJA_REG_BaseADD + 0x03]      //中断寄存器
#define REG_IR_ABLE XBYTE[SJA_REG_BaseADD + 0x04]  //中断使能寄存器
//05保留   不用管
#define REG_BTR0	XBYTE[SJA_REG_BaseADD + 0x06]     //总线定时寄存器0 
#define REG_BTR1	XBYTE[SJA_REG_BaseADD + 0x07]     //总线定时寄存器1 
#define REG_OCR		XBYTE[SJA_REG_BaseADD + 0x08]      //输出控制寄存器
#define REG_TEST	XBYTE[SJA_REG_BaseADD + 0x09]     //测试寄存器
//0a保留   不用管
#define REG_ALC		XBYTE[SJA_REG_BaseADD + 0x0b]     //仲裁丢失捕捉寄存器
#define REG_ECC		XBYTE[SJA_REG_BaseADD + 0x0c]     //错误代码捕捉寄存器
#define REG_EMLR	XBYTE[SJA_REG_BaseADD + 0x0d]    //错误报警限制寄存器
#define REG_RXERR	XBYTE[SJA_REG_BaseADD + 0x0e]   //RX 错误计数寄存器
#define REG_TXERR	XBYTE[SJA_REG_BaseADD + 0x0f]   //TX 错误计数寄存器

#define REG_ACR0	XBYTE[SJA_REG_BaseADD + 0x10]
#define REG_ACR1	XBYTE[SJA_REG_BaseADD + 0x11]
#define REG_ACR2	XBYTE[SJA_REG_BaseADD + 0x12]
#define REG_ACR3	XBYTE[SJA_REG_BaseADD + 0x13]
#define REG_AMR0	XBYTE[SJA_REG_BaseADD + 0x14]
#define REG_AMR1	XBYTE[SJA_REG_BaseADD + 0x15]
#define REG_AMR2	XBYTE[SJA_REG_BaseADD + 0x16]
#define REG_AMR3	XBYTE[SJA_REG_BaseADD + 0x17]

#define REG_RxBuffer0 XBYTE[SJA_REG_BaseADD + 0x10]
#define REG_RxBuffer1 XBYTE[SJA_REG_BaseADD + 0x11]	
#define REG_RxBuffer2 XBYTE[SJA_REG_BaseADD + 0x12]
#define REG_RxBuffer3 XBYTE[SJA_REG_BaseADD + 0x13]
#define REG_RxBuffer4 XBYTE[SJA_REG_BaseADD + 0x14]

#define REG_TxBuffer0 XBYTE[SJA_REG_BaseADD + 0x10]
#define REG_TxBuffer1 XBYTE[SJA_REG_BaseADD + 0x11]
#define REG_TxBuffer2 XBYTE[SJA_REG_BaseADD + 0x12]
#define REG_TxBuffer3 XBYTE[SJA_REG_BaseADD + 0x13]
#define REG_TxBuffer4 XBYTE[SJA_REG_BaseADD + 0x14]

#define REG_DataBuffer1 XBYTE[SJA_REG_BaseADD + 0x15]
#define REG_DataBuffer2 XBYTE[SJA_REG_BaseADD + 0x16]
#define REG_DataBuffer3 XBYTE[SJA_REG_BaseADD + 0x17]
#define REG_DataBuffer4 XBYTE[SJA_REG_BaseADD + 0x18]
#define REG_DataBuffer5 XBYTE[SJA_REG_BaseADD + 0x19]
#define REG_DataBuffer6 XBYTE[SJA_REG_BaseADD + 0x1a]
#define REG_DataBuffer7 XBYTE[SJA_REG_BaseADD + 0x1b]
#define REG_DataBuffer8 XBYTE[SJA_REG_BaseADD + 0x1c]


#define REG_RBSA		XBYTE[SJA_REG_BaseADD + 0x1e]        //RX缓冲器起始地址寄存器
#define REG_CDR			XBYTE[SJA_REG_BaseADD + 0x1f]         //时钟分频寄存器
#define REG_Receive_Counter XBYTE[SJA_REG_BaseADD + 0x1d]  //RX信息计数器(RMC)




sbit CAN_RST = P4^0; //复位控制 
sbit CAN_INT= P3^2; //中断脚

struct CAN_CANConfig {
	unsigned char Mode;      //bit0: 0:basicCAN 1:peleican
	                         //bit1: 0: 双滤波  1:单滤波 
							 //bit2: 0: 标准帧  1:扩展帧	
	unsigned char BTR0;  //波特率
	unsigned char BTR1;  //波特率

	unsigned char ACR0;  //验收代码
	unsigned char ACR1;  //验收代码
	unsigned char ACR2;  //验收代码
	unsigned char ACR3;  //验收代码

	unsigned char AMR0;  //屏蔽代码
	unsigned char AMR1;  //屏蔽代码
	unsigned char AMR2;  //屏蔽代码
	unsigned char AMR3;  //屏蔽代码

	unsigned char EFF0;   //发送识别码,标准帧只用前两个
	unsigned char EFF1;   //发送识别码,标准帧只用前两个
	unsigned char EFF2;   //发送识别码,标准帧只用前两个
	unsigned char EFF3;   //发送识别码,标准帧只用前两个
};


struct CAN_CANConfig CANConfig;

#define  RESET_SJA1000()  {CAN_RST = 0; _nop_(); CAN_RST = 1;}  
#define  ON_CAN_INT()  {EX0 = 1;}
#define  OFF_CAN_INT() {EX0 = 0;}

//函数声明

bit send(unsigned char S_Data);


bit Serial(void);
void Delay1ms(unsigned int i);


bit CAN_Init(void);

/*
unsigned char EEPROM_Read(unsigned char AddrH,unsigned char AddrL);
void EEPROM_Write(unsigned char AddrH,unsigned char AddrL,unsigned char Data);
void Sector_Erase(unsigned char AddrH,unsigned char AddrL);
*/


/******************************************************************		
	延时1ms

*/
void Delay(unsigned int i) 
{
	while (i--)
	{
	};
}

/*

返回实际读取到的数据
 */

unsigned int CAN_Read(unsigned char *Buf,unsigned int MaxNum)
{
	unsigned int Count = 0;
	
	OFF_CAN_INT();
	while (MaxNum--)
	{
		if (RX_Buff_Tail == RX_Buff_Head)
		{//没有数据了
			break;
		}
		*Buf++ = RX_BUFF[RX_Buff_Tail++];
		if(RX_Buff_Tail == RX_BUFF_LEN ) 
				RX_Buff_Tail = 0;  // 指针循环
		Count++;
	}

	ON_CAN_INT();

	return Count;
}
/*

返回实际读取到的数据
 */

unsigned int UART_Read(unsigned char *Buf,unsigned int MaxNum)
{
	unsigned int Count = 0;
	
	ES = 0;
	while (MaxNum--)
	{
		if (UART_RX_Buff_Tail == UART_RX_Buff_Head)
		{//没有数据了
			break;
		}
		*Buf++ = UART_RX_Buff[UART_RX_Buff_Tail++];
		if(UART_RX_Buff_Tail == UART_RX_Buff_LEN ) 
				UART_RX_Buff_Tail = 0;  // 指针循环
		Count++;
	}

	ES = 1;

	return Count;
}
bit UART_Send(unsigned char *DataBuf,unsigned int Num)
{
	unsigned int len;
	bit Flag = 0;
	unsigned char i;
	
	//计算发送缓冲区的剩余大小

	do {
		ES = 0;
	
		if( UART_TX_Buff_Head < UART_TX_Buff_Tail)
		{
			len = UART_TX_Buff_Tail - UART_TX_Buff_Head;
		}
		else
		{
			len =UART_TX_Buff_LEN -  UART_TX_Buff_Head + UART_TX_Buff_Tail;
		}
		
		ES = 1;

		if (len >= Num)
		{//有空间发送多余的数据
			break;
		}
		Delay(100);
		i++;
	} while(i< 200);
	if (i>199)
	{
		return FALSE;
	}

	//讲数据放到发送缓冲区

	ES = 0;
	if( UART_TX_Buff_Head == UART_TX_Buff_Tail)
		Flag = 1;


	for(len=0; len<Num; len++)
	{
		UART_TX_Buff[UART_TX_Buff_Head++]=DataBuf[len];
		
		if(UART_TX_Buff_Head == UART_TX_Buff_LEN ) 
			UART_TX_Buff_Head = 0;  // 指针循环
	}
	ES = 1;
	if (Flag == 1)
	{
		TI = 1;
	}

}

/****************************************************************************
  		 发送函数
参数:*Buf是某个数组名。这个数组一般是xdata型的。例如a[20],CAN_Send(a,20)。Num是发送数据的个数(小于160)。
返回:
注:"如果缓冲区可以容纳这么多直接填充,如果缓冲区满的话等待之.发送前把发送中断直接打开"
	

*/
bit CAN_Send(unsigned char *DataBuf,unsigned int Num)
{
	unsigned char i;
	unsigned int len;
	unsigned char *p;
	

	
	//计算发送缓冲区的剩余大小
	i = 0;
	do {
		OFF_CAN_INT();  //关闭CAN中断
		
		if( TX_Buff_Head < TX_Buff_Tail)
		{
			len = TX_Buff_Tail - TX_Buff_Head;
			
		}
		else
		{
			len =TX_BUFF_LEN -  TX_Buff_Head + TX_Buff_Tail;
		}
		ON_CAN_INT();
		if (len >= Num)
		{//有空间发送多余的数据
			break;
		}
		Delay(10);
		i++;
	} while(i< 200);
	if (i>199)
	{
		return FALSE;
	}
	//讲数据放到发送缓冲区

	OFF_CAN_INT();

	for(len=0; len<Num; len++)
	{
		TX_BUFF[TX_Buff_Head++]=DataBuf[len];
		
		if(TX_Buff_Head == TX_BUFF_LEN ) 
			TX_Buff_Head = 0;  // 指针循环
	}
	
	i = REG_SR;
	p = (unsigned char xdata *)(SJA_REG_BaseADD + 0x15);

	if ((i & 0x04) == 0x04)
	{//发送缓冲区处于释放状态时,可以将部分数据发送出去
		i = 0;
		do {
			p[i] = TX_BUFF[TX_Buff_Tail++];
			i++;
			if(TX_Buff_Tail == TX_BUFF_LEN ) 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -