You are on page 1of 11

1

Gua

POR NAVAISMO

Conectando un PIC a Ethernet 2 (M ETH-BOARD)

1
Introduccin.

odos tenemos las necesidad de experimentar con los diferentes tipos de comunicacin con nuestros PICs, hemos visto gratamente como podemos implementar comunicacin via USB, RF, con el Puerto serie de nuestra PC, es quizs por ello que me naci la cosquilla por comunicar esta vez el PIC con la PC va Ethernet..

Las herramientas que encontr para este fin fueron el PIC 18F4520, el ENC28J60 que es un controlador ethernet al que se accede va SPI y el compilador MIKROBASIC, este ultimo posee rutinas para establecer comunicacin con el ENC28J60 sin necesidad de tocar los registros del PIC ni del ENC28J60. Por ultimo usaremos Visual Basic para hacer nuestras aplicaciones. Esta es una gua que solo persigue el publicar mis experiencias y una manera sencilla de conectar un PIC a la PC a travs de un cable de red. No es nada profesional pero sirve para iniciarse en el tema.

El Hardware: M2ETH-BOARD.
El hardware que utilizaremos se divide en 2 partes. La primera es la interfaz de la placa ethernet la cual conecta el cable de RED con el ENC28J60: la M2ETH-BOARD y la segunda parte es el Hardware del PIC. La M2ETH-BOARD esta basada en el hardware que la misma hoja de datos del controlador propone:

By Navaismo

Pgina - 1 -

Como en la misma hoja de datos del ENC28J60 proponen hay que cuidar los valores de las resistencias, en mi caso uso las siguientes: 6 resistencias de 182 a 1%, son usadas para los LEDs del controlador y las salidas del SPI del controlador 1 resistencia de. 2.32K a 1% para el pin RBIAS del controlador 4 resistencias de 49.9 a 1% para las salidas del RJ45

Uno de los dispositivos mas difciles de conseguir es el conector RJ45 con los filtros integrados pero nada que mouser electronics no nos pueda resolver. El nmero de parte de mouser es el 673-J0012D21 y es tal como se ve en el esquemtico. Y por ultimo el Hardware del PIC, como se ve en la figura no se usa MCLR pero si ustedes lo necesitan lo pueden activar.

By Navaismo

Pgina - 2 -

El Software del Microcontrolador

Para programar el microcontrolador uso Mikrobasic como ya lo haba comentado, no pretendo explicar la librera si no dar una demostracin de ella. Para referirse a las libreras esta la ayuda del manual y el ejemplo que posee. La librera que vamos a usar es la SPI Ethernet Library esta librera nos ahorra mucho trabajo pues como deca anteriormente sabe donde estn los registros del ENC28J60 lo cual permite usar las subrutinas de manera simple. Esta librera nos sirve para PIC de ms de 4KB de ROM y con hardware SPI integrado por lo que no todos los PICs son compatibles. Para el uso de PICs de la familia 16F existen algunas limitaciones, es por ello que uso un PIC18.

