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

📄 can._c

📁 工业开关量检测模块的原代码,带断线检测功能
💻 _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,Pass_Flag;
unsigned char canbaud;
extern VCI_CAN_OBJ rece_data[3];

const Uchar CanBaud[6][3]={{0x02,0x04,0x13},{0x06,0x04,0x13},{0x0E,0x04,0x13},{0x12,0x04,0x13},{0x1E,0x04,0x13},{0x26,0x04,0x13}};
//波特率数组

//15个MOB的ID和MID
unsigned long CANMOBID[15]={0x10000000,0x20000000,0x30000000,0x40000000,0x50000000,0x60000000,0x01000000,0x01000001,0x0200ff00,0x12000001,0x01000002,0x01000003,0x01000004,0x01000005,0x1300ff01};
unsigned long CANMOBMD[15]={0x0000ffff,0x0000ffff,0x0000ffff,0x00ff00ff,0x00ff00ff,0x00ff00ff,0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff,0x1fffffff};
unsigned char CANIDT[15][4]={0};
unsigned char CANIDM[15][4]={0};
Uchar counterTemp,send_count;

void can_init (void)                            //CAN初始化函数
{
 canMob_init();
}


void canMob_init (void)                       //MOB初始化函数
{
    unsigned char i,j;
	unsigned long temp;
	unsigned int temp1,temp2;
	
	CLI();                                    //关中断
	//DDRD=(1<<PD5)|(0<<PD6);   //TXCAN, RXCNA
	DDRD|=0x20;                               //CAN管脚初始化
	DDRD&=0xBF;
	CANGCON |= (1<<SWRES);              //reset CAN interface
    
	Pass_Flag = 0x00;
	//CANMOBID[2]=(unsigned long)(SELFID<<8)|CANMOBID[2];
	for(i=0;i<6;i++)                          //15个邮箱初始化
	{
	 temp=CANMOBID[i]<<3;                      //ID初始化
	 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); 
	 Pass_Flag = Pass_Flag + 1;
	 NOP();
	}
    if(Pass_Flag!=0x06)
	  RESET;
	 WDR();
	 
	 Pass_Flag = 0x00;
	for(i=0;i<6;i++)
	{
	 temp=CANMOBMD[i]<<3;
	 temp1=(unsigned int)temp;               //低16位
	 temp2=(unsigned int)(temp/0x00010000);  //高16位
	 CANIDM[i][3]=(Uchar)temp1;
	 CANIDM[i][2]=(Uchar)(temp1>>8);
	 CANIDM[i][1]=(Uchar)temp2;
	 CANIDM[i][0]=(Uchar)(temp2>>8); 
	 Pass_Flag = Pass_Flag + 1;
	 NOP();
	}
	 if(Pass_Flag!=0x06)
	  RESET;
    //reset all MObs
	
	 Pass_Flag = 0x00;
    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
			
	     Pass_Flag = Pass_Flag + 1;		
    }
	  if(Pass_Flag!=0x0f)
	    RESET;
		
	 WDR();
	CANBT1 = CanBaud[2][0];         
    CANBT2 = CanBaud[2][1];
    CANBT3 = CanBaud[2][2];
	
    //configure MObi
	/******************************************************************/
	
	 Pass_Flag = 0x00;
   for (i=0; i<3; i++)
   {
	 CANPAGE = (i<<4);                   //MOb 0,1,2设置为发送模式
     CANIDT1 = CANIDT[i][0];        		//初始化 ID
     CANIDT2 = CANIDT[i][1];
     CANIDT3 = CANIDT[i][2];
     CANIDT4 = CANIDT[i][3];
     CANIDM1 = CANIDM[i][0];            	//初始化 mask
     CANIDM2 = CANIDM[i][1];
     CANIDM3 = CANIDM[i][2];
     CANIDM4 = CANIDM[i][3];               //0 = ignore bit
    //CANIDM4 = (1<<IDEMSK);                          //identifier extention mask
     CANCDMOB = (1<<IDE)|(8<<DLC0);     //reception, ext. ID,rev2.0B
	 NOP();
	 Pass_Flag = Pass_Flag + 1;		
	}
	 
	  if(Pass_Flag!=0x03)
	    RESET;
		
	 WDR();
	 
	  Pass_Flag = 0x00;
	for(i=3;i<6;i++)                       
	{
	 CANPAGE = (i<<4);                   //MOb3,4,5设置为接受模式
     CANIDT1 = CANIDT[i][0];        		//初始化 ID
     CANIDT2 = CANIDT[i][1];
     CANIDT3 = CANIDT[i][2];
     CANIDT4 = CANIDT[i][3];
     CANIDM1 = CANIDM[i][0];            	//初始化 mask
     CANIDM2 = CANIDM[i][1];
     CANIDM3 = CANIDM[i][2];
     CANIDM4 = CANIDM[i][3];               //0 = ignore bit
     CANCDMOB = (2<<CONMOB0)|(1<<IDE)|(8<<DLC0);     //reception, ext. ID,rev2.0B
	 NOP();
	  Pass_Flag = Pass_Flag + 1;		
	}
	   if(Pass_Flag!=0x03)
	    RESET;
		
	CANGCON = (1<<ENASTB);                //start CAN interface, enable mod
	
	CANGIE = (1<<ENIT)| (1<<ENRX)|(1<<ENTX);    //enable receive interrupt and transmitte interrupt 
	CANIE1 = 0x00;                  
	CANIE2 = 0x3f;                              //enable ALL MObs interrupt
    
	 WDR();
    while (!(CANGSTA & (1<<ENFG)));         //wait until module ready
	
    CANGCON |= (1<<ENA);      //enable CAN controller
	
	SEI();
}



