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

📄 enc28j60.c

📁 此为ATMEGA32+ENC28J60以太网通信很好的代码,含液晶 按键 HTTP WENB页面显示 已经调试通过.
💻 C
📖 第 1 页 / 共 2 页
字号:
	//enc28j60PhyWrite( PHLCON, 0x0476 );	//enc28j60_flag.rx_buffer_is_free = 1;	_delay_ms(20);}*/void enc28j60_init( BYTE *avr_mac){	// initialize I/O	//DDRB |= _BV( DDB4 );	//CSPASSIVE;	// enable PB0, reset as output 	ENC28J60_DDR |= _BV(ENC28J60_RESET_PIN_DDR);	// enable PD2/INT0, as input	ENC28J60_DDR &= ~_BV(ENC28J60_INT_PIN_DDR);	ENC28J60_PORT |= _BV(ENC28J60_INT_PIN);	// set output to gnd, reset the ethernet chip	ENC28J60_PORT &= ~_BV(ENC28J60_RESET_PIN);	_delay_ms(10);	// set output to Vcc, reset inactive	ENC28J60_PORT |= _BV(ENC28J60_RESET_PIN);	_delay_ms(200);    //		DDRB  |= _BV( DDB4 ) | _BV( DDB5 ) | _BV( DDB7 ); // mosi, sck, ss output	//DDRB &= ~_BV( DDB6 ); // MISO is input	CSPASSIVE;	PORTB &= ~(_BV( PB5 ) | _BV( PB7 ) );	//	// initialize SPI interface	// master mode and Fosc/2 clock:    SPCR = _BV( SPE ) | _BV( MSTR );    SPSR |= _BV( SPI2X );	// perform system reset	enc28j60WriteOp(ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET);	_delay_ms(50);	// check CLKRDY bit to see if reset is complete	// The CLKRDY does not work. See Rev. B4 Silicon Errata point. Just wait.	//while(!(enc28j60Read(ESTAT) & ESTAT_CLKRDY));	// do bank 0 stuff	// initialize receive buffer	// 16-bit transfers, must write low byte first	// set receive buffer start address	next_packet_ptr.word = RXSTART_INIT;    // Rx start	enc28j60Write(ERXSTL, RXSTART_INIT&0xFF);	enc28j60Write(ERXSTH, RXSTART_INIT>>8);	// set receive pointer address	enc28j60Write(ERXRDPTL, RXSTART_INIT&0xFF);	enc28j60Write(ERXRDPTH, RXSTART_INIT>>8);	// RX end	enc28j60Write(ERXNDL, RXSTOP_INIT&0xFF);	enc28j60Write(ERXNDH, RXSTOP_INIT>>8);	// TX start	enc28j60Write(ETXSTL, TXSTART_INIT&0xFF);	enc28j60Write(ETXSTH, TXSTART_INIT>>8);	// TX end	enc28j60Write(ETXNDL, TXSTOP_INIT&0xFF);	enc28j60Write(ETXNDH, TXSTOP_INIT>>8);	// do bank 2 stuff	// enable MAC receive	enc28j60Write(MACON1, MACON1_MARXEN|MACON1_TXPAUS|MACON1_RXPAUS);		// bring MAC out of reset	//enc28j60Write(MACON2, 0x00);	// enable automatic padding to 60bytes and CRC operations	enc28j60Write(MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN);	// 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);	// 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, 63);		// 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);		// Set the maximum packet size which the controller will accept    // Do not send packets longer than MAX_FRAMELEN:	enc28j60Write(MAMXFLL, MAX_FRAMELEN&0xFF);		enc28j60Write(MAMXFLH, MAX_FRAMELEN>>8);		// 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, avr_mac[0]);	enc28j60Write(MAADR4, avr_mac[1]);	enc28j60Write(MAADR3, avr_mac[2]);	enc28j60Write(MAADR2, avr_mac[3]);	enc28j60Write(MAADR1, avr_mac[4]);	enc28j60Write(MAADR0, avr_mac[5]);		// no loopback of transmitted frames	enc28j60PhyWrite(PHCON2, (WORD_BYTES){PHCON2_HDLDIS});		// Magjack leds configuration, see enc28j60 datasheet, page 11	// 0x476 is PHLCON LEDA=links status, LEDB=receive/transmit	// enc28j60PhyWrite(PHLCON,0b0000 0100 0111 00 10);	enc28j60PhyWrite(PHLCON,(WORD_BYTES){0x0472});	// 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);	// set inter-frame gap (back-to-back)	enc28j60Write(MABBIPG, 0x12);		// switch to bank 0	enc28j60SetBank(ECON1);	// enable interrutps	enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, EIE, EIE_INTIE|EIE_PKTIE);	// enable packet reception	enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN);	_delay_ms(20);}//*******************************************************************************************//// Function : enc28j60getrev// Description : read the revision of the chip.////*******************************************************************************************BYTE enc28j60getrev(void){	return(enc28j60Read(EREVID));}//*******************************************************************************************//// Function : enc28j60_packet_send// Description : Send packet to network.////*******************************************************************************************void enc28j60_packet_send ( BYTE *buffer, WORD length ){	//Set the write pointer to start of transmit buffer area	enc28j60Write(EWRPTL, LOW(TXSTART_INIT) );            //EWRPTL写指针	enc28j60Write(EWRPTH, HIGH(TXSTART_INIT) );	// Set the TXND pointer to correspond to the packet size given	enc28j60Write(ETXNDL, LOW((TXSTART_INIT+length)) );    //发送结束低字节(ETXND<7:0>)	enc28j60Write(ETXNDH, HIGH((TXSTART_INIT+length)) );	// write per-packet control byte (0x00 means use macon3 settings)	enc28j60WriteOp(ENC28J60_WRITE_BUF_MEM, 0, 0x00);	CSACTIVE;	// issue write command	SPDR = ENC28J60_WRITE_BUF_MEM;	waitspi();	while(length)	{		length--;		// write data		SPDR = *buffer++;		waitspi();	}	CSPASSIVE;		// send the contents of the transmit buffer onto the network	enc28j60WriteOp(ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS);       //将ECON1.TXRTS 位置1 开始发送。	                                                                   //TXRTS:发送请求位                                                                     //1 = 发送逻辑正在尝试发送数据包                                                                     //0 = 发送逻辑空闲	// Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12.	if( (enc28j60Read(EIR) & EIR_TXERIF) )                              //TXERIF: 发送错误中断标志位                                                                      //1 = 已发生发送错误中断                                                                      //0 = 未发生发送错误中断	{		enc28j60WriteOp(ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRTS);	}}//*******************************************************************************************//// Function : enc28j60_mac_is_linked// Description : return MAC link status.////*******************************************************************************************/*BYTE enc28j60_mac_is_linked(void){	if ( (enc28j60_read_phyreg(PHSTAT1) & PHSTAT1_LLSTAT ) )		return 1;	else		return 0;}*///*******************************************************************************************//// Function : enc28j60_packet_receive// Description : check received packet and return length of data////*******************************************************************************************//WORD data_length;WORD enc28j60_packet_receive ( BYTE *rxtx_buffer, WORD max_length ){	WORD_BYTES rx_status, data_length;		// check if a packet has been received and bufferedPKTIF: 接收数据包待处理中断标志位//1 = 接收缓冲器包含一个或多个未处理的数据包;当PKTDEC 置1 时清零//0 = 接收缓冲器为空	// if( !(enc28j60Read(EIR) & EIR_PKTIF) ){     //	// The above does not work. See Rev. B4 Silicon Errata point 6.	if( enc28j60Read(EPKTCNT) == 0 )	{		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 (see datasheet page 43)	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 (see datasheet page 43)	rx_status.bytes[0] = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);	rx_status.bytes[1] = enc28j60ReadOp(ENC28J60_READ_BUF_MEM, 0);		if ( data_length.word > (max_length-1) )	{		data_length.word = max_length-1;	}		// check CRC and symbol errors (see datasheet page 44, table 7-3):	// The ERXFCON.CRCEN is set by default. Normally we should not	// need to check this.	if ( (rx_status.word & 0x80)==0 )	{		// invalid		data_length.word = 0;	}	else	{		// read data from rx buffer and save to rxtx_buffer		rx_status.word = data_length.word;		CSACTIVE;		// issue read command		SPDR = ENC28J60_READ_BUF_MEM;		waitspi();		while(rx_status.word)		{			rx_status.word--;			SPDR = 0x00;			waitspi();			*rxtx_buffer++ = SPDR;		}		CSPASSIVE;	}		// 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 );}

⌨️ 快捷键说明

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