Ir ao conteúdo

Modulo ENC28J60 - Como usar PIC na Ethernet?


chacalgbi

Posts recomendados

Postado

Vou testar aqui e já digo os resultados!

O código não funciona. Nem os LEds da configuração inicial não piscam.

você mandou eu colocar um cristal de 4Mhz, mas no código tá #use delay(clock=48000000) é assim mesmo?

Precisa ativar o MCLR?

Não entendi a parte dos set_tris como vou saber quais pinos do ENC28J60 são entrada e saida?

O código tá bem parecido com o do Matheus, nele não vi nenhuma parte que o microcontrolador pinga algum IP.

Fiz os testes, coloquei o seu código no cabeçalho e nas configurações do Matheus. Deu certo, mas acho que você não entendeu o que eu queria. Dar o ping no ENC28J60 eu já fazia, e também abria página nele, o que eu não consigo é fazer com que o PIC dê um PING em um outro IP e caso consiga, incremente uma variável. É isso que preciso fazer.

Postado
você mandou eu colocar um cristal de 4Mhz, mas no código tá #use delay(clock=48000000) é assim mesmo?

Precisa ativar o MCLR?

Sim...

O código tá bem parecido com o do Matheus, nele não vi nenhuma parte que o microcontrolador pinga algum IP.

Esse código não é meu nem dele,foi retirado do link abaixo:

-> Código original e esquema<-

...o que eu não consigo é fazer com que o PIC dê um PING em um outro IP e caso consiga, incremente uma variável. É isso que preciso fazer.

Realmente isso não da para entender,ja que ping é um comando genérico.

Postado
Sim...

Esse código não é meu nem dele,foi retirado do link abaixo:

-> Código original e esquema<-

Realmente isso não da para entender,ja que ping é um comando genérico.

Ping ou latência como podemos chamar, é um utilitário que usa o protocolo ICMP para testar a conectividade entre equipamentos. Seu funcionamento consiste no envio de pacotes para o equipamento de destino e na "escuta" das respostas. Se o equipamento de destino estiver ativo, uma "resposta" (o "pong", uma analogia ao famoso jogo de ping-pong) é devolvida ao computador solicitante.

Quero que meu microcontrolador conectado a rede pelo módulo ENC28J60 faça o comando descrito acima para testar a conectividade com um determinado equipamento na mesma rede (PC, Notebook, Roteador, etc..)Tudo que tem um IP que pode responder ao protocolo de teste ICMP Internet Control Message Protocol vulgarmente chamado de PING. Entendeu?

E eu sei que o PIC+ENC28J60 é capaz de fazer isso, nó não sei como.

Olha esse trecho da ajuda do TCPIP Stack v5.42.04

bo59.jpg

E olha esse arquivo ICMP.c


/*********************************************************************
*
* Internet Control Message Protocol (ICMP) Server
* Module for Microchip TCP/IP Stack
* -Provides "ping" diagnostics
* -Reference: RFC 792
*
*********************************************************************
* FileName: ICMP.c
* Dependencies: IP, ARP
* Processor: PIC18, PIC24F, PIC24H, dsPIC30F, dsPIC33F, PIC32
* Compiler: Microchip C32 v1.05 or higher
* Microchip C30 v3.12 or higher
* Microchip C18 v3.30 or higher
* HI-TECH PICC-18 PRO 9.63PL2 or higher
* Company: Microchip Technology, Inc.
*
* Software License Agreement
*
* Copyright (C) 2002-2009 Microchip Technology Inc. All rights
* reserved.
*
* Microchip licenses to you the right to use, modify, copy, and
* distribute:
* (i) the Software when embedded on a Microchip microcontroller or
* digital signal controller product ("Device") which is
* integrated into Licensee's product; or
* (ii) ONLY the Software driver source files ENC28J60.c, ENC28J60.h,
* ENCX24J600.c and ENCX24J600.h ported to a non-Microchip device
* used in conjunction with a Microchip ethernet controller for
* the sole purpose of interfacing with the ethernet controller.
*
* You should refer to the license agreement accompanying this
* Software for additional information regarding your rights and
* obligations.
*
* THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT
* WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
* LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* MICROCHIP BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
* PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
* BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
* THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
* SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
* (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
*
*
* Author Date Comment
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Howard Schlunder 03/16/07 Original
********************************************************************/
#define __ICMP_C

