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

📄 enc28j60.c

📁 enc28j60-ok 我已经调试好的哟哈
💻 C
📖 第 1 页 / 共 2 页
字号:
	                                            // enable MAC receive
	ENC28J60Write(MACON1, MACON1_TXPAUS | MACON1_RXPAUS | MACON1_MARXEN);

	                                            // Allow infinite deferals if the medium is continuously busy 
                                                // (do not time out a transmission if the half duplex medium is 
                                                // completely saturated with other people's data)
    ENC28J60Write(MACON4, MACON4_DEFER);

	                                            // Set the maximum packet size which the controller will accept
                                                // Do not send packets longer than MAX_FRAMELEN:
	ENC28J60Write(MAMXFLL, LOW(MAX_FRAMELEN));	// 网络节点一般被设计为处理不大于1518 字节的数据包
	ENC28J60Write(MAMXFLH, HIGH(MAX_FRAMELEN));
	                                            // set inter-frame gap (back-to-back)
	ENC28J60Write(MABBIPG, 0x12);
	                                            // Set non-back-to-back inter-packet gap to 9.6us.  The back-to-back 
	                                            // inter-packet gap (MABBIPG) is set by MACSetDuplex() which is called 
	                                            // later.
	ENC28J60Write(MAIPGL, 0x12);
	ENC28J60Write(MAIPGH, 0x0C);
	                                            // Late collisions occur beyond 63+8 bytes (8 bytes for preamble/start of frame delimiter)
	                                            // 55 is all that is needed for IEEE 802.3, but ENC28J60 B5 errata for improper link pulse 
	                                            // collisions will occur less often with a larger number.
    ENC28J60Write(MACLCON2, 100);
    ENC28J60Write(MACLCON2, 63);
	                                            // do bank 3 stuff
                                                // write MAC address
	                                            // NOTE: MAC address in ENC28J60 is byte-backward
	                                            // ENC28J60 is big-endian avr gcc is little-endian
	ENC28J60Write(MAADR5, mac[0]);
	ENC28J60Write(MAADR4, mac[1]);
	ENC28J60Write(MAADR3, mac[2]);
	ENC28J60Write(MAADR2, mac[3]);
	ENC28J60Write(MAADR1, mac[4]);
	ENC28J60Write(MAADR0, mac[5]);

	temp.word = 0x0000;                         // 
	ENC28J60WritePhy(PHCON1, temp);	
	
	temp.word = PHCON2_HDLDIS;                  // no loopback of transmitted frames
	ENC28J60WritePhy(PHCON2, temp);
	
	                                            // Magjack leds configuration, see enc28j60 datasheet, page 11
	                                            // 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit
	temp.word = 0x0122;                         // enc28j60PhyWrite(PHLCON,0b0000 0100 0111 00 10);
	ENC28J60WritePhy(PHLCON, temp);

	                                            // do bank 1 stuff, packet filter:
	                                            // For broadcast packets we allow only ARP packtets
	                                            // All other packets should be unicast only for our mac (MAADR)
	                                            // The pattern to match on is therefore
	                                            // Type     ETH.DST
	                                            // ARP      BROADCAST
 	                                            // 06 08 -- ff ff ff ff ff ff -> ip checksum for theses bytes=f7f9
	                                            // in binary these poitions are:11 0000 0011 1111
	                                            // This is hex 303F->EPMM0=0x3f,EPMM1=0x30
	ENC28J60Write(ERXFCON, ERXFCON_UCEN|ERXFCON_CRCEN|ERXFCON_PMEN);
	ENC28J60Write(EPMM0, 0x3f);
	ENC28J60Write(EPMM1, 0x30);
	ENC28J60Write(EPMCSL, 0xf9);
	ENC28J60Write(EPMCSH, 0xf7);
    
    
    ENC28J60WriteOp(ENC28J60_BIT_FIELD_SET,ECON1, ECON1_TXRTS | ECON1_RXEN);
    if(0x0000==ENC28J60ReadPhy(PHCON1)&PHCON1_PDPXMD)                        // 从物理层判断模式                                      
	    ENC28J60Write(MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN); // enable automatic padding to 60bytes and CRC operations   
    else
        ENC28J60Write(MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN|MACON3_FULDPX);
	                                            // switch to bank 0
	ENC28J60SetBank(ECON1);

    ENC28J60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_AUTOINC); //指针自动加一
	ENC28J60WriteOp(ENC28J60_BIT_FIELD_CLR, EIR, EIR_TXIF);	
	                                            // enable interrutps
	ENC28J60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE);
	                                            // enable packet reception
	ENC28J60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);

    VICIntEnable = 1 << 16;                     //初始化完毕,开启中断
}

/*******************************************************************************
*名称: ENC28J60PacketSend()    

*功能: ENC28J60发送以太网包数据
*******************************************************************************/
u8_t IsTxReady(void)
{
    return !(ENC28J60Read(ECON1)&ECON1_TXRTS);
}


