O projeto é o mesmo deste aqui http://microcontroladores-c.blogspot.com.br/2014/01/servidor-web-com-wiz820-usando-o.html que já foi explicado aqui no blog o que muda é somente o código fonte utilizado,usei a porta 5000 e a porta padrão de ethernet (porta 80), para acessar o hardware basta digitar no browser 192.168.50.141 e para acessar o socket0 192.168.50.141:5000, segue abaixo o exemplo:
O código fonte :
//*********************************************************************************************************** // Usando o modulo wiz820io // // no gravador configurar os fuses assim: // EXTENDED 0XFF // HIGH 0XD8 - neste modo funciona com qualquer valor de cristal usei um de 16Mhz // LOW 0XC7 // LOKBITS 0XFF - sem proteção // // // versão : 1 // descrição : Servidor web que aceita 2 conexões com o modulo modulo wiz820 // para isso vamos ter o mesmo IP mas portas diferentes // aqui no exemplo será a porta 5000 e a porta 5001 // Autor : Aguivone // microcontrolador : ATmega328P // compilador : AVR-GCC / Atmel AVR Studio 4.17 // Data do projeto : 03 / 04 / 2014 // aviso! - no modulo wiz 820 deve ser colocado um capacitor de 100nF no pino de reset para evitar problemas de ruido //************************************************************************************************************* #include <avr/io.h> #include <string.h> #include <stdio.h> #include <util/delay.h> #include <avr/interrupt.h> #include <avr/pgmspace.h>// AVRJazz Mega328 SPI I/O ////////////////////////funçoes auxiliares///////////////////////////// #define liga_pino(x,y) x |= _BV(y) #define desliga_pino(x,y) x &= ~(_BV(y)) ///////////////////////////////////////////////////////////////////////////////////////////// //configuração dos pinos SPI #define SPI_PORT PORTB //porta que será usado para SPI #define SPI_DDR DDRB #define SPI_SS PORTB2//seleção de chip(habilita comunicação SPI) // Wiznet W5200 endereço dos registradores #define MR 0x0000 // Registrador de modo #define GAR 0x0001 // endereço(inicial) de Gateway : 0x0001 a 0x0004 #define SUBR 0x0005 // mascara de subrede : 0x0005 a 0x0008 #define SHAR 0x0009 // Source Address Register , endereço de hardware (MAC) : 0x0009 a 0x000E #define SIPR 0x000F // IP do hardware(escolhido pelo programador): 0x000F to 0x0012 //Socket 0 #define RTR 0x0017 // timeout #define RCR 0x0019 // timeout /////////////////configurei apenas o sockt0 pois vou usar apenas este./////////////// /* para colocar mais socket 2 por exemplo (0X4n00) S0_PORT 0X4204 lembre que agora os buffer de rx e tx mudaram uma vez que o wiz820 tem capacidade para até 7 sockets */ /////////////// socket 0 /////////////////////////////////////////////////////// #define S0_MR 0x4000 // Socket 0: registrador do socket0 #define S0_CR 0x4001 // Socket 0: registrador de comandos do socket0 #define S0_IR 0x4002 // Socket 0: registrador de interrupçoes do socket0 #define S0_SR 0x4003 // Socket 0: registrador de status do socket0 #define S0_PORT 0x4004 // Socket 0: aqui é colocado o valor da porta TCP -> endereço = 0x0404 a 0x0405 #define S0_DPORT 0x4010 // Socket 0: aqui é colocado o valor da porta TCP de destino-> endereço = 0x0410 a 0x0411 #define S0_DHAR 0x4006 // Socket 0: endereçamento de registro de hardware(tipo MAC)-> endereço = 0x0406 a 0x040B #define S0_DIPR 0x400C // Socket 0: IP de acesso remoto -> endereço = 0x040C a 0x040F #define SO_TX_FSR 0x4020 // Socket 0: tamanho do registrador de transmissão: 0x0420 to 0x0421 #define S0_TX_RD 0x4022 // Socket 0: ponteiro de leitura do buffer de transmissão : 0x0422 a 0x0423 #define S0_TX_WR 0x4024 // Socket 0: ponteiro de escrita do buffer de transmissão: 0x0424 a 0x0425 #define S0_RX_RSR 0x4026 // Socket 0: tamanho do registrador de recepção: 0x0426 a 0x0427 #define S0_RX_RD 0x4028 // Socket 0: ponteiro de leitura do tamanho dos dados: 0x0428 a 0x0429 #define S0_IMR 0x402C // mascara de interrupção dos sockets #define RMSR0 0x401E // RX - localização do buffer de recepção #define TMSR0 0x401F // TX - localização do buffer de envio ///////////////socket 1 //////////////////////////////////////////////////////////////////////////////////////// #define S1_MR 0x4100 // Socket 1: registrador do socket1 #define S1_CR 0x4101 // Socket 1: registrador de comandos do socket1 #define S1_IR 0x4102 // Socket 1: registrador de interrupçoes do socket1 #define S1_SR 0x4103 // Socket 1: registrador de status do socket1 #define S1_PORT 0x4104 // Socket 1: aqui é colocado o valor da porta TCP -> endereço = 0x0404 a 0x0405 #define S1_DPORT 0x4110 // Socket 1: aqui é colocado o valor da porta TCP de destino-> endereço = 0x0410 a 0x0411 #define S1_DHAR 0x4106 // Socket 1: endereçamento de registro de hardware(tipo MAC)-> endereço = 0x0406 a 0x040B #define S1_DIPR 0x410C // Socket 1: IP de acesso remoto -> endereço = 0x040C a 0x040F #define S1_TX_FSR 0x4120 // Socket 1: tamanho do registrador de transmissão: 0x0420 to 0x0421 #define S1_TX_RD 0x4122 // Socket 1: ponteiro de leitura do buffer de transmissão : 0x0422 a 0x0423 #define S1_TX_WR 0x4124 // Socket 1: ponteiro de escrita do buffer de transmissão: 0x0424 a 0x0425 #define S1_RX_RSR 0x4126 // Socket 1: tamanho do registrador de recepção: 0x0426 a 0x0427 #define S1_RX_RD 0x4128 // Socket 1: ponteiro de leitura do tamanho dos dados: 0x0428 a 0x0429 #define S1_IMR 0x412C // mascara de interrupção dos sockets #define RMSR1 0x411E // RX - localização do buffer de recepção do socket 1 #define TMSR1 0x411F // TX - localização do buffer de envio do socket 1 //////////////////endereços de escrita e recepção ////////////////////// #define TXBUFADDR0 0x8000 // W5200 posição inicial do buffer de escrita #define RXBUFADDR0 0xC000 // W5200 posição inicial do buffer de recepção /////socket1 pois o tamanho é de 4096(4K) #define TXBUFADDR1 0x9000 // W5200 posição inicial do buffer de escrita #define RXBUFADDR1 0xD000 // W5200 posição inicial do buffer de recepção ////////////comando do chip//////////////////////////////////////////// //MR (possiveis configuração) #define MR_CLOSE 0x00 // socket não usado #define MR_TCP 0x01 // TCP #define MR_UDP 0x02 // UDP #define MR_IPRAW 0x03 // IP LAYER RAW SOCKET #define MR_MACRAW 0x04 // MAC LAYER RAW SOCKET #define MR_PPPOE 0x05 // PPPoE #define MR_ND 0x20 // sem delay de Ack(somente TCP) #define MR_MULTI 0x80 // suporte ao multicast(valido somente para UDP) // CR values #define CR_OPEN 0x01 // Initializa ou abre socket #define CR_LISTEN 0x02 // espera resposta de um ponto na rede (no modo tcp(modo servidor)) #define CR_CONNECT 0x04 // envia resposta a um ponto da rede(modo cliente) #define CR_DISCON 0x08 // finaliza conexão e gera interrupção se falhar(desconexão) #define CR_CLOSE 0x10 // desconecta socket #define CR_SEND 0x20 // atualiza memoria de transmissão e envia dados #define CR_SEND_MAC 0x21 // envia dados com o endereço do MAC, sem o processo ARP(modo UDP) #define CR_SEND_KEEP 0x22 // ckeca estado da conexão - envia um byte pra testar a conexão (modo tcp) #define CR_RECV 0x40 // indica uma recepção no socket //SR values #define SOCK_CLOSED 0x00 // socket fechado #define SOCK_INIT 0x13 // inicializa conexão #define SOCK_LISTEN 0x14 // verifica estado(listen) #define SOCK_SYNSENT 0x15 // comando de conexão foi iniciado #define SOCK_SYNRECV 0x16 // houve sincronismo de recepção #define SOCK_ESTABLISHED 0x17 // sucesso na conexão #define SOCK_FIN_WAIT 0x18 // esperando finalizar #define SOCK_CLOSING 0x1A // finalizando conexão #define SOCK_TIME_WAIT 0x1B // espera tempo para finaliza #define SOCK_CLOSE_WAIT 0x1C // recebeu comando de fechar pelo host #define SOCK_LAST_ACK 0x1D // durante a finalização é o ultimo ack #define SOCK_UDP 0x22 // UDP socket #define SOCK_IPRAW 0x32 // IP raw socket #define SOCK_MACRAW 0x42 // MAC raw socket #define SOCK_PPPOE 0x5F // PPPOE socket #define TX_BUF_MASK 0x0FFF // Mascara do buffer de transmissão 4K (4096 - 1 = 4095 = 0X0FFF) #define RX_BUF_MASK 0x0FFF // Mascara do buffer de recepção 4K (4096 - 1 = 4095 = 0X0FFF) #define NET_MEMORIA 0x04 // Use 4K de Tx/Rx Buffer(pode se usar até 16K) #define TCP_PORT 80 // porta TCP/IP usada pelo modulo #define MAX_BUF 50 // tamanho maximo do buffer de recepção ///////// //////// variaveis globais //////////////////////////////////////// //////// uint8_t buf[MAX_BUF]; uint8_t sockstat; uint16_t rsize; int get_pos; char radiostat0[10],radiostat1[10]; unsigned char temp[2];//usado para passar os defines - variavel auxiliar /////////variaveis da serial/////////////////////// unsigned char caracter;// unsigned int tam_buffer;//usado para contar o tamanho do buffer de recepção unsigned char buffer_serial[14];//buffer da serial volatile char rec_buffer ='S';//usado para ler o buffer de recepção (volatile para funcionar pois sempre ira retornar mesmo valor) void inicializa_spi(void) { // Seta MOSI (PORTB3),SCK (PORTB5) and PORTB2 (SS) , e os outros pinos como saida SPI_DDR = (1<<PORTB3)|(1<<PORTB5)|(1<<PORTB2)|(1<<PORTB1);//coloca b1 como saida // SS não ativado SPI_PORT |= (1<<SPI_SS); // habilita SPI, modo mestre 0, seta clock para fck/2 SPCR = (1<<SPE)|(1<<MSTR); SPSR |= (1<<SPI2X); } ///////////////////////função de escrita SPI//////////////////////// void spi_escreve(unsigned int endereco,unsigned char *dados,unsigned int tamanho) { // ativa pino de habilitação do SPI SPI_PORT &= ~(1<<SPI_SS); //******************** endereço ************************ // escreve bytes mais significativo no buffer spi SPDR = (endereco & 0xFF00) >> 8; // espera finalizar a transmissão while(!(SPSR & (1<<SPIF))); //escreve os bytes menos significativo no buffer spi SPDR = endereco & 0x00FF; // espera finalizar a transmissão while(!(SPSR & (1<<SPIF))); //******************** Opcode + tamanho dos dados************************ SPDR = ((0X80)|((tamanho & 0xFF00) >> 8));//indica que vai escrever(opcode) // espera finalizar a transmissão while(!(SPSR & (1<<SPIF))); //escreve os bytes menos significativo no buffer spi SPDR = tamanho & 0x00FF; // espera finalizar a transmissão while(!(SPSR & (1<<SPIF))); unsigned int contagem=0; while(contagem<tamanho) { SPDR = dados[contagem]; // inicializa transmissão de dados while(!(SPSR & (1<<SPIF))); // espera finalizar a transmissão // finaliza comunicação. contagem++; } SPI_PORT |= (1<<SPI_SS); } /////////////////////////de leitura//////////////////////////////// unsigned char spi_ler(unsigned int endereco) { // ativa pino de habilitação do SPI SPI_PORT &= ~(1<<SPI_SS); //******************** endereço ************************ // escreve bytes mais significativo no buffer spi SPDR = (endereco & 0xFF00) >> 8; // espera finalizar a transmissão while(!(SPSR & (1<<SPIF))); //escreve os bytes menos significativo no buffer spi SPDR = endereco & 0x00FF; // espera finalizar a transmissão while(!(SPSR & (1<<SPIF))); //******************** Opcode + tamanho dos dados************************ //aqui vou sempre receber 1 byte de dados, embora é possivel enviar mais // escreve bytes mais significativo no buffer spi SPDR = 0X00; // espera finalizar a transmissão while(!(SPSR & (1<<SPIF))); //escreve os bytes menos significativo no buffer spi SPDR = 0X01;//seta para receber apenas 1 byte // espera finalizar a transmissão while(!(SPSR & (1<<SPIF))); // envia um valor qualquer para ler os dados(pois isto liga o sinal de clock do registrado SPI) SPDR = 0x00; // espera finalizar a transmissão while(!(SPSR & (1<<SPIF))); // finaliza comunicação. SPI_PORT |= (1<<SPI_SS); return(SPDR);//retorna o valor lido do W5200 } ////////////////////////inicializa ethernet ////////////////////////////////// void W5200_Inicializa(void) { unsigned char porta0[] = {0x13,0X88};// ex 5000 = 0X1388 -> 0X13 +0X88 //porta 5000 unsigned char porta1[] = {0x00,0X50};// ex 0X0050 -> 0X00 +0X50 //porta 80 // esse mac é do AA0000 dezembro obsoleto unsigned char mac_addr[] = {0xAA,0x00,0x00,0xFF,0xFF,0x88};//MAC usado pelo microcontrolador(para teste) //dois dispositivos na mesma rede não pode ter o mesmo mac, coloquei o mais alto como padrão //aqui usei o ip para alterar o mac assim como em cada conexão não pode haver o mesmo ip ,tambem não haverá o mesmo mac unsigned char ip_addr[] = {192,168,50,141};//endereço de ip do servidor(valor para teste,do microcontrolador) unsigned char sub_mask[] = {255,255,255,0};//sem mascara mascara de sub_rede unsigned char gtw_addr[] = {192,168,50,254};//enderreço de ip do gateway cliente (valor para teste,do pc) //este ip não é necessariamente o do pc mas deve estar nesta faixa //unsigned char ip_dipr[] = {192,168,0,5}; temp[0] = 0X80; spi_escreve(MR, temp,1); // MR = 0b10000000; isso inicicializa os registradores internos automaticamente _delay_ms(1); temp[0] = 0X03;//numero de retransmissão spi_escreve(RCR,temp,1); // desabilita todas as interrupções do W5200 _delay_ms(1); temp[0] = 0X00; spi_escreve(S0_IMR,temp,1); // desabilita todas as interrupções do W5200 para o socket0 _delay_ms(1); spi_escreve(S1_IMR,temp,1); // desabilita todas as interrupções do W5200 para o socket1 _delay_ms(1); temp[0] = 0X07; temp[1] = 0XD0;//timeouto para 200ms(por padrão é 100us) spi_escreve(RTR,temp,2); // desabilita todas as interrupções do W5200 _delay_ms(1); //configura porta de comunicação para acesso remoto no socket0 spi_escreve(S0_PORT , porta0,2); _delay_ms(1); spi_escreve(S0_DPORT , porta0,2); //configura porta de comunicação para acesso remoto no socket1 spi_escreve(S1_PORT , porta1,2); _delay_ms(1); spi_escreve(S1_DPORT , porta1,2); temp[0] = MR_TCP;//conf. para TCP spi_escreve(S0_MR,temp,1); // configura o registrador de modo(MR) do socket0 _delay_ms(1); spi_escreve(S1_MR,temp,1); // configura o registrador de modo(MR) do socket1 _delay_ms(1); // configura o MAC de destino vou deixar o mesmo spi_escreve(S0_DHAR , mac_addr,6); _delay_ms(1); spi_escreve(S1_DHAR , mac_addr,6); _delay_ms(1); // configura o MAC (SHAR): 0x0009 à 0x000E spi_escreve(SHAR ,mac_addr,6); _delay_ms(1); // endereço de IP de acesso remoto do socket0 será sempre 1 na ultima casa // spi_escreve(S0_DIPR,ip_dipr,4); spi_escreve(S0_DIPR,ip_addr,4); _delay_ms(1); // endereço de IP de acesso remoto do socket0 será sempre 1 na ultima casa //spi_escreve(S1_DIPR,ip_dipr,4); spi_escreve(S1_DIPR,ip_addr,4); _delay_ms(1); //configura gateway do cliente spi_escreve(GAR ,gtw_addr,4); _delay_ms(1); // mascara de sub rede (SUBR): 0x0005 à 0x0008 spi_escreve(SUBR ,sub_mask,4); _delay_ms(1); // endereço de IP (SIPR): 0x000F à 0x0012 spi_escreve(SIPR,ip_addr,4); _delay_ms(1); // configura o tamanho do buffer de memoria de escrita e leitura temp[0] = NET_MEMORIA; spi_escreve(RMSR0,temp,1);//configura para socket0 4K de memoria de leitura(no W5200 tem 8 socket mas vamos usar somente o socket0 e o socket1) _delay_ms(1); spi_escreve(TMSR0,temp,1);//configura para socket0 4K de memoria de transmissao(no W5200 tem 8 socket mas vamos usar somente o socket0 e o socket1) _delay_ms(1); spi_escreve(RMSR1,temp,1);//configura para socket1 4K de memoria de leitura _delay_ms(1); spi_escreve(TMSR1,temp,1);//configura para socket1 4K de memoria de transmissao _delay_ms(1); } //////////////////////////////////fecha socket /////////////////////// void fechar_socket(uint8_t socket) { if (socket == 0) { temp[0] = CR_CLOSE; spi_escreve(S0_CR,temp,1); // espera que S0_CR seja zerado(finalizado) while(spi_ler(S0_CR)); } if (socket == 1) { temp[0] = CR_CLOSE; spi_escreve(S1_CR,temp,1); // espera que S0_CR seja zerado(finalizado) while(spi_ler(S1_CR)); } } //////////////////////////////////fecha conexão////////////////////////// void desconectar(uint8_t socket) { if (socket == 0) { temp[0] = CR_DISCON; spi_escreve(S0_CR,temp,1); // espera desconexão. while(spi_ler(S0_CR)); } if (socket == 1) { temp[0] = CR_DISCON; spi_escreve(S1_CR,temp,1); // espera desconexão. while(spi_ler(S1_CR)); } } ////////////////////////////////conecta pelo modo servidor//////////////////// uint8_t conex_servidor(uint8_t socket) { uint8_t retval=0; if (socket == 0) { if (spi_ler(S0_SR) == SOCK_CLOSED) // verificando se o socket 0 está fechado. { fechar_socket(socket); } // abrindo o Socket 0 temp[0]=CR_OPEN; spi_escreve(S0_CR,temp,1); // abre socket while(spi_ler(S0_CR)); //espera abrir if (spi_ler(S0_SR) == SOCK_INIT)//checa estado inicial retval=1; else fechar_socket(socket); } if (socket == 1) { if (spi_ler(S1_SR) == SOCK_CLOSED) // verificando se o socket 1 está fechado. { fechar_socket(socket); } // abrindo o Socket 1 temp[0]=CR_OPEN; spi_escreve(S1_CR,temp,1); // abre socket while(spi_ler(S1_CR)); //espera abrir if (spi_ler(S1_SR) == SOCK_INIT)//checa estado inicial retval=1; else fechar_socket(socket); } return retval; } /////////////////////////////"escuta" a rede///////////////////////////////// uint8_t escutar_rede(uint8_t socket) { uint8_t retval = 0; if (socket == 0) { if (spi_ler(S0_SR) == SOCK_INIT) { temp[0]=CR_LISTEN; spi_escreve(S0_CR,temp,1);//envia comando para escutar a rede while(spi_ler(S0_CR)); // espera terninar processo de escuta if (spi_ler(S0_SR) == SOCK_LISTEN) //verifica status de escuta retval=1; else fechar_socket(socket); } } if (socket == 1) { if (spi_ler(S1_SR) == SOCK_INIT) { temp[0]=CR_LISTEN; spi_escreve(S1_CR,temp,1);//envia comando para escutar a rede while(spi_ler(S1_CR)); // espera terninar processo de escuta if (spi_ler(S1_SR) == SOCK_LISTEN) //verifica status de escuta retval=1; else fechar_socket(socket); } } return retval; } ////////////////////////////envia pacote////////////////////////////////////(falta adaptar) uint16_t envia_pacote(unsigned char *frase,uint16_t buffer_tamanho,uint8_t socket) { unsigned int ponteiro,ende_temp,ende_real,tx_tamanho,timeout; if(socket == 0) { if (buffer_tamanho <= 0 )return 0;//verifica se tem espaço livre para transmitir tx_tamanho=spi_ler(SO_TX_FSR); tx_tamanho=(((tx_tamanho & 0x00FF) << 8 ) + spi_ler(SO_TX_FSR + 1));//calcula tamanho do buffer de transmissão. timeout=0; while (tx_tamanho < buffer_tamanho) { _delay_us(500);//0.5ms tx_tamanho= spi_ler(SO_TX_FSR); tx_tamanho=(((tx_tamanho & 0x00FF) << 8 ) + spi_ler(SO_TX_FSR + 1)); // Timeout para aproximadamente 5ms if (timeout++ > 10) { // desconecta socket 0 pois não há espaço livre após 10ms desconectar(0); return 0; } } tx_tamanho=0; ponteiro = spi_ler(S0_TX_WR);//lê o ponteiro de escrita. ende_temp = (((ponteiro & 0x00FF) << 8 ) + spi_ler(S0_TX_WR + 1)); while(buffer_tamanho>0) { buffer_tamanho--; // calcula o endereço real do buffer de transmissão. ende_real = TXBUFADDR0 + (ende_temp & TX_BUF_MASK); // copia pacote para W5200(TX_buffer) temp[0] = frase[tx_tamanho]; spi_escreve(ende_real,temp,1); ende_temp++; tx_tamanho++; } // incrementa valor de S0_TX_WR , então este será o ponto da proxima transmissão temp[0]=( ende_temp & 0xFF00) >> 8; temp[1]= ende_temp & 0x00FF; spi_escreve(S0_TX_WR,temp,2); // agora envia o comando de enviar dados para rede. temp[0] = CR_SEND; spi_escreve(S0_CR,temp,1); // espera terminar o envio while(spi_ler(S0_CR)); } if(socket == 1) { if (buffer_tamanho <= 0 )return 0;//verifica se tem espaço livre para transmitir tx_tamanho=spi_ler(S1_TX_FSR); tx_tamanho=(((tx_tamanho & 0x00FF) << 8 ) + spi_ler(S1_TX_FSR + 1));//calcula tamanho do buffer de transmissão. timeout=0; while (tx_tamanho < buffer_tamanho) { _delay_us(500);//0.5ms tx_tamanho= spi_ler(S1_TX_FSR); tx_tamanho=(((tx_tamanho & 0x00FF) << 8 ) + spi_ler(S1_TX_FSR + 1)); // Timeout para aproximadamente 5ms if (timeout++ > 10) { // desconecta socket 0 pois não há espaço livre após 10ms desconectar(1); return 0; } } tx_tamanho=0; ponteiro = spi_ler(S1_TX_WR);//lê o ponteiro de escrita. ende_temp = (((ponteiro & 0x00FF) << 8 ) + spi_ler(S1_TX_WR + 1)); while(buffer_tamanho>0) { buffer_tamanho--; // calcula o endereço real do buffer de transmissão. ende_real = TXBUFADDR1 + (ende_temp & TX_BUF_MASK); // copia pacote para W5200(TX_buffer) temp[0] = frase[tx_tamanho]; spi_escreve(ende_real,temp,1); ende_temp++; tx_tamanho++; } // incrementa valor de S1_TX_WR , então este será o ponto da proxima transmissão temp[0]=( ende_temp & 0xFF00) >> 8; temp[1]= ende_temp & 0x00FF; spi_escreve(S1_TX_WR,temp,2); // agora envia o comando de enviar dados para rede. temp[0] = CR_SEND; spi_escreve(S1_CR,temp,1); // espera terminar o envio while(spi_ler(S1_CR)); } return 1; } /////////////////////////////////recebe pacote////////////////////////////////////////// void recebe_pacote(uint8_t *pacote, uint8_t socket) { unsigned int conta=0,buffer_tamanho = MAX_BUF-2; char FIM[9]={'H','T','T','P','/','1','.','1'}; unsigned int ponteiro,ende_temp,ende_real; if(socket == 0) { ponteiro = spi_ler(S0_RX_RD);//pega localização do dado recebido(tamanho) ende_temp = (((ponteiro & 0x00FF) << 8 ) + spi_ler(S0_RX_RD + 1));////pega localização do dado recebido por ser 16 bits "ponteiro" deve ser descolado while((buffer_tamanho) && (conta<8)) { buffer_tamanho--; ende_real=RXBUFADDR0 + (ende_temp & RX_BUF_MASK);//endereço inicial de leitura + endereço dos dados recebidos *pacote = spi_ler(ende_real); //put_serial(*pacote); if(FIM[conta] == spi_ler(ende_real)) { conta++; }else { conta=0; } ende_temp++; pacote++; } *pacote='\0'; // String de fim de pacote // incrementa S0_RX_RD ,este será o ponto da proxima recepção temp[0]=(ende_temp & 0xFF00) >> 8; temp[1]= ende_temp & 0x00FF; spi_escreve(S0_RX_RD,temp,2); //envia comando para leitura temp[0]=CR_RECV; spi_escreve(S0_CR,temp,1); _delay_us(5); // espera terminar leitura. } if(socket == 1) { ponteiro = spi_ler(S1_RX_RD);//pega localização do dado recebido(tamanho) ende_temp = (((ponteiro & 0x00FF) << 8 ) + spi_ler(S1_RX_RD + 1));////pega localização do dado recebido por ser 16 bits "ponteiro" deve ser descolado while((buffer_tamanho) && (conta<8)) { buffer_tamanho--; ende_real=RXBUFADDR1 + (ende_temp & RX_BUF_MASK);//endereço inicial de leitura + endereço dos dados recebidos *pacote = spi_ler(ende_real); //put_serial(*pacote); if(FIM[conta] == spi_ler(ende_real)) { conta++; }else { conta=0; } ende_temp++; pacote++; } *pacote='\0'; // String de fim de pacote // incrementa S0_RX_RD ,este será o ponto da proxima recepção temp[0]=(ende_temp & 0xFF00) >> 8; temp[1]= ende_temp & 0x00FF; spi_escreve(S1_RX_RD,temp,2); //envia comando para leitura temp[0]=CR_RECV; spi_escreve(S1_CR,temp,1); _delay_us(5); // espera terminar leitura. } } /////////////////////////////////////////////////////////////////////// uint16_t tamanho_recepcao(uint8_t socket) { uint16_t retorno; if(socket == 0) { retorno = (((spi_ler(S0_RX_RSR) & 0x00FF) << 8 ) + spi_ler(S0_RX_RSR + 1)); // } if(socket == 1) { retorno = (((spi_ler(S1_RX_RSR) & 0x00FF) << 8 ) + spi_ler(S1_RX_RSR + 1)); // } return(retorno); } //////////////////////////////////////////////////////////////////////// int string_index(char *str_de_teste,char *str_compara)//procura posição de uma string { uint16_t i,str_tamanho; str_tamanho=strlen(str_compara);// pega tamanho da string for(i=0;*(str_de_teste+i); i++)//percorre o ponteiro { if (strncmp(str_de_teste+i,str_compara,str_tamanho) == 0)//compara com str_compara return i; } return -1; } int envia_pagina(uint8_t socket) { int flag=0; // criando pagina HTTP de resposta strcpy_P((char *)buf,PSTR("HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n")); strcat_P((char *)buf,PSTR("<html><body><span style=\"color:#0000A0\">\r\n")); strcat_P((char *)buf,PSTR("<h1>PROGRAMA DE TESTE</h1>\r\n")); if(socket == 0) { strcat_P((char *)buf,PSTR("<h1>No socket 0 </h1>\r\n")); } if(socket == 1) { strcat_P((char *)buf,PSTR("<h1>No socket 1 </h1>\r\n")); } strcat_P((char *)buf,PSTR("<h2>MICROCONTROLADORES-C</h2>\r\n")); strcat_P((char *)buf,PSTR("<p><form method=\"GET\">\r\n"));//POST // cria resposta do botao HTTP strcat_P((char *)buf,PSTR("<p><input type=\"radio\" name=\"Bot\" value=\"0\" ")); strcat((char *)buf,radiostat0); strcat_P((char *)buf,PSTR(">Desligar led. \r\n")); strcat_P((char *)buf,PSTR("<br><input type=\"radio\" name=\"Bot\" value=\"1\" ")); strcat((char *)buf,radiostat1); strcat_P((char *)buf,PSTR(">Ligar led. \r\n")); strcat_P((char *)buf,PSTR("</strong><p>\r\n")); strcat_P((char *)buf,PSTR(" \r\n <input type=\"submit\" value=\"Enviar\"> \r\n")); strcat_P((char *)buf,PSTR("</form></span></body></html>\r\n"));//finaliza pagina // // enviando pagina HTTP de resposta do botao if (envia_pacote(buf,strlen((char *)buf),socket) <= 0)//socket 0 ,envia o vetor buf,coloca o tamanho do vetor flag=1; return(flag); } ////////////////////função principal///////////////////////////////////// int main(void) { //////////////////inicializa port D ///////////////////////////////////////////////////////////////////// DDRD = 0xFE; // Seta PORTD como saida exceto a entrada serial PORTD = 0x00; DIDR0 = 0X00;////desabilita entrada analogico(reduz consumo).evita problemas quando esse pino é usado como saida DDRB = 0x2F;//configura port B inicializa_spi(); //comunicação spi rsize = 0; liga_pino(PORTB,PB1);//led desliga_pino(PORTB,PB0);///// //reseta o chip de ethernet - para garantir uma conexão segura _delay_ms(10);//tempo de reset liga_pino(PORTB,PB0); _delay_ms(150);//nessecessario para o modulo se preparar W5200_Inicializa(); //ethernet /////////////////////////////////// sei(); desliga_pino(PORTB,PB1);//led /////////////////////////////////////////////////////// for(;;) { sockstat=spi_ler(S0_SR); switch(sockstat) { case SOCK_CLOSED: ///socket fechado. if ( conex_servidor(0) > 0) {// escuta Socket 0 if (escutar_rede(0) <= 0)//socket 0 _delay_ms(1); }break; case SOCK_ESTABLISHED://conectado { // pega o tamanho do pacote recebido do cliente rsize=((spi_ler(S0_RX_RSR) & 0x00FF) << 8 ) + spi_ler(S0_RX_RSR + 1);//pega tamanho dos dados recebido if (rsize > 0)//isso indica que o pacote é maior que zero { // lê o pacote recebido recebe_pacote(buf,0); // Check the Request Header get_pos=string_index((char *)buf,"GET /");//procura pela posição da string "GET /" if (get_pos >= 0 ) { // ckeca botão do codigo html if (string_index((char *)buf,"Bot=0") > 0)//procura pela posição da string "radio=0" { desliga_pino(PORTB,PB1);//led strcpy_P(radiostat0,PSTR("checked")); strcpy(radiostat1,""); } if (string_index((char *)buf,"Bot=1") > 0)//procura pela posição da string "radio=1" { liga_pino(PORTB,PB1);//led strcpy(radiostat0,""); strcpy_P(radiostat1,PSTR("checked")); } if(envia_pagina(0)==1)//se falhar sai da conexão break; // atualiza estado dos botoes }//fim do getpos desconectar(0);// desconecta socket 0 } else { _delay_us(5); //perde tempo para espera resposta } }break; case SOCK_FIN_WAIT: case SOCK_CLOSING: case SOCK_TIME_WAIT: case SOCK_CLOSE_WAIT: case SOCK_LAST_ACK: fechar_socket(0);// força o fechamento do socket 0 break; }//chave do switch ///////////checa socket 1 /////////////////////////////////////////////////////////////////////////////////// sockstat=spi_ler(S1_SR); switch(sockstat) { case SOCK_CLOSED: ///socket fechado. if ( conex_servidor(1) > 0) {// escuta Socket 0 if (escutar_rede(1) <= 0)//socket 0 _delay_ms(1); }break; case SOCK_ESTABLISHED://conectado { // pega o tamanho do pacote recebido do cliente rsize=((spi_ler(S1_RX_RSR) & 0x00FF) << 8 ) + spi_ler(S1_RX_RSR + 1);//pega tamanho dos dados recebido if (rsize > 0)//isso indica que o pacote é maior que zero { // lê o pacote recebido recebe_pacote(buf,1); // Check the Request Header get_pos=string_index((char *)buf,"GET /");//procura pela posição da string "GET /" if (get_pos >= 0 ) { // ckeca botão do codigo html if (string_index((char *)buf,"Bot=0") > 0)//procura pela posição da string "radio=0" { desliga_pino(PORTB,PB1);//led strcpy_P(radiostat0,PSTR("checked")); strcpy(radiostat1,""); } if (string_index((char *)buf,"Bot=1") > 0)//procura pela posição da string "radio=1" { liga_pino(PORTB,PB1);//led strcpy(radiostat0,""); strcpy_P(radiostat1,PSTR("checked")); } if(envia_pagina(1)==1)//se falhar sai da conexão break; // atualiza estado dos botoes }//fim do getpos desconectar(1);// desconecta socket 1 } else { _delay_us(5); //perde tempo para espera resposta } }break; case SOCK_FIN_WAIT: case SOCK_CLOSING: case SOCK_TIME_WAIT: case SOCK_CLOSE_WAIT: case SOCK_LAST_ACK: fechar_socket(1);// força o fechamento do socket 1 break; }//chave do switch }//chave do laço infinito (for) }//chave de main
Nenhum comentário :
Postar um comentário
olá,digite aqui seu comentário!