#include "TCPIP Stack/TCPIP.h"

#if defined(STACK_USE_ICMP_SERVER) || defined(STACK_USE_ICMP_CLIENT)

#if defined(STACK_USE_ICMP_CLIENT)

// ICMP Timeout Value
#define ICMP_TIMEOUT (4ul*TICK_SECOND)

// ICMP Packet Structure
typedef struct
{
BYTE vType;
BYTE vCode;
WORD wChecksum;
WORD wIdentifier;
WORD wSequenceNumber;
WORD wData;
} ICMP_PACKET;

// ICMP Sequence Number
static WORD wICMPSequenceNumber;
// ICMP tick timer variable
static DWORD ICMPTimer;

// ICMP Flag structure
static struct
{
unsigned char bICMPInUse:1; // Indicates that the ICMP Client is in use
unsigned char bReplyValid:1; // Indicates that a correct Ping response to one of our pings was received
unsigned char bRemoteHostIsROM:1; // Indicates that a remote host name was passed as a ROM pointer argument
} ICMPFlags = {0x00};

// ICMP Static Variables
static union
{
union
{
ROM BYTE *szROM;
BYTE *szRAM;
} RemoteHost;
NODE_INFO ICMPRemote;
} StaticVars;

// ICMP State Machine Enumeration
static enum
{
SM_IDLE = 0,
SM_DNS_SEND_QUERY,
SM_DNS_GET_RESPONSE,
SM_ARP_SEND_QUERY,
SM_ARP_GET_RESPONSE,
SM_ICMP_SEND_ECHO_REQUEST,
SM_ICMP_GET_ECHO_RESPONSE
} ICMPState;

#endif

/*********************************************************************
* Function: void ICMPProcess(void)
*
* PreCondition: MAC buffer contains ICMP type packet.
*
* Input: *remote: Pointer to a NODE_INFO structure of the
* ping requester
* len: Count of how many bytes the ping header and
* payload are in this IP packet
*
* Output: Generates an echo reply, if requested
* Validates and sets ICMPFlags.bReplyValid if a
* correct ping response to one of ours is received.
*
* Side Effects: None
*
* Overview: None
*
* Note: None
********************************************************************/
void ICMPProcess(NODE_INFO *remote, WORD len)
{
DWORD_VAL dwVal;

// Obtain the ICMP header Type, Code, and Checksum fields
MACGetArray((BYTE*)&dwVal, sizeof(dwVal));

// See if this is an ICMP echo (ping) request
if(dwVal.w[0] == 0x0008u)
{
// Validate the checksum using the Microchip MAC's DMA module
// The checksum data includes the precomputed checksum in the
// header, so a valid packet will always have a checksum of
// 0x0000 if the packet is not disturbed.
if(MACCalcRxChecksum(0+sizeof(IP_HEADER), len))
return;

// Calculate new Type, Code, and Checksum values
dwVal.v[0] = 0x00; // Type: 0 (ICMP echo/ping reply)
dwVal.v[2] += 8; // Subtract 0x0800 from the checksum
if(dwVal.v[2] < 8u)
{
dwVal.v[3]++;
if(dwVal.v[3] == 0u)
dwVal.v[2]++;
}

// Wait for TX hardware to become available (finish transmitting
// any previous packet)
while(!IPIsTxReady());

// Position the write pointer for the next IPPutHeader operation
// NOTE: do not put this before the IPIsTxReady() call for WF compatbility
MACSetWritePtr(BASE_TX_ADDR + sizeof(ETHER_HEADER));

// Create IP header in TX memory
IPPutHeader(remote, IP_PROT_ICMP, len);

// Copy ICMP response into the TX memory
MACPutArray((BYTE*)&dwVal, sizeof(dwVal));
MACMemCopyAsync(-1, -1, len-4);
while(!MACIsMemCopyDone());

// Transmit the echo reply packet
MACFlush();
}
#if defined(STACK_USE_ICMP_CLIENT)
else if(dwVal.w[0] == 0x0000u) // See if this an ICMP Echo reply to our request
{
// Get the sequence number and identifier fields
MACGetArray((BYTE*)&dwVal, sizeof(dwVal));

// See if the identifier matches the one we sent
if(dwVal.w[0] != 0xEFBE)
return;

if(dwVal.w[1] != wICMPSequenceNumber)
return;

// Validate the ICMP checksum field
IPSetRxBuffer(0);
if(CalcIPBufferChecksum(sizeof(ICMP_PACKET))) // Two bytes of payload were sent in the echo request
return;

// Flag that we received the response and stop the timer ticking
ICMPFlags.bReplyValid = 1;
ICMPTimer = TickGet() - ICMPTimer;
}
#endif
}

