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

📄 can._c

📁 can tongxunCAN128的底层驱动
💻 _C
字号:
#include "main.h"

//#pragma interrupt_handler can_ReceiveData:19

/*******************************************************************
CAN initialization:
Mailbox 0: Receive  --> interrupt
Mailbox 1: Transmit --> polling
*******************************************************************/
#define TYP_RESET		5
#define TYP_BAUD		10

#define SELFID  2

extern unsigned char sysrst;
unsigned char canbaud;

const Uchar CanBaud[6][3]={{0x00,0x04,0x13},{0x02,0x04,0x13},{0x06,0x04,0x13},{0x08,0x04,0x13},{0x0E,0x04,0x13},{0x12,0x04,0x13}};



unsigned long CANMOBID[15]={0x1300ff01,0x1300ff01,0x02000000|(SELFID<<8),0x02000000|(SELFID<<8),0x0100ff00,0x0100ff00,0x01000000|(SELFID<<8),0x01000000|(SELFID<<8),0x0200ff00,0x12000001,0x01000000|(SELFID<<8),0x01000000|(SELFID<<8),0x01000000|(SELFID<<8),0x01000000|(SELFID<<8),0x1300ff01};
unsigned long CANMOBMD[15]={0x1f00ffff,0x1f00ffff,0x0f00ff00,            0x0f00ff00,            0x0f00ff00,0x0f00ff00,0x0f00ff00,            0x0f00ff00,            0x0f00ff00,0x1f0000ff,0x0f00ff00,0x0f00ff00,0x0f00ff00,0x0f00ff00,0x1f00ffff};
unsigned char CANIDT[15][4]={0};
unsigned char CANIDM[15][4]={0};
Uchar counterTemp;
void can_init (void)
{
 canMob_init();
 //IDRcbufInit();
 //RstIDused();
}


void canMob_init (void)
{
    unsigned char i,j;
	unsigned long temp;
	unsigned int temp1,temp2;
	
	
	//DDRD=(1<<PD5)|(0<<PD6);   //TXCAN, RXCNA
	DDRD|=0x20;
	DDRD&=0xBF;
	CANGCON |= (1<<SWRES);              //reset CAN interface
    
	
	//CANMOBID[2]=(unsigned long)(SELFID<<8)|CANMOBID[2];
	for(i=0;i<15;i++)
	{
	 temp=CANMOBID[i]<<3;
	 temp1=(unsigned int)temp;
	 temp2=(unsigned int)(temp/0x00010000);
	 CANIDT[i][3]=(Uchar)temp1;
	 CANIDT[i][2]=(Uchar)(temp1>>8);
	 CANIDT[i][1]=(Uchar)temp2;
	 CANIDT[i][0]=(Uchar)(temp2>>8); 
	 NOP();
	}
	
	for(i=0;i<15;i++)
	{
	 temp=CANMOBMD[i]<<3;
	 temp1=(unsigned int)temp;
	 temp2=(unsigned int)(temp/0x00010000);
	 CANIDM[i][3]=(Uchar)temp1;
	 CANIDM[i][2]=(Uchar)(temp1>>8);
	 CANIDM[i][1]=(Uchar)temp2;
	 CANIDM[i][0]=(Uchar)(temp2>>8); 
	 NOP();
	}
    //reset all MObs
    for (i=0; i<15; i++)
    {
        CANPAGE = (i<<4);           //select MOb
        CANCDMOB = 0;           	//disable MOb
        CANSTMOB = 0;               //clear status
        CANIDT1 = 0;        		//clear ID
        CANIDT2 = 0;
        CANIDT3 = 0;
        CANIDT4 = 0;
        CANIDM1 = 0;            	//clear mask
        CANIDM2 = 0;
        CANIDM3 = 0;
        CANIDM4 = 0;
        for (j=0; j<8; j++)
            CANMSG = 0;         //clear data
    }

    //bit timing -> datasheet page 260 (check table) 250Kbps
    //CANBT1 = 0x02;            //16Mhz,1Mbps
    //CANBT2 = 0x04;
    //CANBT3 = 0x13;
    
	//canbaud= EEPROM_read(0x0020);
	//CANBT1 = CanBaud[2][0];         
    //CANBT2 = CanBaud[2][1];
    //CANBT3 = CanBaud[2][2];
	
	CANBT1 = 0x0e;         
    CANBT2 = 0x04;
    CANBT3 = 0x13;
	
    //configure MObi
	/******************************************************************/
   for (i=0; i<15; i++)
   {
	CANPAGE = (i<<4);                   //MOb number 0
     CANIDT1 = CANIDT[i][0];        		//clear ID
     CANIDT2 = CANIDT[i][1];
     CANIDT3 = CANIDT[i][2];
     CANIDT4 = CANIDT[i][3];
     CANIDM1 = CANIDM[i][0];            	//clear mask
     CANIDM2 = CANIDM[i][1];
     CANIDM3 = CANIDM[i][2];
     CANIDM4 = CANIDM[i][3];               //0 = ignore bit
    //CANIDM4 = (1<<IDEMSK);                          //identifier extention mask
     CANCDMOB = (2<<CONMOB) | (1<<IDE);     //reception, ext. ID,rev2.0B
	 NOP();
	}
	
    //CANHPMOB = (2<<HPMOB);
	CANGCON = (1<<ENASTB);              //start CAN interface, enable mode
/***********************************************************************/
    //interrupts
    //CANGIE = (1<<ENIT) | (1<<ENRX);         //enable receive interrupt
	
	CANGIE = (1<<ENIT) | (1<<ENTX)| (1<<ENRX);    //enable receive interrupt and transmitte interrupt 
    /////////////////////////////////////////////////////////////////////// 
	CANIE1 = 0xff;                  
	CANIE2 = 0x7f;                         //enable ALL MObs interrupt
    CANSIT1 = 0;                          //clear MOb status interrupt
    CANSIT2 = 0;
    
///////////////////////////	Enable Mob0 transmit/////////////////////
    CLI();
    CANPAGE = (1<<4);
    CANCDMOB |= (1<<CONMOB0);
/////////////////////////////////////////////////////////////////////

    while (!(CANGSTA & (1<<ENFG)));         //wait until module ready
	
    CANGCON |= (1<<ENA);      //enable CAN controller
}

