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

📄 can_module._c

📁 Atmel mcu can interface design example
💻 _C
字号:
#include "can.h"
#include "macros.h"
extern unsigned char TX_Buffer[13];
extern unsigned char RX_Buffer[13];
/*struct {
      uchar F_Fmt;
	  uchar ID[4];
	  uchar Data[8];
}SJAFrameStruct,  *P_SJAFrameStruct ;*/

//SJAFrameStruct TX_Buffer;
//unsigned char RX_Buffer[13];
//unsigned char TX_Buffer[13];

unsigned char read_sja(unsigned char addr) 				   //读SJA1000状态寄存器子程序
{
    unsigned char *sja_address = (unsigned char *)startadd;
	sja_address = (unsigned char *)startadd;
	sja_address = sja_address + addr;
	return (*(sja_address));
}

void write_sja(unsigned char addr,unsigned char val) 	   //写SJA1000控制寄存器子程序
{
	unsigned char *sja_address = (unsigned char *)startadd;
	sja_address = (unsigned char *)startadd;
	sja_address = sja_address + addr;
	*(sja_address) = val;
}

unsigned char SJATestInterface(unsigned char testvalue)
{
    unsigned char Err_Cnt = 0x20;
	unsigned char Err_Flag = TRUE;
	while(--Err_Cnt) 
	{
	     write_sja(TEST, testvalue);   %%TEST defined in can.h
		 if(read_sja(TEST) == testvalue) 
		 {
		    Err_Flag = FALSE;
			break;
		 }
	}
	return Err_Flag;
}

unsigned char SJAEntryResetMode(void)
{
    unsigned char Err_Cnt = 0x20;
	unsigned char Err_Flag = TRUE;
	while(--Err_Cnt) 
	{
	     write_sja(MODE, 0x09);
		 if((read_sja(MODE) & 0x01) == 0x01) 
		 {
		    Err_Flag = FALSE;
			break;
		 }
	}
	return Err_Flag;
}

unsigned char SJAQuitResetMode(void)
{
    unsigned char Err_Cnt = 0x20;
	unsigned char Err_Flag = TRUE;
	while(--Err_Cnt) 
	{
	     write_sja(MODE, 0x00);
		 if(read_sja(MODE) == 0x00) 
		 {
		    Err_Flag = FALSE;
			break;
		 }
	}
	return Err_Flag;
}

unsigned char SJATestRstMode(void)
{
    unsigned char SjaFlag;
	if((read_sja(MODE) & 0x01) == 0x01)
	{
	   SjaFlag = FALSE;
	}
	else
	   SjaFlag = TRUE;  //工作模式下返回TRUE
	return SjaFlag;   
}

unsigned char SJASetOutControl(unsigned char OutCtrl)
{
    unsigned char Err_Cnt = 0x20;
	unsigned char Err_Flag = TRUE;
	if(SJATestRstMode())
	{
	   Err_Flag = TRUE;
	}
	else
	{
	   while(--Err_Cnt)
	   {
	      write_sja(OCR, OutCtrl);
		  if(read_sja(OCR) == OutCtrl)
		  {
		     Err_Flag = FALSE;
			 break;
		  }
	   }
	}
	return Err_Flag;
}



unsigned char SJASetAccCode(unsigned char acr0, unsigned char acr1, unsigned char acr2, unsigned char acr3)
{
    unsigned char Err_Cnt = 0x20;
	unsigned char Err_Flag = TRUE;
	if(SJATestRstMode())
	{
	   Err_Flag = TRUE;
	}
	else
	{
	   while(--Err_Cnt)
	   {
	      write_sja(ACR0, acr0);
		  if(read_sja(ACR0) != acr0)
		  {
		     continue;
		  } 
		  
		  Err_Cnt = 0x20;
		  write_sja(ACR1, acr1);
		  if(read_sja(ACR1) != acr1)
		  {
		     continue;
		  } 
		  
		  Err_Cnt = 0x20;
		  write_sja(ACR2, acr2);
		  if(read_sja(ACR2) != acr2)
		  {
		     continue;
		  } 
		  
		  Err_Cnt = 0x20;
		  write_sja(ACR3, acr3);
		  if(read_sja(ACR3) != acr3)
		  {
		     continue;
		  } 
		  
		  Err_Flag = FALSE;
		  break;   
	   }
	}
	return Err_Flag;
}