#if defined(STACK_USE_ICMP_CLIENT)
/*********************************************************************
* Function: void ICMPSendPing(DWORD dwRemoteIP)
*
* PreCondition: ICMPBeginUsage() returned TRUE
*
* Input: dwRemoteIP: IP Address to ping. Must be stored
* big endian. Ex. 192.168.0.1 should be
* passed as 0x0100A8C0.
*
* Output: Begins the process of transmitting an ICMP echo
* request. This normally involves an ARP
* resolution procedure first.
*
* Side Effects: None
*
* Overview: None
*
* Note: None
********************************************************************/
void ICMPSendPing(DWORD dwRemoteIP)
{
ICMPFlags.bReplyValid = 0;
ICMPTimer = TickGet();
StaticVars.ICMPRemote.IPAddr.Val = dwRemoteIP;
ICMPState = SM_ARP_SEND_QUERY;
}

#if defined(STACK_USE_DNS)
/*********************************************************************
* Function: void ICMPSendPingToHost (BYTE * szRemoteHost)
*
* PreCondition: ICMPBeginUsage() returned TRUE
*
* Input: szRemoteHost: Host name to ping. Must be stored
* in RAM if being called by PIC18.
* Ex. www.microchip.com
*
* Output: Begins the process of transmitting an ICMP echo
* request. This normally involves an ARP
* resolution procedure first.
*
* Side Effects: None
*
* Overview: None
*
* Note: None
********************************************************************/
void ICMPSendPingToHost(BYTE * szRemoteHost)
{
ICMPFlags.bReplyValid = 0;
ICMPTimer = TickGet();
ICMPFlags.bRemoteHostIsROM = 0;
StaticVars.RemoteHost.szRAM = szRemoteHost;
ICMPState = SM_DNS_SEND_QUERY;
}

#if defined(__18CXX)

/*********************************************************************
* Function: void ICMPSendPingToHostROM (ROM BYTE * szRemoteHost)
*
* PreCondition: ICMPBeginUsage() returned TRUE
*
* Input: szRemoteHost: Host name to ping. Must be stored
* in ROM. Should only be called by PIC18.
* Ex. www.microchip.com
*
* Output: None
*
* Side Effects: None
*
* Overview: Begins the process of transmitting an ICMP echo
* request. This normally involves an ARP
* resolution procedure first.
*
* Note: None
********************************************************************/
void ICMPSendPingToHostROM(ROM BYTE * szRemoteHost)
{
ICMPFlags.bReplyValid = 0;
ICMPTimer = TickGet();
ICMPFlags.bRemoteHostIsROM = 1;
StaticVars.RemoteHost.szROM = szRemoteHost;
ICMPState = SM_DNS_SEND_QUERY;
}

#endif
#endif

