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

📄 main.c

📁 GZ60的can通信源程序 用c语言编写
💻 C
字号:
#include <hidef.h> /* for EnableInterrupts macro */
#include <MC68HC908GZ60.h> /* include peripheral declarations */
#define canrecebuff  0x00000540
#define cansendbuff0 0x00000550
#define cansendbuff1 0x00000560
#define cansendbuff2 0x00000570
#define can_datafram 1;
#define can_remoutefram 2;

void CANInit(word value_void);
byte CANsnd1DFrm(unsigned int rid,unsigned char * databuf,unsigned char len);
unsigned char CANrcv1Frm(unsigned char * CANRcvbuf);
void delay(word count);
byte can_send_return_value;
byte can_rece_return_value;
byte cansend_data_buff[8];
byte can_rece_databuff[16]=0;
byte a;

void main(void) {
  EnableInterrupts; /* enable interrupts */
  /* include your code here */
   CONFIG2_MSCANEN=1;	  //启用can
   	CANInit(1);

  for(;;) {
    __RESET_WATCHDOG(); /* feeds the dog */
 	
 		cansend_data_buff[0]='c';
 		cansend_data_buff[1]='a';
 		cansend_data_buff[2]='n';
 	
 	 			
    can_send_return_value=CANsnd1DFrm(0x0140,cansend_data_buff,0x03);
 		can_rece_return_value=CANrcv1Frm(can_rece_databuff);
 
 
  } /* loop forever */
  /* please make sure that you never leave this function */
}





  		 //------------------------------------------------------------------------------------------------//
//程序名:void CANInit(unsigned char time1,unsigned char time0)
//功能:CAN初始化
//入口:无
//出口:无
//说明:在16M CAN总线频率下将总线速率设为400kbps,
//      节点标识符设为0
//--------------------------------------------------------------------------------------------------//
void CANInit(word value_void) {
   
  
 
   CMCR0_SFTRES=1 ;//控制寄存器的软复位标志为1
   CMCR1_CLKSRC=0; //MSCAN08时钟源选择外部晶振(二分频);即若外部晶振为16M时,fmscan=8M	  //
   CMCR1_LOOPB=1;   //自测方式
   CMCR1_WUPM=1;
   CBTR0=0x01;      //同步跳转宽度为1,预分频因子为2
   CBTR1=0x25;    //同步跳转宽度=1(Tq),时间段1=6(Tq),TSEG2=3(Tq) 位时间=1+6+3=10(Tq);
                       //速率设为400kbps   
   CIDAC=0x00;       //1次验收滤波器模式
   CIDAR0=0b00000001;      
   CIDAR1=0b01000000;			//给接收代码寄存器0-1赋值,节点标示符号为10
   CIDMR0=0x00;     //给接收屏蔽寄存器0-1赋值
   CIDMR1=0x1F;
   CMCR0=0x00;  //正常模式					  
}
   //------------------------------------------------------------------//
//程序名:unsigned char CANsnd1DFrm(unsigned int rid, 
//   unsigned char * databuf,unsigned char len)
//功能:CAN发送1帧(数据长度<=8)处理子程序
//入口:unsigned int rid---报文标识符,
//      unsigned char * databuf---报文数据区首址
//      unsigned char len---报文数据长度
//出口:unsigned char CANsnd1DFrm --- 发送成功与否标志,
//     =0,没有空闲发送缓冲区,发送不成功;=1,发送成功
//说明:在发送数据之前,先查询是否有空闲发送缓冲区
//      若无,则不能发送,返回0。
//------------------------------------------------------------------//
byte CANsnd1DFrm(unsigned int rid,unsigned char * databuf,unsigned char len)
{	 byte free_buf_num; 
   unsigned char j;
   unsigned char * addr;
   if(CTFLG&0x07==0)
   return 0;  
   	 
    if (CTFLG_TXE0==1)
    free_buf_num=0;  
    else if (CTFLG_TXE1==1)
       free_buf_num=1;
    else  	free_buf_num=2;                   //查找空闲的发送缓冲区 第一个buff的优先级最高
	
   addr=(unsigned char *)(cansendbuff0)+0x10*free_buf_num;//计算相应缓冲区首地址 
   //--------------------------------------------------------//
   //将报文按CAN格式进行封装并存入空闲发送缓冲区等待发送
   addr[0]=(unsigned char)(rid >>8); //11位报文标识符高8位
   addr[1]=((unsigned char)rid);     //低3位
   addr[1] &=0xE7;              //RTR=0,数据帧  ;IDE位=0 
              
   for(j=0;j<len;j++)
      addr[j+4]=databuf[j];          //数据赋值
   addr[12]=len;                     //数据长度
   
  if (free_buf_num==0)
   CTFLG_TXE0=1;
   else if (free_buf_num==1)
   CTFLG_TXE1=1;
   else CTFLG_TXE2=1;//发送缓冲区相应TXE位写1,通知MSCAN08发送数据
   
   return(1);          //数据成功写入空闲缓冲区,返回1
}

  
  void delay(word count) {
	word i;
	for (i=0; i<count; i++);
}

//------------------------------------------------------------------//
//程序名:unsigned char CANrcv1Frm(unsigned char * CANRcvbuf)
//功能:CAN接收1帧子程序
//入口:无
//出口:unsigned char CANrcv1Frm---函数名,表示接收帧的情况,
//      =0xff,未收到帧;=1,收到数据帧;=2,收到远程帧
//      unsigned char * CANRcvbuf--若收到报文,为16字节报文的首地址
//说明: 
//------------------------------------------------------------------//
unsigned char CANrcv1Frm(unsigned char * CANRcvbuf)
{   
   unsigned char tt=0;
   unsigned char * addr;
   unsigned char ss=0;
   if (CRFLG_RXF==0) 
    return 0xff;  //未收到数据,返回0xff
   addr=(unsigned char *)canrecebuff;  //RXF=1,表示收到数据,取数据处理
   for(tt=0;tt<16;tt++)
     CANRcvbuf[tt]=addr[tt];   //将CAN接收缓冲区中的数据取到临时缓冲区
   CRFLG=0x00;                 //清所有接收标志 
   //------判断是标准帧还是扩展帧---------------------------//
   tt=CANRcvbuf[1]; 
   tt&=0x08;         //取标识符中IDE标志
   if (tt!=0x08)          //是否为标准帧
   {  
     if(CANRcvbuf[1]&0x10==0x10) //取标识符中RTR标志 ;判断是数据帧还是远程帧
      ss=can_remoutefram;												  
     if(CANRcvbuf[1]&0x10==0x00)//取标识符中RTR标志 ;判断是数据帧还是远程帧
     ss=can_datafram; 
   }
   else 
      ss=0xFF;          //不处理扩展帧
 
      return ss;    //返回数据帧标志(1)或远程帧(2)标志
}

⌨️ 快捷键说明

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