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

📄 main.c

📁 c8051f040实验程序含CAN SMBUS IIC
💻 C
📖 第 1 页 / 共 2 页
字号:
unsigned char PHY_Init()
{
   unsigned char temp_char;
   unsigned char retval = 0;
   
   //--------------------------------------------------------------------------
   //以下部分为物理层自适应同步,详见CP2200数据手册
   //--------------------------------------------------------------------------

   
      PHYCN = 0x00;  // 禁止物理层寄存器
   
   
      TXPWR = 0x80;
      PHYCF = ( SMSQ | JABBER | ADPAUSE | AUTOPOL );

      // 使能物理层 
      PHYCN = PHYEN;
     
      // 物理层上电
          
      PHYCN = ( PHYEN | TXEN | RXEN ); //  使能传输与接收寄存器
   	  // 唤醒中断
     
           
      temp_char = INT1;

 
     

   //--------------------------------------------------------------------------
   //以下是物理层初始化
   //--------------------------------------------------------------------------
   
   
    PHYCN = 0x00; //禁止物理层寄存器
  
   
    PHYCF = ( SMSQ | LINKINTG | JABBER | AUTONEG | ADPAUSE | AUTOPOL ); //进行连接完整性与自适应配置
   
    PHYCN = PHYEN;//使能物理层
    PHYCN = ( PHYEN | TXEN | RXEN ); //  使能传输与接收寄存器
  

   
      temp_char = INT1;
          
      while(1){
         
                if(INT1RD & (ANCINT | ANFINT))break; 	 // 判断初始化是成功
		  	     
               }

      temp_char = INT1RD;
      temp_char &= (ANCINT | ANFINT);

      
      if(temp_char & ANFINT)          // 检测自适应是否失败 
	     {
      	  retval = LINK_ERROR;
	   	 } 
	  else 
   								       
      
           if(temp_char == ANCINT)	  // 检测自适应是否通过
	         {
            	retval = 0;
	            IOPWR = 0x0C;   	  // 使能 Link LED and Activity LED 
         	 }
		   else     
             { 
              retval = LINK_ERROR;
    		 }

     return retval;
     
}

/***********************************************************************/
//数据链路层初始化
/***********************************************************************/

void MAC_Init(void)
{  

   //判断是否为全双工通讯,并进行相关设置 详见CP2200数据手册
   if(PHYCN & 0x10)
     {
      MAC_Write(MACCF, 0x40B3);
      MAC_Write(IPGT, 0x0015);
      } 
   else 
     {
	  MAC_Write(MACCF, 0x4012);
      MAC_Write(IPGT, 0x0012); 
	 }
      MAC_Write(IPGR, 0x0C12);
      MAC_Write(MAXLEN, 0x05EE);

   // 读出厂前设置的MAC地址
   FLASHADDRH = 0x1F;
   FLASHADDRL = 0xFA;

   MYMAC.Char[0] = FLASHAUTORD;
   MYMAC.Char[1] = FLASHAUTORD;
   MYMAC.Char[2] = FLASHAUTORD;
   MYMAC.Char[3] = FLASHAUTORD;
   MYMAC.Char[4] = FLASHAUTORD;
   MYMAC.Char[5] = FLASHAUTORD;      
   my_hwaddr[0]=MYMAC.Char[0];
   my_hwaddr[1]=MYMAC.Char[1];
   my_hwaddr[2]=MYMAC.Char[2];
   my_hwaddr[3]=MYMAC.Char[3];
   my_hwaddr[4]=MYMAC.Char[4];
   my_hwaddr[5]=MYMAC.Char[5];
  
   MAC_SetAddress(&MYMAC); 

   MAC_Write(MACCN, 0x0001);           // 允许回环模式

}
/************************************************************************/
//访问MAC间接寄存器
/************************************************************************/
void MAC_Write(unsigned char mac_reg_offset, unsigned int mac_reg_data)
{   
   MACADDR = mac_reg_offset;              
   MACDATAH = (mac_reg_data >> 8);    // Copy High Byte
   MACDATAL = (mac_reg_data & 0xFF);  // Copy Low Byte
   MACRW = 0;
   
   return;
}


/**************************************************************************/
//设置MAC地址
/**************************************************************************/
void MAC_SetAddress(MACADDRESS* pMAC)
{
   UINT1 temp_int;

   temp_int.Char[0] = pMAC->Char[5];
   temp_int.Char[1] = pMAC->Char[4];
   MAC_Write(MACAD0, temp_int.Int);
   
   temp_int.Char[0] = pMAC->Char[3];
   temp_int.Char[1] = pMAC->Char[2];
   MAC_Write(MACAD1, temp_int.Int);
   
   temp_int.Char[0] = pMAC->Char[1];
   temp_int.Char[1] = pMAC->Char[0];
   MAC_Write(MACAD2, temp_int.Int);
   
   return;
}

