#include #include //////////////////////////////////////////////////////////////////////////////// // ATmega8: // начальное: RC - 1 МHz: Low E1; Higt D9; // RC - 8 МHz: Low E4; Higt D9; // кварц - 8 МHz: Low EF; Higt C9 (CKOPT -on); XTAL2 – выход--V // кварц - 8 МHz: Low EF; Higt D9 (CKOPT -off); // XTAL1 – вход: Low E0; Higt D9 //////////////////////////////////////////////////////////////////////////////// // ATmega328: // начальное: RC -1 МHz: Higt D9; Ext 07; Lok 3F; Low 62 // RC -8 МHz: Higt D9; Ext 07; Lok 3F; Low E2 // кварц - 20 МHz: Higt D9; Ext 07; Lok 3F; Low E7(CKOUT -off); XTAL2 – выход--V // кварц - 20 МHz: Higt D9; Ext 07; Lok 3F; Low E7(CKOUT -on); CKOUT – выход //////////////////////////////////////////////////////////////////////////////// // W5500: // 3,3 V - 80 mA. - 10 МБит/c // 3,3 V - 135 mA. - 100 МБит/c // Socket_0 - MACRAW // Socket_1 - UDP //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// счёт: unsigned char x; // x - счёт unsigned char x1; // x1 - счёт unsigned char x2; // x2 - счёт //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// SPI: unsigned char tx; // tx - SPI unsigned char rx; // rx - SPI ////////////////////////////////// SPI: void SPI(void) { SPDR=tx; while(!(SPSR & (1<<7))); rx=SPDR; } //////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////// UDP: unsigned char RX_int[160]={ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; unsigned int RX_len; unsigned char RX_IP[4]={0,0,0,0}; unsigned int RX_port; //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// W5500: unsigned int add; // add - адрес данных W5500 (RX/TX) unsigned int len; // len - длина данных W5500 (RX/TX) //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////// TX_UDP: void TX_UDP(void) { /////////////////////////////////////////////// TX: W5500: // пишем MAC, IP, порт > Destination ////////////////////////////// Socket_1 + Register Block 1: (0000 1... BSB[4:0]блок) PORTB.0=0; // SS W5500 // (для команды SEND без автоматического ARP-запроса) //tx=0x00; SPI(); tx=0x06; SPI(); tx=0x2C; SPI(); // MAC, IP, порт // (для команды SEND c автоматическим ARP-запросом): -8 ARP tx=0x00; SPI(); tx=0x0C; SPI(); tx=0x2C; SPI(); //(MAC = ARP), IP, порт // MAC адрес: //tx=0xff; SPI(); // Data // Destination Hardware Address (Sn_DHAR0)(0x0006 - Address) //tx=0xff; SPI(); // Data // Destination Hardware Address (Sn_DHAR1)(0x0007 - Address) //tx=0xff; SPI(); // Data // Destination Hardware Address (Sn_DHAR2)(0x0008 - Address) //tx=0xff; SPI(); // Data // Destination Hardware Address (Sn_DHAR3)(0x0009 - Address) //tx=0xff; SPI(); // Data // Destination Hardware Address (Sn_DHAR4)(0x000A - Address) //tx=0xff; SPI(); // Data // Destination Hardware Address (Sn_DHAR5)(0x000B - Address) //RX_IP > IP адрес: tx=RX_IP[0]; SPI(); // Data // Destination IP Address (Sn_DIPR0)(0x000C - Address) tx=RX_IP[1]; SPI(); // Data // Destination IP Address (Sn_DIPR1)(0x000D - Address) tx=RX_IP[2]; SPI(); // Data // Destination IP Address (Sn_DIPR2)(0x000E - Address) tx=RX_IP[3]; SPI(); // Data // Destination IP Address (Sn_DIPR3)(0x000F - Address) // порт: tx=0x00; SPI(); // Data // Destination Port (Sn_DPORT0) (0x0010 - Address) -порт 80 tx=0x50; SPI(); // Data // Destination Port (Sn_DPORT1) (0x0011 - Address) -порт 80 PORTB.0=1; // SS W5500 /////////////////////////////////////////////// TX: W5500: // Читаем начальный адрес для записи данных Socket 1 Sn_TX_WR: PORTB.0=0; // SS W5500 tx=0x00; SPI(); tx=0x24; SPI(); tx=0x28; SPI(); // Address + Control Registers tx=0x00; SPI(); x1 = rx; // Data -Sn_TX_WR0 -начальный адрес для записи данных //сарший регистр tx=0x00; SPI(); x2 = rx; // Data -Sn_TX_WR1 -начальный адрес для записи данных //младший регистр PORTB.0=1; // SS W5500 add=x1; add = (add<<8)|x2; // начальный адрес для записи данных // 0x0000...0xFFFF /////////////////////////////////////////////// TX: W5500: //Пишем данные с начального адреса буфера Socket 1 TX Buffer: x1 = (add>>8); x2 = add; PORTB.0=0; // SS W5500 tx=x1; SPI(); tx=x2; SPI(); tx=0x34; SPI(); // Address + Control Registers /////////////////////////////////////////////// TX: W5500: len = 0; // сброс len // UDP // IP | port | len | Data. // IP - 0x00 0x00 0x00 0x00 // port - 0x00 0x00 // len - 0x00 0x00 (len=Data). /////////////////////////////////////////////// TX: RX_int > W5500: for (x=0; x<32 ; x++) { tx=RX_int[x]; SPI(); len++; }; PORTB.0=1; // SS W5500 /////////////////////////////////////////////// TX: W5500: // Пишем регистр указателя Socket 1 Sn_TX_WR до увеличенного значения: add = add + len; x1 = (add>>8); x2 = add; PORTB.0=0; // SS W5500 tx=0x00; SPI(); tx=0x24; SPI(); tx=0x2C; SPI(); // Address + Control Registers tx=x1; SPI(); // Data -Sn_TX_WR0 -конечный адрес передачи данных //сарший регистр tx=x2; SPI(); // Data -Sn_TX_WR1 -конечный адрес передачи данных //младший регистр PORTB.0=1; // SS W5500 /////////////////////////////////////////////// TX: W5500: //Пишем команду передачи SEND Socket 1 Command: PORTB.0=0; // SS W5500 tx=0x00; SPI(); tx=0x01; SPI(); tx=0x2C; SPI(); // Address + Control Registers tx=0x20; SPI(); // Data -0x20 (команда SEND c автоматическим ARP-запросом) //tx=0x21; SPI();// Data -0x21 (команда SEND без автоматического ARP-запроса) PORTB.0=1; // SS W5500 /////////////////////////////////////////////// TX: W5500: //If (Sn_CR == 0x00) по окончанию передачи статус меняется на Sn_CR = 0x00 } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// void main(void) { /////////////////////////////////////////////// SPI (мастер) DDRB.5=1; // выход SCK PORTB.5=0; // выход SCK DDRB.4=0; // вход MISO PORTB.4=0; // вход MISO DDRB.3=1; // выход MOSI PORTB.3=0; // выход MOSI DDRB.2=1; // выход SS (! SS настроен на выход) PORTB.2=1; // выход SS (! SS настроен на выход) /////////////////////////////////////////////// W5500 DDRD.0=0; // вход INT W5500 PORTD.0=1; // вход INT W5500 + DDRD.5=1; // выход RESET W5500 PORTD.5=1; // выход RESET W5500 DDRB.0=1; // выход SS W5500 PORTB.0=1; // выход SS W5500 //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// SPI: SPCR=0x50; // 8 МГц/4 = 2 МГц -режим мастер //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////// инициализация W5500: // 00000000 - Address Registers (автоматическая инкрементная адресация +1). // 00000000 - Address Registers (автоматическая инкрементная адресация +1). /////////////////////////////////////////////// // Control Registers: // 0000 0... - BSB [4:0] блок // .... .0.. - R/W - 0 чтение/1 запись // .... ..00 - OP Mode (VDM)- данные переменной длины (Длина данных контролируется SS). /////////////////////////////////////////////// RESET W5500: PORTD.5=0; // delay_ms(100); // PORTD.5=1; // delay_ms(100); // //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// W5500 PHY: // перед настройкой PHY сделать программный Cброс PHY: PORTB.0=0; // SS W5500 tx=0x00; SPI(); tx=0x2E; SPI(); tx=0x04; SPI(); // Address Registers + Control Registers tx=0x00; SPI(); // Data -0x00 tx=0x00; SPI(); // Data -0x00 PORTB.0=1; // SS W5500 // пишем режим PHY: // 1... .... RST - 1. // .1.. .... программная настройка режима - 1 // ..0. .... 10BT Full-duplex, Auto-negotiation disabled / Power Down mode // ...0 .... 10BT Full-duplex, Auto-negotiation disabled / Power Down mode // .... 1... 10BT Full-duplex, Auto-negotiation disabled / Power Down mode // .... .1.. Duplex Status // .... ..0. Speed Status // .... ...1 Link Status PORTB.0=0; // SS W5500 tx=0x00; SPI(); tx=0x2E; SPI(); tx=0x04; SPI(); // Address Registers + Control Registers tx=0xC8; SPI(); // Data -0xC8 (10 Мбит/с, Full-duplex) tx=0x00; SPI(); // Data -0x00 PORTB.0=1; // SS W5500 //////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////// настройка W5500: PORTB.0=0; // SS W5500 tx=0x00; SPI(); tx=0x01; SPI(); tx=0x04; SPI(); // Address Registers + Control Registers // -шлюз tx=192; SPI(); // Gateway Address (GAR0) (0x0001 - Address) tx=168; SPI(); // Gateway Address (GAR1) (0x0002 - Address) tx=0; SPI(); // Gateway Address (GAR2) (0x0003 - Address) tx=1; SPI(); // Gateway Address (GAR3) (0x0004 - Address) // -маска tx=255; SPI(); // Subnet Mask Address (SUBR0) (0x0005 - Address) tx=255; SPI(); // Subnet Mask Address (SUBR1) (0x0006 - Address) tx=255; SPI(); // Subnet Mask Address (SUBR2) (0x0007 - Address) tx=0; SPI(); // Subnet Mask Address (SUBR3) (0x0008 - Address) // -MAC (Wiznet_01:02:03) tx=0x00; SPI(); // Source Hardware Address (SHAR0) (0x0009 - Address) tx=0x08; SPI(); // Source Hardware Address (SHAR1) (0x000A - Address) tx=0xDC; SPI(); // Source Hardware Address (SHAR2) (0x000B - Address) tx=0x01; SPI(); // Source Hardware Address (SHAR3) (0x000C - Address) tx=0x02; SPI(); // Source Hardware Address (SHAR4) (0x000D - Address) tx=0x03; SPI(); // Source Hardware Address (SHAR5) (0x000E - Address) // -IP tx=192; SPI(); // Source IP Address (SIPR0) (0x000F - Address) tx=168; SPI(); // Source IP Address (SIPR1) (0x0010 - Address) tx=0; SPI(); // Source IP Address (SIPR2) (0x0011 - Address) tx=3; SPI(); // Source IP Address (SIPR3) (0x0012 - Address) PORTB.0=1; // SS W5500 //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// Socket_1 - UDP: // Протокол: пишем протокол UDP Socket_1: PORTB.0=0; // SS W5500 tx=0x00; SPI(); tx=0x00; SPI(); tx=0x2C; SPI(); // Address Registers + Control Registers tx=0x02; SPI(); // Data 0x02 -protocol UDP. PORTB.0=1; // SS W5500 // Порт: пишем Port Source Socket_1: PORTB.0=0; // SS W5500 tx=0x00; SPI(); tx=0x04; SPI(); tx=0x2C; SPI(); // Address Registers + Control Registers tx=0x00; SPI(); // Data -0x1F (порт 80) tx=0x50; SPI(); // Data -0x40 (порт 80) PORTB.0=1; // SS W5500 // пишем команду OPEN Socket_1: PORTB.0=0; // SS W5500 tx=0x00; SPI(); tx=0x01; SPI(); tx=0x2C; SPI(); // Address Registers + Control Registers tx=0x01; SPI(); // Data -0x01 (команда OPEN) PORTB.0=1; // SS W5500 //////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////// Socket_1 - INT: // INT Mask Socket_1: пишем INT Mask Socket_1: (SIMR) 0x0018 PORTB.0=0; // SS W5500 tx=0x00; SPI(); tx=0x18; SPI(); tx=0x04; SPI(); // Address Registers + Control Registers tx=0x02; SPI(); // Data 0x02 -Enable INT Socket_1 . PORTB.0=1; // SS W5500 // INT Mask Socket_1 RECV: пишем INT Mask завершение приёма Socket_1: (Sn_IMR) 0x002C PORTB.0=0; // SS W5500 tx=0x00; SPI(); tx=0x2C; SPI(); tx=0x2C; SPI(); // Address Registers + Control Registers tx=0x04; SPI(); // Data 0x04 -INT Mask завершение приёма. PORTB.0=1; // SS W5500 //////////////////////////////////////////////////////////////////////////////// _1: //////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////// TX_UDP: delay_ms(1); //////////////////////////////////////////////////////////////////////////////// // проверка INT RX_UDP: if (PIND.0 == 1) {goto _1;}; // UDP пуст > _1 // пишем: сброс флаг завершение приёма INT Socket_1: (Sn_IR) 0x0002 PORTB.0=0; // SS W5500 tx=0x00; SPI(); tx=0x02; SPI(); tx=0x2C; SPI(); // Address Registers + Control Registers tx=0x04; SPI(); // Data 0x04 -сброс флаг завершение приёма. PORTB.0=1; // SS W5500 // читаем размер принятых данных Socket_1 Sn_RX_RSR: PORTB.0=0; // SS W5500 tx=0x00; SPI(); tx=0x26; SPI(); tx=0x28; SPI(); // Address + Control Registers tx=0x00; SPI(); x1 = rx; // Data -Sn_RX_RSR0 -размер принятых данных //сарший регистр tx=0x00; SPI(); x2 = rx; // Data -Sn_RX_RSR1 -размер принятых данных //младший регистр PORTB.0=1; // SS W5500 // проверка размер принятых данных // 0x0000...0xFFFF len=x1; len=(len<<8)|x2; if (len == 0x00) { goto _1; // UDP пуст > _1 }; //////////////////////////////////////////////////////////////////////////////// // Читаем начальный адрес принятых данных Socket_1 Sn_RX_RD PORTB.0=0; // SS W5500 tx=0x00; SPI(); tx=0x28; SPI(); tx=0x28; SPI(); // Address tx=0x00; SPI(); x1 = rx; // Data -Sn_RX_RD0 -начальный адрес принятых данных //сарший регистр tx=0x00; SPI(); x2 = rx; // Data -Sn_RX_RD1 -начальный адрес принятых данных //младший регистр PORTB.0=1; // SS W5500 add=x1; add=(add<<8)|x2; // начальный адрес принятых данных // 0x0000...0xFFFF //////////////////////////////////////////////////////////////////////////////// // Читаем данные с начального адреса буфера Socket_1 RX Buffer: x1 = (add>>8); x2 = add; PORTB.0=0; // SS W5500 tx=x1; SPI(); tx=x2; SPI(); tx=0x38; SPI(); // Address + Control Registers // UDP // IP | port | len | Data. // IP - 0x00 0x00 0x00 0x00 // port - 0x00 0x00 // len - 0x00 0x00 (len=Data). // RX_IP - 0x00 0x00 0x00 0x00 for (x=0; x<4; x++) { tx=0; SPI(); RX_IP[x]=rx; }; // RX_port - 0x00 0x00 tx=0x00; SPI(); RX_port=rx; RX_port=(RX_port<<8); tx=0x00; SPI(); RX_port|=rx; // RX_len - 0x00 0x00 tx=0x00; SPI(); RX_len=rx; RX_len=(RX_len<<8); tx=0x00; SPI(); RX_len|=rx; // UDP > RX_int for (x=0; x<32; x++) { tx=0x00; SPI(); RX_int[x]=rx; }; PORTB.0=1; // SS W5500 //////////////////////////////////////////////////////////////////////////////// // Пишем регистр указателя Sn_RX_RD до увеличенного значения: add = add + len; //add - начальный/конечный адрес принятых данных // 0x0000...0xFFFF //len - размер полученных данных // 0x0000...0xFFFF x1 = (add>>8); x2 = add; PORTB.0=0; // SS W5500 tx=0x00; SPI(); tx=0x28; SPI(); tx=0x2C; SPI(); // Address + Control Registers tx=x1; SPI(); // Data -Sn_RX_RD0 -конечный адрес принятых данных //сарший регистр tx=x2; SPI(); // Data -Sn_RX_RD1 -конечный адрес принятых данных //младший регистр PORTB.0=1; // SS W5500 //////////////////////////////////////////////////////////////////////////////// // Пишем команду завершения приема RECV: PORTB.0=0; // SS W5500 tx=0x00; SPI(); tx=0x01; SPI(); tx=0x2C; SPI(); // Address + Control Registers tx=0x40; SPI(); // Data -0x40 (команда RECV) PORTB.0=1; // SS W5500 //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// TX_UDP(); // > TX_UDP() //////////////////////////////////////////////////////////////////////////////// goto _1; // > _1 //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// }