Pingeando
Una vez que contamos con el Hardware armado necesitamos saber si nuestra placa responde y que manera mas sencilla de hacerlo si no con un PING, lo que equivale a un esta vivo. Para realizar el Ping usamos la subrutina Spi_Ethernet_DoPacket(), esta subrutina responde automticamente a solicitudes ARP e ICMP por lo que si todo marcha bien nuestro PIC responder automticamente. Para hacer esto haremos este sencillo Programa:
program ping nombre del programa include "eth_enc28j60" Librerias que usa el compilador include "eth_enc28j60_api" dim mymacaddr as byte [6] Variables para la MAC, IP, DNS, GW y Mascara de RED dim myipaddr as byte [4] dim gwipaddr as byte [4] dim dnsipaddr as byte [4] dim ipmask as byte [4] dim i as byte /// Estas 2 funciones son llamadas por la Rutina DoPacket por eso es necesario definirlas. ////// La funcnion USERTCP sirve para la recepcion de paquetes TCP como esto solo es un ping no nos interesa y la declaramos como 0 sub function Spi_Ethernet_UserTCP(dim byref remoteHost as byte[4],dim remotePort, localPort, reqLength as word) as word result=0 end sub ////// La funcnion USERUDP sirve para la recepcion de paquetes UDP como esto solo es un ping no nos interesa y la declaramos como 0 sub function Spi_Ethernet_UserUDP(dim byref remoteHost as byte[4], dim remotePort, destPort, reqLength as word) as word result=0 end sub main: Iniciamos el Programa adcon0=0 sin comparadores, sin ADC, Puerto A B y D como Salida adcon1=15 cmcon=7 trisa=0 porta=0 trisb=0 portb=0 trisd=0 portd=0 Direccion Fisica de nuestroPIC la MAC A3:12:45:B3:22:F1 mymacaddr[0]=0xA3 mymacaddr[1]=0x12 mymacaddr[2]=0x45 mymacaddr[3]=0xb3 mymacaddr[4]=0x22 mymacaddr[5]=0xf1 By Navaismo Pgina - 3 -

myipaddr[0]=192 myipaddr[1]=168 myipaddr[2]=1 myipaddr[3]=20 ipmask[0]=255 ipmask[1]=255 ipmask[2]=255 ipmask[3]=0 dnsipaddr[0]=192 dnsipaddr[1]=168 dnsipaddr[2]=1 dnsipaddr[3]=1 gwipaddr[0]=192 gwipaddr[1]=168 gwipaddr[2]=1 gwipaddr[3]=1

Direccion IP del PIC 192.168.1.20

Mascara del PIC

255.255.255.0

Direccion del DNS 192.168.1.1

Direccion del Gateway o Puerta de enlace 192.168.1.1

spi_init() Inicializamos el Hardware SPI del PIC spi_ethernet_init(portc,0,portc,1,mymacaddr,myipaddr,1) Ponemos RC0 como Reset, RC1 Como el CS, metemos la MAC y la IP spi_ethernet_confnetwork(ipmask,gwipaddr,dnsipaddr) Configuramos la RED del PIC for i=0 to 2 portd.7=0 delay_ms(500) portd.7=1 delay_ms(500) next i Hacemos un Blink en el PORTD.0 para saber que vive el PIC

tryping: Comenzamos el programa principal while trae Abrimos un bucle infinito spi_ethernet_dopacket() Llamamos la subrutina DoPacket la cual procesa los paquetes provenientes de la interfaz ethernet wend goto tryping Vamos a repetirlo. end.

Para grabar nuestro programa uso el WinPIC800 y la configuracin es la siguiente:

By Navaismo

Pgina - 4 -

Y el resultado es un PING contestado desde el PIC:

Jugando con el PORTD


Vamos a encender y apagar los Bits del PORTD usando el protocolo UDP, para ello necesitamos modificar el programa anterior; adems de usar Visual Basic para togglear el PORTD.

El cdigo del PIC


program ping nombre del programa ' modulo donde se implementa el codigo ' modulo usado por el compilador include "enc_m2eth" include "eth_enc28j60"

dim mymacaddr as byte [6] Variables para la MAC, IP, DNS, GW y Mascara de RED dim myipaddr as byte [4] dim gwipaddr as byte [4] dim dnsipaddr as byte [4] dim ipmask as byte [4] dim i as byte main: Iniciamos el Programa adcon0=0 adcon1=15 cmcon=7 trisa=0 porta=0 trisb=0 portb=0 trisd=0 portd=0 Direccion Fisica de nuestro PIC la MAC A3:12:45:B3:22:F1 mymacaddr[0]=0xA3 mymacaddr[1]=0x12 mymacaddr[2]=0x45 mymacaddr[3]=0xb3 mymacaddr[4]=0x22 mymacaddr[5]=0xf1 By Navaismo Pgina - 5 sin comparadores, sin ADC, Puerto A B y D como Salida