/*********************************************************************
* Function: LONG ICMPGetReply(void)
*
* PreCondition: ICMPBeginUsage() returned TRUE and ICMPSendPing()
* was called
*
* Input: None
*
* Output: -3: Could not resolve hostname (DNS timeout or
* hostname invalid)
* -2: No response received yet
* -1: Operation timed out (longer than ICMP_TIMEOUT)
* has elapsed.
* >=0: Number of TICKs that elapsed between
* initial ICMP transmission and reception of
* a valid echo.
*
* Side Effects: None
*
* Overview: None
*
* Note: None
********************************************************************/
LONG ICMPGetReply(void)
{
ICMP_PACKET ICMPPacket;

switch(ICMPState)
{
#if defined(STACK_USE_DNS)
case SM_DNS_SEND_QUERY:
// Obtain DNS module ownership
if(!DNSBeginUsage())
break;

// Send DNS query
if(ICMPFlags.bRemoteHostIsROM)
DNSResolveROM(StaticVars.RemoteHost.szROM, DNS_TYPE_A);
else
DNSResolve(StaticVars.RemoteHost.szRAM, DNS_TYPE_A);

ICMPState = SM_DNS_GET_RESPONSE;
break;

case SM_DNS_GET_RESPONSE:
// See if DNS is done, and if so, get the remote IP address
if(!DNSIsResolved(&StaticVars.ICMPRemote.IPAddr))
break;

// Free the DNS module
DNSEndUsage();

// Return error code if the DNS query failed
if(StaticVars.ICMPRemote.IPAddr.Val == 0x00000000ul)
{
ICMPState = SM_IDLE;
return -3;
}

ICMPState = SM_ARP_SEND_QUERY;
// No break;
#endif

case SM_ARP_SEND_QUERY:
ARPResolve(&StaticVars.ICMPRemote.IPAddr);
ICMPState = SM_ARP_GET_RESPONSE;
break;

case SM_ARP_GET_RESPONSE:
// See if the ARP reponse was successfully received
if(!ARPIsResolved(&StaticVars.ICMPRemote.IPAddr, &StaticVars.ICMPRemote.MACAddr))
break;

ICMPState = SM_ICMP_SEND_ECHO_REQUEST;
// No break;

case SM_ICMP_SEND_ECHO_REQUEST:
if(!IPIsTxReady())
break;

// Set up the ping packet
ICMPPacket.vType = 0x08; // 0x08: Echo (ping) request
ICMPPacket.vCode = 0x00;
ICMPPacket.wChecksum = 0x0000;
ICMPPacket.wIdentifier = 0xEFBE;
wICMPSequenceNumber++;
ICMPPacket.wSequenceNumber = wICMPSequenceNumber;
ICMPPacket.wData = 0x2860;
ICMPPacket.wChecksum = CalcIPChecksum((BYTE*)&ICMPPacket, sizeof(ICMPPacket));

// Record the current time. This will be used as a basis for
// finding the echo response time, which exludes the ARP and DNS
// steps
ICMPTimer = TickGet();

// Position the write pointer for the next IPPutHeader operation
MACSetWritePtr(BASE_TX_ADDR + sizeof(ETHER_HEADER));

// Create IP header in TX memory
IPPutHeader(&StaticVars.ICMPRemote, IP_PROT_ICMP, sizeof(ICMPPacket));
MACPutArray((BYTE*)&ICMPPacket, sizeof(ICMPPacket));
MACFlush();

// Echo sent, advance state
ICMPState = SM_ICMP_GET_ECHO_RESPONSE;
break;

case SM_ICMP_GET_ECHO_RESPONSE:
// See if the echo was successfully received
if(ICMPFlags.bReplyValid)
return (LONG)ICMPTimer;

break;

// SM_IDLE or illegal/impossible state:
default:
return -1;
}

// See if the DNS/ARP/echo request timed out
if(TickGet() - ICMPTimer > ICMP_TIMEOUT)
{
// Free DNS module if we have it in use
#if defined(STACK_USE_DNS)
if(ICMPState == SM_DNS_GET_RESPONSE)
DNSEndUsage();
#endif

// Stop ICMP echo test and return error to caller
ICMPState = SM_IDLE;
return -1;
}

// Still working. No response to report yet.
return -2;
}


/*********************************************************************
* Function: BOOL ICMPBeginUsage(void)
*
* PreCondition: None
*
* Input: None
*
* Output: TRUE: You have successfully gained ownership of
* the ICMP client module and can now use the
* ICMPSendPing() and ICMPGetReply() functions.
* FALSE: Some other application is using the ICMP
* client module. Calling ICMPSendPing()
* will corrupt the other application's ping
* result.
*
* Side Effects: None
*
* Overview: Claims ownership of the ICMP module.
*
* Note: None
********************************************************************/
BOOL ICMPBeginUsage(void)
{
if(ICMPFlags.bICMPInUse)
return FALSE;

ICMPFlags.bICMPInUse = TRUE;
return TRUE;
}


/*********************************************************************
* Function: void ICMPEndUsage(void)
*
* PreCondition: ICMPBeginUsage() was called by you and it
* returned TRUE.
*
* Input: None
*
* Output: Your ownership of the ICMP module is released.
* You can no longer use ICMPSendPing().
*
* Side Effects: None
*
* Overview: Gives up ownership of the ICMP module.
*
* Note: None
********************************************************************/
void ICMPEndUsage(void)
{
ICMPFlags.bICMPInUse = FALSE;
}