/*******************************************************************
CAN transmission via mailbox 1 (polling)
*******************************************************************/
void can_tx (VCI_CAN_OBJ msg)
{
    unsigned char i,index,pass_Flag;
	pass_Flag = 0x01;
	index =(unsigned char) (msg.ID%256);   
	pass_Flag <<= 1;
	msg.ID <<= 3;     
    CANPAGE = (index<<4);
    CANCDMOB = (1<<IDE) |(8<<DLC0);   
	pass_Flag <<= 1;                                               
    CANIDT4 = (unsigned char) (msg.ID&0xF8);
    CANIDT3 = (unsigned char) (msg.ID>>8);
    CANIDT2 = (unsigned char) (msg.ID>>16);
	pass_Flag <<= 1;
    CANIDT1 = (unsigned char) (msg.ID>>24);
	if(pass_Flag!=0x08)
	  RESET;
    for(i=0;i<8;i++)                               
      {
	   
       CANMSG = msg.Data[i];
	  }        
    CANCDMOB |= (1<<CONMOB0);           //enable transmission
}


#pragma interrupt_handler can_ReceiveData:19
void can_ReceiveData (void)             //receive interrupt 
{
	unsigned char nb_data;
	unsigned char i,nn,err_temp,sta_temp;
	unsigned int RC_CANSI,RCtemp2,tempp,RCF;
	VCI_CAN_OBJ msg[3];
	
	WDR();
    CANGIE &= ~((1<<ENRX)|(1<<ENTX));                  //关接收中断
	RCtemp2=CANSIT2;                       //读取中断信息
	err_temp = CANTEC;                     //读取发送错误计数器
	
	if(err_temp>96)                       
	RESET;
	
	err_temp = CANREC;                   //读取接收错误计数器
	if(err_temp>128)
	RESET;
	
	if(RCtemp2&(0x07))
	{
	for(i=0;i<3;i++)                    //查询前三个邮箱中断状态
	{
	  tempp=(1<<i);
	  RCF=(RCtemp2&tempp);
	   if(RCF!=0)
	    {  
		 CANPAGE = i<<4;
		 sta_temp = CANSTMOB;
		 if(sta_temp&0x40)             //是发送完成中断
		 {
		  send_count = 0;              //清发送计数器
		     if(LED)
			 
	           PORTB |=  0x40;
		      else 
			  
		       PORTB &=  0xbf;
		   
		    WDR();
		 }
		}
	}
	}
	else if(RCtemp2&(0x38))
	{
    for(i=3;i<6;i++)                       //判断哪个邮箱产生接收中断
	 {
	  tempp=(1<<i);
	  RCF=(RCtemp2&tempp);
	  if(RCF!=0)
	    {  
		    if(LED)
             PORTB |= 0X80;
			else
		      PORTB &= 0X7f;
		  CANPAGE = i<<4;
		   WDR();
		  for (nb_data = 0; nb_data <8; nb_data++)  
	      {
	        rece_data[i-3].Data[nb_data]=CANMSG;
	       }
	   rece_data[i-3].ID = 0;
       rece_data[i-3].ID |= ((unsigned long) CANIDT1<<24);    //get identifier
       rece_data[i-3].ID |= ((unsigned long) CANIDT2<<16);
       rece_data[i-3].ID |= ((unsigned long) CANIDT3<<8);
       rece_data[i-3].ID |= (CANIDT4&0xF8);
       rece_data[i-3].ID >>= 3;
		 }
	 }
	 }
		CANSTMOB &= ~((1<<RXOK)|(1<<TXOK));
		CANCDMOB = 0x98;                      //接收使能 
		CANGIE |= (1<<ENRX);                   //开中断 
		CANGIE |= (1<<ENTX);      
		 WDR();
}






⌨️ 快捷键说明

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