unsigned char SJASetClockDivision(unsigned char clockdiv)
{
    unsigned char Err_Cnt = 0x20;
	unsigned char Err_Flag = TRUE;
	if(SJATestRstMode())
	{
	   Err_Flag = TRUE;
	}
	else
	{
	   while(--Err_Cnt)
	   {
	      write_sja(CDR, clockdiv);
		  if(read_sja(CDR) == clockdiv)
		  {
		     Err_Flag = FALSE;
			 break;
		  }
	   }
	}
	return Err_Flag; 
}

unsigned char SJASetAccMask(unsigned char amr0, unsigned char amr1, unsigned char amr2, unsigned char amr3)
{
    unsigned char Err_Cnt = 0x20;
	unsigned char Err_Flag = TRUE;
	if(SJATestRstMode())
	{
	   Err_Flag = TRUE;
	}
	else
	{
	   while(--Err_Cnt)
	   {
	      write_sja(AMR0, amr0);
		  if(read_sja(AMR0) != amr0)
		  {
		     continue;
		  } 
		  
		  Err_Cnt = 0x20;
		  write_sja(AMR1, amr1);
		  if(read_sja(AMR1) != amr1)
		  {
		     continue;
		  } 
		  
		  Err_Cnt = 0x20;
		  write_sja(AMR2, amr2);
		  if(read_sja(AMR2) != amr2)
		  {
		     continue;
		  } 
		  
		  Err_Cnt = 0x20;
		  write_sja(AMR3, amr3);
		  if(read_sja(AMR3) != amr3)
		  {
		     continue;
		  } 
		  
		  Err_Flag = FALSE;
		  break;   
	   }
	}
	return Err_Flag;
}

//16MHZ
unsigned char SJA_BTR_CODETAB[] = {
      0x53, 0x2F,   //20KBPS    0
	  0x87, 0xFF,   //40KBPS    1
	  0x47, 0x2F,   //50KBPS    2
	  0x83, 0xFF,   //80KBPS    3
	  0x43, 0x2F,   //100KBPS   4
	  0x03, 0x1C,   //125KBPS   5
	  0x81, 0xFA,   //200KBPS   6
	  0x01, 0x1C,   //250KBPS   7
	  0x80, 0xFA,   //400KBPS   8
	  0x00, 0x1C,   //500KBPS   9
	  0x80, 0xB6,   //666KBPS   10
	  0x00, 0x16,   //800KBPS   11
	  0x00, 0x14    //1000KBPS  12
};

unsigned char SJASetBaudRateStandard(unsigned char BaudRateSize)
{
     unsigned char Err_Cnt = 0x20;
	 unsigned char Err_Flag = TRUE;
	 if(BaudRateSize > 12)
	 {
	    Err_Flag = TRUE;
	 }
	 else
	 {
	    while(--Err_Cnt)
		{
		    write_sja(BTR0, SJA_BTR_CODETAB[BaudRateSize*2]);
			if(read_sja(BTR0) != SJA_BTR_CODETAB[BaudRateSize*2])
			{
			   continue;
			}
			
			Err_Cnt = 0x20;
			write_sja(BTR1, SJA_BTR_CODETAB[BaudRateSize*2 + 1]);
			if(read_sja(BTR1) != SJA_BTR_CODETAB[BaudRateSize*2 + 1])
			{
			   continue;
			}
			Err_Flag = FALSE;
			break;
		}
	 }
	 return Err_Flag;
	 
}	

/*void SJAWriteDataToTxBuf(unsigned char Num, unsigned char Data)
{
    switch(Num)
	{
	      case 0:
		       TX_Buffer[0] = Data;
			   break;
	      case 1:
		       TX_Buffer[1] = Data;
			   break;
		  case 2:	   		   
	           TX_Buffer[2] = Data;
			   break;
		  case 3:	   		   
	           TX_Buffer[3] = Data;
			   break;
		  case 4:	   		   
	           TX_Buffer[4] = Data;
			   break;
	      case 5:	   		   
	           TX_Buffer[5] = Data;
			   break;		   	   
		  case 6:	   		   
	           TX_Buffer[6] = Data;
			   break;	
		  case 7:	   		   
	           TX_Buffer[7] = Data;
			   break;	
	      case 8:	   		   
	           TX_Buffer[8] = Data;
			   break;
		  case 9:	   		   
	           TX_Buffer[9] = Data;
			   break;	
		  case 10:	   		   
	           TX_Buffer[10] = Data;
			   break;	
		  case 11:	   		   
	           TX_Buffer[11] = Data;
			   break;	
		  case 12:	   		   
	           TX_Buffer[12] = Data;
			   break;		   	   	   			   	   	   	   
	}
}*/