#endif //#if defined(STACK_USE_ICMP_CLIENT)

#endif //#if defined(STACK_USE_ICMP_SERVER) || defined(STACK_USE_ICMP_CLIENT)

Postado

Veja,eu conheço o que voce citou mas não sei se o módulo junto com o PIC pode enviar um comando 'ping' e aguardar o retorno.

Eu sei que o módulo pode RESPONDER ao comando ping.

voce vai ter que pesquisar mesmo.

Postado
Veja,eu conheço o que voce citou mas não sei se o módulo junto com o PIC pode enviar um comando 'ping' e aguardar o retorno.

Eu sei que o módulo pode RESPONDER ao comando ping.

voce vai ter que pesquisar mesmo.

Não, ele envia sim. Li muita coisa nos últimos dias. Tem todos os comandos de envio e aguardo de resposta.

OLha esse código, tô trabalhando em cima dele


// ICMP Echo (Ping) example code
#if defined(STACK_USE_ICMP_CLIENT)
static void PingDemo(void)
{
static enum
{
SM_HOME = 0,
SM_GET_RESPONSE
} PingState = SM_HOME;
static TICK Timer;
SHORT ret;
IP_ADDR RemoteIP;

switch(PingState)
{
case SM_HOME:
// Enviar uma solicitação de ping se o usuário aperta button3
if(BUTTON3_IO == 0)
{
// Não pingar sempre: esperar pelo menos 1 segundo entre solicitações de ping
if((DWORD)(TickGet()-Timer) > 1u*TICK_SECOND)
{
// Obter a propriedade do módulo ICMP
if(ICMPBeginUsage())
{
Timer = TickGet();
PingState = SM_GET_RESPONSE;

// Enviar PING para 192.168.0.51
RemoteIP.v[0] = 192;
RemoteIP.v[1] = 168;
RemoteIP.v[2] = 0;
RemoteIP.v[3] = 51;
ICMPSendPing(RemoteIP.Val);
}
}
}
break;

case SM_GET_RESPONSE:
// Obter o status do módulo ICMP
ret = ICMPGetReply();
if(ret == -2)
{
// Não fazer nada: ainda à espera da resposta do PING
break;
}
else if(ret == -1)
{
// A solicitação expirou
#if defined(USE_LCD)
memcpypgm2ram((void*)&LCDText[16], (ROM void *)"Ping timed out", 15);
LCDUpdate();
#endif
PingState = SM_HOME;
}
else
{
// Eco recebido. Tempo decorrido é armazenado em ret
#if defined(USE_LCD)
memcpypgm2ram((void*)&LCDText[16], (ROM void *)"Reply: ", 7);
uitoa(ret, &LCDText[16+7]);
strcatpgm2ram((char*)&LCDText[16+7], (ROM char*)"ms");
LCDUpdate();
#endif
PingState = SM_HOME;
}

// Terminou com o módulo de ICMP, liberá-lo para outros aplicativos pode começar a usá-lo
ICMPEndUsage();
break;
}
}
#endif //#if defined(STACK_USE_ICMP_CLIENT)

Postado

Encontrei uma Biblioteca do TCP/IP da microchip modificada para o compilador CCS.

Biblioteca CCS TCP/IP microchip

Ela foi desenvolvida para as placas de teste vendidas pela CCS (ou que usavam o CCS como compilador). A CCS não disponibiliza para download, um cara que tinha essa placa postou no 4shared o stack tcp/ip modificado.

Mas todos os exemplos e modificações feitas foram feitas para os seguintes PICs:

18F4620

18F6722

18F67J60

Eu não consegui o que queria com o PIC18F4550, vou parar com esse projeto por uns dias. Comprei no ebay um PIC18F4620, quando chegar eu retomo os testes com essas bibliotecas próprias para esse PIC.

A paciência acabou...:confused::mad:

Se um dia consegui eu posto os resultados. (agora é uma questão de honra... rs)

Peço ao moderador que não feche o tópico, só vou aguardar o PIC chegar.

Adios!

  • 4 semanas depois...
  • Coordenador
Postado

Caso o autor do tópico necessite, o mesmo será reaberto, para isso deverá entrar em contato com a moderação solicitando o desbloqueio.

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!