/*******************************************************************
CAN transmission via mailbox 1 (polling)
*******************************************************************/
void can_tx (VCI_CAN_OBJ msg)
{
    unsigned char i;
	//enable MOb1, auto increment index, start with index = 0
    CANPAGE = (1<<4);

    CANCDMOB = (1<<IDE) | (8<<DLC0);        //set IDE bit rev2.0B, data length = 8

   
	msg.ID <<= 3;                   //write 29 Bit identifier
    CANIDT4 = (unsigned char) (msg.ID&0xF8);
    CANIDT3 = (unsigned char) (msg.ID>>8);
    CANIDT2 = (unsigned char) (msg.ID>>16);
    CANIDT1 = (unsigned char) (msg.ID>>24);
	
    for(i=0;i<8;i++)                               
      {
	   
       CANMSG = msg.Data[i];
	  }
   // for (i=0; i<8; i++)       //put data in mailbox 6
        
    CANCDMOB |= (1<<CONMOB0);           //enable transmission

    //while (!(CANSTMOB & (1<<TXOK)));        //wait until complete
    //CANSTMOB &= ~(1<<TXOK);             //reset flag
}


#define can_TX_BUFFER_SIZE  8
VCI_CAN_OBJ tx_msg_buff[can_TX_BUFFER_SIZE];
Uchar can_sendingP;
Uchar can_willsendP;
Uchar can_tx_count;
Uint CAN_tx_OverFlow= 60000;
void can_tx_buff(VCI_CAN_OBJ tx_msg)
{ 
  CAN_tx_OverFlow = 60000;
  while (can_tx_count == can_TX_BUFFER_SIZE)
   { 
     CAN_tx_OverFlow--;
	 if(CAN_tx_OverFlow<=50)
	   {
	      can_tx_count = 0;
		  can_sendingP = can_willsendP; 
		  CANSTMOB &= ~(1<<TXOK);
		  CAN_tx_OverFlow = 60000;
	   }
   }
  if(can_tx_count || (CANGSTA & (1<<TXBSY)))
  {
     tx_msg_buff[can_willsendP] = tx_msg;
     if(++can_willsendP == can_TX_BUFFER_SIZE)
	     can_willsendP = 0;
	 ++can_tx_count;
  } 
  else 
  {
    if(can_willsendP != can_sendingP)
	{
	  NOP();
	  can_willsendP=0;
	  can_sendingP=0;
	}
    can_tx(tx_msg);
  }  
}