unsigned char SJASetOtherReg(void)
{
    unsigned char Err_Cnt = 0x20;
	unsigned char Err_Flag = TRUE;
	 
	if(SJATestRstMode())
	{
	   Err_Flag = TRUE;
	}
	else
	{
	 	while(--Err_Cnt)
	 	{
	     	write_sja(RXERR,0x00);	
		 	if(read_sja(RXERR) != 0x00)
		 	{
		   		continue;
		 	}
		 
		    Err_Cnt = 0x20;
		    write_sja(TXERR,0x00);;	
		    if(read_sja(TXERR) != 0x00)
		    {
		       continue;
		    } 
		 
		    Err_Cnt = 0x20;
		    write_sja(ECC,0x00);	
		    if(read_sja(ECC) != 0x00)
		    {
		       continue;
		    }
		 
		    Err_Cnt = 0x20;
		    write_sja(RBSA,0x00);;	
		    if(read_sja(RBSA) != 0x00)
		    {
		       continue;
		    }
		 
		    Err_Flag = FALSE;
		    break;
	   }
	}
	return Err_Flag;
}

unsigned char SJASetIER(unsigned char value)
{
     unsigned char Err_Cnt = 0x20;
	 unsigned char Err_Flag = TRUE;
	 
	 /*if(SJATestRstMode())
	 {
	   Err_Flag = TRUE;
	 }
	 else*/
	 //{
	    while(--Err_Cnt)
	    {
	       write_sja(IER, value);
		   if(read_sja(IER) == value)
		   {
		      Err_Flag = FALSE;
			  break;
		   }
	    }
     //}
	 return Err_Flag;
}