/**************************************************************************/
// 以太网帧接收函数
/**************************************************************************/
void eth_rcve(UCHAR xdata * inbuf)
{
   ETH_HEADER xdata * eth;
   eth = (ETH_HEADER xdata *)inbuf;
   if (eth->frame_type < 1520)	   // 帧长度不能超过IEEE 802标准归定
      {
	    return;      
      }
     
   switch (eth->frame_type)	      //根据接收到的数据包类型,选择不同的处理方式
      {
	   case ARP_PACKET:
	        arp_rcve(inbuf);
	        break;
		      
	   case IP_PACKET:
	        ip_rcve(inbuf);
            break;
	   default:break;
      }
}

/*************************************************************************/
//以太网帧传输函数--------传输层
/*************************************************************************/
void eth_send(UCHAR xdata * outbuf, UCHAR * hwaddr, UINT ptype, UINT len)
{
	ETH_HEADER xdata * eth;
   
   eth = (ETH_HEADER xdata *)outbuf;
	  
	//加入14位的以太网数据帧头标识
	memcpy(eth->dest_hwaddr, hwaddr, 6);
	memcpy(eth->source_hwaddr, my_hwaddr, 6); 
    eth->frame_type = ptype;
	CP220x_Send(outbuf, len + 14); // 增加数据包长度
}

/*************************************************************************/
// CP2200发送函数
/*************************************************************************/
void CP220x_Send( UCHAR xdata * outbuf, UINT len)
{

   int i; 
   unsigned int ramaddr;

                                        // 定义宏来增加地址指针
   #define INC_RAMADDR  ramaddr++; \
                        RAMADDRH = (ramaddr >> 8);\
                        RAMADDRL = (ramaddr & 0x00FF);


   
   while(TXBUSY);                       //等待传输结束
      
       TXSTARTH = 0x00;
       TXSTARTL = 0x00;
	   RAMADDRH = 0x00;				    //地址设为零
       RAMADDRL = 0x00;
       ramaddr = 0x0000;
	        
       for(i = 0; i < len; i++)
	      {
           RAMTXDATA = outbuf[i];
           INC_RAMADDR
          }
      
       while(ramaddr < 64)			  	//将不足64字节长度的数据填充到64字节
	    {
          RAMTXDATA = 0;
          INC_RAMADDR
        }
      
        ramaddr--;			        
        TXENDH = (ramaddr >> 8);		  //将RAM地址减一后赋给TXEND使其地址为)X0040
        TXENDL = (ramaddr & 0x00FF);
        TXSTARTH = 0x00;
        TXSTARTL = 0x00;                  //将TXSTAR地址归零
        TXCN = 0x01;	                  //向TXGO写1开始传输
}

/****************************************************************/
//CP2200芯片接收数据函数
/****************************************************************/
UCHAR xdata * rcve_frame(void)

{
   bit rx_ok;
   bit skip = 0;
   UINT1 cplen;   
   unsigned int i;
   UCHAR xdata * buf;

   unsigned char interrupt_read;
   unsigned char valid_bits;
   unsigned char num_packets;

   
   interrupt_read = INT1;
   interrupt_read = INT0;	                   //清中断标志
   
   
   if( interrupt_read & RXINT)                 //判断接收中断是否产生
   {   
      
      valid_bits = TLBVALID;     			   //对接收数据包进行统计
	    for(num_packets = 0; valid_bits; num_packets++)      
          {                                 
           valid_bits &= valid_bits - 1; 
          }
   
     
        if( num_packets >= 7) 			      //接收区超过7个数据包,停止接收
          {
           RXCN = RXINH;           
          }
	}

      //以下步骤参考CP2200数据手册的接收部分              
      rx_ok = (CPINFOL & RXOK) && (CPINFOH & RXVALID);
      
      if(rx_ok)
	  {
   		cplen.Char[0] = CPLENH;
        cplen.Char[1] = CPLENL;
	    buf=inbuf1;
	       
      }
      else
	   { 
	    cplen.Int = 0;
        skip = 1;      
	    buf = NULL;
       }   
	      
      if(1)
	  {	     
           for(i = 0; i < cplen.Int; i++)
		     {
              buf[i] = RXAUTORD;
             }
	  	   rcve_buf_allocated = TRUE;
	   } 
	   else 
	   { 
          cplen.Int = 0;
          skip = 1; 
        }
      
     if(skip)
      {
       RXCN |= 0x02;                   
      } 

     else 
       {
        RXCN |= 0x04;                   
       }
	    
     if(TLBVALID == 0x00)
       {
        RXCN = 0x00;   
       }
   
     return(buf);
}


⌨️ 快捷键说明

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