void ENC28J60PacketSend ( u8_t *buffer, u16_t length )
{
	                                                  //Set the write pointer to start of transmit buffer area
	ENC28J60Write( ETXSTL, LOW(TXSTART_INIT));
	ENC28J60Write( ETXSTH, HIGH(TXSTART_INIT));

	ENC28J60Write( EWRPTL, LOW(TXSTART_INIT));
	ENC28J60Write( EWRPTH, HIGH(TXSTART_INIT));
    if(length > 1500)
    {
        length = 1500;
    }
 
	                                                  // Set the TXND pointer to correspond to the packet size given
	ENC28J60Write( ETXNDL, LOW(TXSTART_INIT+length));
	ENC28J60Write( ETXNDH, HIGH(TXSTART_INIT+length));
	
	ENC28J60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x0F);   //写控制字节
    ENC28J60WriteBuf(buffer,length);                  // 写缓冲
	                                                  
	                                                  
	//UART0_SendByte('L');
	//UART0_SendByte(HexToAsc(length/1000));
	//UART0_SendByte(HexToAsc((length%1000)/100));                                                  
	//UART0_SendByte(HexToAsc((length%100)/10));                                                  
	//UART0_SendByte(HexToAsc(length%10));
	
	                                                  
	                                                  // 请求发送   send the contents of the transmit buffer onto the network
	ENC28J60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);
	                                                  // 查看是否发送无错误   Reset the transmit logic problem.
	if( (ENC28J60Read(EIR) & EIR_TXERIF) )
	{
		ENC28J60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS);
	}
}
/*******************************************************************************
*名称: ENC28J60PacketReceive()    

*功能: ENC28J60接收以太网包数据
*******************************************************************************/
u16_t ENC28J60PacketReceive ( u8_t *buffer, u16_t max_length  )
{
	WORD_BYTES rx_status, data_length;
	
	                                                 // check if a packet has been received and buffered
	if( ENC28J60Read(EPKTCNT) == 0 )
	{
	    ENC28J60CheckRxPtr();
	    return 0;
	}
	                                                 // Set the read pointer to the start of the received packet
	ENC28J60Write(ERDPTL, next_packet_ptr.bytes[0]);
	ENC28J60Write(ERDPTH, next_packet_ptr.bytes[1]); 
	                                                 // read the next packet pointer
	next_packet_ptr.bytes[0] = ENC28J60ReadOp(ENC28J60_READ_BUF_MEM, 0);
    next_packet_ptr.bytes[1] = ENC28J60ReadOp(ENC28J60_READ_BUF_MEM, 0);

	                                                 // read the packet length
	data_length.bytes[0] = ENC28J60ReadOp(ENC28J60_READ_BUF_MEM, 0);
	data_length.bytes[1] = ENC28J60ReadOp(ENC28J60_READ_BUF_MEM, 0);
	data_length.word -=4;                            //remove the CRC count
	
	                                                 // read the receive status 
	rx_status.bytes[0] = ENC28J60ReadOp(ENC28J60_READ_BUF_MEM, 0);
	rx_status.bytes[1] = ENC28J60ReadOp(ENC28J60_READ_BUF_MEM, 0);
    OS_ENTER_CRITICAL();	
	if ( data_length.word > (max_length-1) )
	{
		data_length.word = max_length-1;
	}

	                                                // need to check this.
	if ( (rx_status.word & 0x80)==0 )               // 接收成功,表示数据包具有有效的CRC,无符号错误。
	{                                  
		data_length.word = 0;                       // invalid
	}
	else
	{
		                                            // read data from rx buffer and save to rxtx_buffer
        ENC28J60ReadBuf(buffer,data_length.word);
	}
    OS_EXIT_CRITICAL();		
                                                    // Move the RX read pointer to the start of the next received packet
	                                                // 释放缓冲    This frees the memory we just read out
	ENC28J60Write(ERXRDPTL, next_packet_ptr.bytes[0]);
	ENC28J60Write(ERXRDPTH, next_packet_ptr.bytes[1]);
	                                                // decrement the packet counter indicate we are done with this packet
	ENC28J60WriteOp(ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC);
    

    return data_length.word;

}



/*******************************************************************************
*名称: ENC28J60PacketReceive()    

*功能: ENC28J60接收以太网包数据
*******************************************************************************/
u16_t ENC28J60PacketLength ( u16_t max_length )
{
	WORD_BYTES data_length;
	                                                 // read the packet length
	data_length.bytes[0] = ENC28J60ReadOp(ENC28J60_READ_BUF_MEM, 0);
	data_length.bytes[1] = ENC28J60ReadOp(ENC28J60_READ_BUF_MEM, 0);
	data_length.word -=4;                            //remove the CRC count	
	if ( data_length.word > (max_length-1) )
	{
		data_length.word = max_length-1;
	}	
	
    return data_length.word;
}
/*******************************************************************************
*名称: ENC28J60CheckRxPtr()    

*功能: ENC28J60检查接收指针
*******************************************************************************/
void ENC28J60CheckRxPtr ( void )
{
    WORD_BYTES rxwr_ptr;
    WORD_BYTES rxrd_ptr;
  
	if( ENC28J60Read(EPKTCNT) == 0 )
	{
        rxwr_ptr.bytes[0] = ENC28J60Read(ERXWRPTL);
        rxwr_ptr.bytes[1] = ENC28J60Read(ERXWRPTH);
     
        rxrd_ptr.bytes[0] = ENC28J60Read(ERXRDPTL);
        rxrd_ptr.bytes[1] = ENC28J60Read(ERXRDPTH);	    
	    if(rxwr_ptr.word != rxrd_ptr.word)   
	    {
	        ENC28J60Write(ERDPTL, rxwr_ptr.bytes[0]);
	        ENC28J60Write(ERDPTH, rxwr_ptr.bytes[1]); 
	    	ENC28J60Write(ERXRDPTL, rxwr_ptr.bytes[0]);
	        ENC28J60Write(ERXRDPTH, rxwr_ptr.bytes[1]);
	        next_packet_ptr.bytes[0] = rxwr_ptr.bytes[0];
	        next_packet_ptr.bytes[1] = rxwr_ptr.bytes[1];
	    }
	}
}









⌨️ 快捷键说明

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