请教关于C8051F040+CP2200的问题 总是发现自动协商失败

wangjian801213   2008-8-25 16:21 楼主
我自己划的板子由C8051F040和CP2200组成 使用PM34-1006变压器进行输入网络信号  发现程序初始化没有问题 但是CP2200时钟无法完成自动协商

我曾经买了块C8051F020的网络开发板 使用Silabs成功使用了UDP通信 所以我把CP2201的四根网络输入线 直接接上了自己划板子的CP2200 还是没有反应(因为这样连接可能有问题)

所以还是期待变压器的正确连接 虽然排除不了本身程序的问题 但是直觉还是信号没有进来  我把CP2200的底层驱动帖出来 希望大家帮帮忙!
unsigned char CP2200_HW_Reset(void)
{
   char SFRPAGE_SAVE = SFRPAGE;
   data unsigned char temp_char;

   CP2200_RST_Low();//将cp2200的复位脚置低
   
   wait_ms(20);                 
   
   //--------------------------------------------------------------------------
   // Step 1: Wait for the reset pin to rise.
   //--------------------------------------------------------------------------
   CP2200_RST_High();//将cp2200的复位脚置高
   
   //--------------------------------------------------------------------------
   // Step 2 + 3: Wait for oscillator and self initializaion to complete
   //--------------------------------------------------------------------------          

   wait_ms(5000);
   /* wait for OSC Init interrupt */
   while(INT_PIN)
   {
   }           

   // INT0 is not reading 0xFF;
   wait_ms(1000);
   while(((temp_char & 0x30) != 0x30) || (temp_char == 0xFF))
   {
       temp_char = INT0RD;
   }
               
   // Verify communication

   if(RXHASHH != 0x04)
   {  
      return MEM_ERROR;
   }   

   // Read and write the RAM at 0x7FF in the transmit buffer
   // we can verify the send/rev buffer normal
   RAMADDRH = 0x07;
   RAMADDRL = 0xFF;

   RAMTXDATA = 0x00;

   if(RAMTXDATA != 0x00)             
   {   
      return MEM_ERROR;
   }
   
   RAMTXDATA = 0xFF;

   if(RAMTXDATA != 0xFF)
   {   
      return MEM_ERROR;
   }
   
   /* Init has completed */

   //--------------------------------------------------------------------------
   // Step 4: Disable Interrupts For Events that will not be monitored
   //--------------------------------------------------------------------------   
   
   // Disable All Interrupts except for the packet received interrupt
   INT0EN = 0x03;     //关中断   允许接收缓冲区满和数据包已接收中断
                  
   INT1EN = 0x00;
   
   // Clear all Interrupt Flags by reading the self-clearing status registers                          
   temp_char = INT0;                     
   temp_char = INT1;
                       
   SFRPAGE = SFRPAGE_SAVE;

   debug_ledDn = 1;

   return 0;

}


unsigned char PHY_Init()
{
   char SFRPAGE_SAVE = SFRPAGE;
   unsigned char temp_char;
   unsigned char retval = 0;
   unsigned char i = 0;
   
   // Step 1: Disable the PHY
   PHYCN = 0x00;  //禁止phy
  
   // Step 2: Enable the PHY with link integrity test and auto-negotiation
   // turned off
      
   // A. Disable the Transmitter Power Save Option and Configure Options
   TXPWR = 0x80;

   PHYCF = ( SMSQ | JABBER | ADPAUSE | AUTOPOL);//配置phy工作方式         enable auto-negotiate

   // B. Enable the Physical Layer
   PHYCN = PHYEN;//允许phy

   wait_ms(10);

   PHYCN = ( PHYEN | TXEN | RXEN );
  
   wait_ms(2000);
   // Step 3: Poll the Wake-on-Lan Interrupt
      
   // A. Clear Interrupt Flags
   temp_char = INT1;//清除中断标志


   
   // C. Check for a signal
   for(i = 0 ; i < 150; i++)
   {
      wait_ms(10);

      temp_char = INT1RD;
      // If a signal is detected, wait 250 ms, then continue
      if(temp_char & WAKEINT)
          {
         wait_ms(250);

                 debug_ledUp = 0;
         break;
      }
   }

   //--------------------------------------------------------------------------
   // Physical Layer Initialization (Section 15.7 of CP220x Datasheet)
   //--------------------------------------------------------------------------
   // Step 1: Synchronization procedure implemented above

   // Step 2: Disable the physical layer
   PHYCN = 0x00;
   
   // Step 3: Configure the desired physical layer options including
   // auto-negotiation and link integrity
   PHYCF = ( SMSQ | LINKINTG | JABBER | AUTONEG | ADPAUSE | AUTOPOL );
  
   // Step 4: Enable the physcial layer
      
   // A. Enable the Physical Layer
      PHYCN = PHYEN;

   // B. Wait for the physical layer to power up
      wait_ms(10);

   // C. Enable the Transmitter and Receiver
   // Auto-negotiation begins now
      PHYCN = ( PHYEN | TXEN | RXEN );
  

   // Step 5: Wait for auto-negotiation to complete

   // Clear INT1 Interrupt Flags
      temp_char = INT1;
  
      // Check for autonegotiation fail or complete flag
     for(i = 0; i < 60; i++)
         {
             wait_ms(100);
             temp_char = INT1RD;

         // If Auto-Negotiation Completes/Fails, break
         if(temp_char & (ANCINT | ANFINT))
                 {
            break;            
         }   
      }


      // Mask out all bits except for auto negotiation bits
      temp_char = INT1RD;            //中断状态寄存器1
      temp_char &= (ANCINT | ANFINT);  //0x01 | 0x04 = 0x05           与后仅仅观察自动协商的标志位

      // Check if Auto-Negotiation has FAILED
      if(temp_char & ANFINT)
          {                     //自动协商失败
      
         // Auto-Negotiation has failed
         retval = LINK_ERROR;
   
      }
          else if(temp_char == ANCINT)                           // Check if Auto-Negotiation has PASSED
          {                       
      
         // Auto-Negotiation has passed
         retval = 0;                 

      }
          else  
      {           
         retval = LINK_ERROR;
      }

   SFRPAGE = SFRPAGE_SAVE;
   return retval;      
}

回复评论 (4)

小弟先谢过了
点赞  2008-8-26 10:16
点赞  2008-8-30 10:06
自动协商不需要软件参与就可完成。如不能成功,该是硬件有问题。可能是连线错误。
点赞  2008-9-3 22:53
能不能把你的CP2200 的UDP 通讯代码发给我学习学习呢?邮箱283090402@QQ.com
谢谢了
点赞  2008-11-25 10:24
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复