myipaddr[0]=192 myipaddr[1]=168 myipaddr[2]=1 myipaddr[3]=20 ipmask[0]=255 ipmask[1]=255 ipmask[2]=255 ipmask[3]=0 dnsipaddr[0]=192 dnsipaddr[1]=168 dnsipaddr[2]=1 dnsipaddr[3]=1 gwipaddr[0]=192 gwipaddr[1]=168 gwipaddr[2]=1 gwipaddr[3]=1

Direccion IP del PIC 192.168.1.20

Mascara del PIC

255.255.255.0

Direccion del DNS 192.168.1.1

Direccion del Gateway o Puerta de enlace 192.168.1.1

spi_init() Inicializamos el Hardware SPI del PIC spi_ethernet_init(portc,0,portc,1,mymacaddr,myipaddr,1) Ponemos RC0 como Reset, RC1 Como el CS, metemos la MAC y la IP spi_ethernet_confnetwork(ipmask,gwipaddr,dnsipaddr) Configuramos la RED del PIC for i=0 to 2 portd.7=0 delay_ms(500) portd.7=1 delay_ms(500) next i Hacemos un Blink en el PORTD.0 para saber que vive el PIC

tryping: Comenzamos el programa principal while trae Abrimos un bucle infinito spi_ethernet_dopacket() Llamamos la subrutina DoPacket la cual procesa los paquetes provenientes de la interfaz ethernet wend goto tryping Vamos a repetirlo. end.

Hasta este momento todo parece igual, pero hemos aadido el modulo enc_m2eth que es donde implementamos nuestro cdigo para hacer que nuestro PORTD responda, esta vez la funcin USERUDP no ser iguala a cero pues si queremos evaluar los paquetes que tengan este protocolo. Sin embargo la funcin USERTCP si ser igualada a cero pues no la necesitamos.

El cdigo del modulo enc_m2eth


module enc_m2eth nuestro modulo include "eth_enc28j60_api" ' Modulo del compilador

dim getRequest as byte[20] ' variables de uso general dyna as byte[30] txt as string[20] i as byte /////// No evaluamos paquetes TCP por lo que la funcion es 0 sub function Spi_Ethernet_UserTCP(dim byref remoteHost as byte[4], dim remotePort, localPort, reqLength as word) as word result=0 end sub '/////// ' Implementamos la recepcion de paquetes UDP reseteando siempre el resultado a 0 sub function Spi_Ethernet_UserUDP(dim byref remoteHost as byte[4], dim remotePort, destPort, reqLength as word) as word result = 0 ' reseteo de la funcion If destport = 200 then El puerto donde vamos a escuchar los paketes es el 200 cualquier peticon a otro no es evaluada. for i=0 to 3 ' captamos los bytes entrantes del buffer ethernet getRequest[i]=spi_ethernet_getbyte() 'captamos 3 esta ocasion debido al codigo de VB next i

By Navaismo

Pgina - 6 -

'//////////// RUTINA PARA ENCENDER BITS EN EL PORTD if getrequest[0]="R" then if getRequest[1]="D" then if getRequest[2]="O" then select case getRequest[3] case "0" PORTD.0=1 txt = "RD0 ENCENDIDO" case "1" PORTD.1=1 txt = "RD1 ENCENDIDO" case "2" PORTD.2=1 txt = "RD2 ENCENDIDO" case "3" PORTD.3=1 txt = "RD3 ENCENDIDO" case "4" PORTD.4=1 txt = "RD4 ENCENDIDO" case "5" PORTD.5=1 txt = "RD5 ENCENDIDO" case "6" PORTD.6=1 txt = "RD6 ENCENDIDO" case "7" PORTD.7=1 txt = "RD7 ENCENDIDO" end select cls lcd_out(1,1,txt) end if end if end if '/////////// RUTINA PARA APAGAR BITS EN EL PORTD if getrequest[0]="R" then if getRequest[1]="D" then if getRequest[2]="F" then select case getRequest[3] case "0" PORTD.0=0 txt = "RD0 APAGADO" case "1" PORTD.1=0 txt = "RD1 APAGADO" case "2" PORTD.2=0 txt = "RD2 APAGADO" case "3" PORTD.3=0 txt = "RD3 APAGADO" case "4" PORTD.4=0 txt = "RD4 APAGADO" case "5" PORTD.5=0 txt = "RD5 APAGADO" case "6" PORTD.6=0 txt = "RD6 APAGADO" case "7" PORTD.7=0 txt = "RD7 APAGADO" end select cls lcd_out(1,1,txt) end if end if end if result = 13 + reqLength ' el resultado es la longitud del texto a enviar mas lo que nos llega del buffer spi_ethernet_putbytes(@txt,13) ' Ponemos el mensaje en el buffer de transmision 'Aqui enviamos los paquetes (sacado de la libreria original) while(reqLength <> 0) Spi_Ethernet_putByte(Spi_Ethernet_getByte()) reqLength = reqLength - 1 wend end if end sub By Navaismo Pgina - 7 -