/*************************************************
                SJA1000初始化子函数
*************************************************/
void Init_CAN(void)
{
    unsigned char temp;
	unsigned int k ; 
	CLI();
	do
	{
	   temp = SJATestInterface(0x55);
	}while(temp);//检查硬件连线
	WDR();
	for(k=0;k<6;k++); 				//延时约5us
	do
	{
	    temp = SJAEntryResetMode();
	}while(temp);
	WDR();
	read_sja(IR);//clear IR
	for(k=0;k<6;k++); 				//延时约5us
	WDR();
	if(!SJATestRstMode())
	{
	   do
	   {
	      temp = SJASetClockDivision(0xC8);
	   }while(temp);
	   WDR();
	   for(k=0;k<6;k++); 				//延时约5us
	   do
	   {
	      temp = SJASetOutControl(0x1a);
	   }while(temp);
	   WDR();
	   for(k=0;k<6;k++); 				//延时约5us
	   do
	   {
	      temp = SJASetBaudRateStandard(2);
	   }while(temp);
	   WDR();
	   for(k=0;k<6;k++); 				//延时约5us
	   do
	   {
	      temp = SJASetAccCode(0x00, 0x00, 0x00, 0x00);
	   }while(temp);
	   WDR();
	   for(k=0;k<6;k++); 				//延时约5us
	   do
	   {
	      temp = SJASetAccMask(0xFF, 0xFF, 0xFF, 0xFF);
	   }while(temp);
	   WDR();
	   for(k=0;k<6;k++); 				//延时约5us
	   do
	   {
	      temp = SJASetOtherReg();
	   }while(temp);
	   WDR();
	   for(k=0;k<6;k++); 				//延时约5us
	   do
	   {
	      temp = SJAQuitResetMode();
	   }while(temp);
	   
	   WDR();
	   for(k=0;k<6;k++); 				//延时约5us
	   do
	   {
	      temp = SJASetIER(0x01);
	   }while(temp);
	   
	   
	}
	
	write_sja(CMR,0x0c);		  	//清除数据溢出和释放接收缓冲器;
	for(k=0;k<6;k++); 				//延时约5us
	WDR();
	do
	{
	   write_sja(MODE, 0x0C);
	}while((read_sja(MODE) & 0x01));
	/*WDR();
	for(k=0;k<6;k++); 				//延时约5us
	if(SJATestRstMode())
	{
	   do
	   {
	      temp = SJASetIER(0x01);
	   }while(temp);
	}*/
	SEI();
	
} 
/*************************************************
                SJA1000发送子函数
*************************************************/
void CanTransmit(void) 
{ 
	unsigned char status;
	CLI();		   	   	 		   //关中断		
	//实际用时对SJAWriteDataToTxBuf();的调用在个检测模块中
	/*SJAWriteDataToTxBuf(0, 0x88);
    SJAWriteDataToTxBuf(1, 0x00);		
	SJAWriteDataToTxBuf(2, 0x00);
	SJAWriteDataToTxBuf(3, 0x00);
	SJAWriteDataToTxBuf(4, 0x00);
	SJAWriteDataToTxBuf(5, 0x01);
	SJAWriteDataToTxBuf(6, 0x02);
	SJAWriteDataToTxBuf(7, 0x03);	
	SJAWriteDataToTxBuf(8, 0x04);	
	SJAWriteDataToTxBuf(9, 0x05);	
	SJAWriteDataToTxBuf(10, 0x06);	
	SJAWriteDataToTxBuf(11, 0x07);	
	SJAWriteDataToTxBuf(12, 0xaa);*/
	TX_Buffer[0]=0x88;		
	TX_Buffer[1]=0x00;	
	TX_Buffer[2]=0x00;	
	TX_Buffer[3]=0x00;	
	TX_Buffer[4]=0x00;	
	TX_Buffer[5]=0x01;	
	TX_Buffer[6]=0x02;	
	TX_Buffer[7]=0x03;	
	TX_Buffer[8]=0x04;	
	TX_Buffer[9]=0x05;	
	TX_Buffer[10]=0x06;	
	TX_Buffer[11]=0x07;	
	TX_Buffer[12]=0xaa;	
					  
	while(!(read_sja(SR)&0x04));  //wait until reg2^2==1 ,即判断发送缓冲器的状态
	
	write_sja(TXEFF, TX_Buffer[0]);		   //扩展帧,数据长度为8个字节
	write_sja(TXID0, TX_Buffer[1]);
	write_sja(TXID1, TX_Buffer[2]);
	write_sja(TXID2, TX_Buffer[3]);
	write_sja(TXID3, TX_Buffer[4]);
	write_sja(TXDATA0, TX_Buffer[5]);
	write_sja(TXDATA1, TX_Buffer[6]);
	write_sja(TXDATA2, TX_Buffer[7]);
	write_sja(TXDATA3, TX_Buffer[8]);
	write_sja(TXDATA4, TX_Buffer[9]);
	write_sja(TXDATA5, TX_Buffer[10]);
	write_sja(TXDATA6, TX_Buffer[11]);
	write_sja(TXDATA7, TX_Buffer[12]);
	write_sja(CMR,0x10);		  //发送请求命令
	while(!(read_sja(SR) & 0x08));//检测SR.3位,判断发送是否完成
	SEI();				  	  	  //开中断
} 

unsigned char CanReceive(void)
{
 	unsigned char result = FALSE;
	unsigned char status,number,i,sff;
	unsigned char prbuf;
	status = read_sja(SR);
	prbuf = RXEFF;
	if((status&0xc3) != 0)  		  //读取总线脱离、错误状态、接收溢出、有数据等位
	{
		if((status&0x80) == 0x80)
		{
			write_sja(MODE, 0x00);
			return FALSE;
		}
		if((status&0x02) == 0x02)
		{
			write_sja(CMR, 0x0c);
			return FALSE;
		}
		
		if((status&0x01) == 0x01)
		{
			if((read_sja(RXEFF) & 0x40) == 0x40)  //如果RTR=1,为远程帧
			{
				write_sja(CMR, 0x04);		  //则释放FXFIFO
			}
			else							  //为0,则是数据帧
			{
				sff = read_sja(prbuf) & 0x80;	  //取第一个字节的最高位
				number = (read_sja(prbuf) & 0x0f);//取第一个字节的低四位,即数据长度
				if((sff & 0x80) == 0x80)		  //判断是标准帧还是扩展帧
				   number = number + 5;			  //扩展帧,则帧的总长度加5(13字节)
				else
				   number = number + 3;			  //标准帧,则帧的总长度加3(11字节)
				for(i = 0; i < number; i++)		  //读取数据
				{
					RX_Buffer[i]=read_sja(prbuf);
					prbuf++;
				}
				result = TRUE;	 		 	  //读取到正确的数据则返回TRUE
				write_sja(CMR, 0x04);		  //最后释放FXFIFO
			}
		}
	}
	return result;
} 
	  
	  
	  









⌨️ 快捷键说明

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