/*******************************************************************
CAN receive interrupt service routine (mailbox i)
*******************************************************************/
#pragma interrupt_handler can_ReceiveData:19
void can_ReceiveData (void)             //receive interrupt 
{Uchar RCFlag;
	unsigned char nb_data;
	unsigned char temp = CANPAGE;           //save CANPAGE
	unsigned char i,tt=0,CAN_REMOb[15],nn;
	unsigned int RC_CANSI,RCtemp1,RCtemp2,tempp,RCF;
	VCI_CAN_OBJ msg[15];

    //VCI_CAN_OBJ CanTkfrm;

	
if(CANSTMOB & (1<<TXOK))
 { 
   CANSTMOB &= ~(1<<TXOK);
   if(can_tx_count)
     {
	   --can_tx_count;
	   can_tx(tx_msg_buff[can_sendingP]);
	   if(++can_sendingP==can_TX_BUFFER_SIZE) can_sendingP=0;
	 }
 }
else 
 {	 
	RCtemp2=CANSIT2;
	RCtemp1=CANSIT1;
	CANSTMOB &= ~(1<<RXOK);
	RC_CANSI=(RCtemp1<<8)|RCtemp2;
    for(i=0;i<15;i++)
	 {
	  tempp=(1<<i);
	  RCF=(RC_CANSI&tempp);
	  if(RCF!=0)
	    {
		 if(i==10)
		   NOP();
		 CAN_REMOb[tt]=i;
		 tt++;
		 }
	 }
	  
   /* for(i=0;i<tt;i++)
	{
	 CANPAGE = (CAN_REMOb[i]<<4);
	 CANSTMOB &= ~(1<<RXOK);
	 for (nb_data = 0; nb_data <(CANCDMOB&DLC_MSK); nb_data++)  
	  {
	   msg[i].Data[nb_data]=CANMSG;
	  }
	   msg[i].ID = 0;
       msg[i].ID |= ((unsigned long) CANIDT1<<24);    //get identifier
       msg[i].ID |= ((unsigned long) CANIDT2<<16);
       msg[i].ID |= ((unsigned long) CANIDT3<<8);
       msg[i].ID |= (CANIDT4&0xF8);
       msg[i].ID >>= 3;
	   CANCDMOB = (2<<CONMOB) | (1<<IDE);
	 }*/
	 
	 for(i=0;i<tt;i++)
	 {
	 CANPAGE = (CAN_REMOb[i]<<4);
	 CANSTMOB &= ~(1<<RXOK);
	 for (nb_data = 0; nb_data <(CANCDMOB&DLC_MSK); nb_data++)  
	   {
	    msg[i].Data[nb_data]=CANMSG;
	   }
	   msg[i].ID = 0;
       msg[i].ID |= ((unsigned long) CANIDT1<<24);    //get identifier
       msg[i].ID |= ((unsigned long) CANIDT2<<16);
       msg[i].ID |= ((unsigned long) CANIDT3<<8);
       msg[i].ID |= (CANIDT4&0xF8);
       msg[i].ID >>= 3;
	   CANCDMOB = (2<<CONMOB) | (1<<IDE);
	 }
	 
	 for(nn=0;nn<tt;nn++)
	 {
/*****************************************************
*          用户程序
*      举例: msg[nn].ID 是ID 号
             msg[nn].date[0]~msg[nn].date[8] 是数据
********************************************************/
	 } 
   }
   CANPAGE = temp;                 //restore CANPAGE
}






⌨️ 快捷键说明

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