Prcticamente lo que hacemos es evaluar los paquetes que entran al puerto 200 UDP de la M2ETHBOARD. Filtrando la cadena enviada desde la PC. Y cuando es recibido automticamente se regresa la cadena con el Bit que se encendi o se apago.

El cdigo de Visual Basic.


Para poder manipular los bits del PIC va Ethernet necesitamos usar un programa, en este caso uso el Visual Basic debido a su facilidad por acceder a estos puertos usando el control WINSOCK. Para esta miniguia propngo el siguiente codigo ya que cumple con las condiciones del programa del PIC:
Private sub Form_Load() ' puerto PORTD Winsock1.Protocol = sckUDPProtocol Protocolo que usa el socket Winsock1.RemoteHost = "192.168.1.20" IP remota la del PIC Winsock1.RemotePort = 200 Puerto a enviar los paquetes Winsock1.Bind 1002 Puerto donde escucha la PC End sub 'Cachamos datos para funcniones del PORTD Private Sub winsock1_DataArrival(ByVal bytesTotal As Long) Dim strData As String Winsock1.GetData strData Text3.Text = strData End Sub 'Enviamos datos para toggle de bits del PORTD Private Sub Check1_Click() If Check1 = 1 Then Winsock1.SendData "RDO0" Else Winsock1.SendData "RDF0" End If End Sub Private Sub Check2_Click() If Check2 = 1 Then Winsock1.SendData "RDO1" Else Winsock1.SendData "RDF1" End If End Sub Private Sub Check3_Click() If Check3 = 1 Then Winsock1.SendData "RDO2" Else Winsock1.SendData "RDF2" End If End Sub Private Sub Check4_Click() If Check4 = 1 Then Winsock1.SendData "RDO3" Else Winsock1.SendData "RDF3" End If End Sub Private Sub Check5_Click() If Check5 = 1 Then Winsock1.SendData "RDO4" Else Winsock1.SendData "RDF4" End If End Sub Private Sub Check6_Click() If Check6 = 1 Then Winsock1.SendData "RDO5" Else Winsock1.SendData "RDF5" End If By Navaismo Pgina - 8 -

Private Sub Check7_Click() If Check7 = 1 Then Winsock1.SendData "RDO6" Else Winsock1.SendData "RDF6" End If End Sub Private Sub Check8_Click() If Check8 = 1 Then Winsock1.SendData "RDO7" Else Winsock1.SendData "RDF7" End If End Sub 'Encendemos todo el PORTD Private Sub Command1_Click() Check1 = 1 Check2 = 1 Check3 = 1 Check4 = 1 Check5 = 1 Check6 = 1 Check7 = 1 Check8 = 1 End Sub 'Apagamos Todo El PORTD Private Sub Command2_Click() Check1 = 0 Check2 = 0 Check3 = 0 Check4 = 0 Check5 = 0 Check6 = 0 Check7 = 0 Check8 = 0 End Sub

Con esto podemos observar como responde nuestro programa:

By Navaismo

Pgina - 9 -

Y por ultimo les dejo una foto de la M2ETH-BOARD.

Espero esta pequea gua les haya sido de utilidad.

By Navaismo

Pgina - 10 -