Programa Principal:
program PICNTP
include "enc_ss" ' modulo donde se implementa el codigo
include "eth_enc28j60" ' modulo usado por el compilador
dim mymacaddr as byte [6] ' variables para MAC, IP, DNS,GW,MASCARA, Paquete NTP
dim myipaddr as byte [4]
dim gwipaddr as byte [4]
dim dnsipaddr as byte [4]
dim ipmask as byte [4]
dim NTP_Pack as byte [48]
dim dum as byte
sub procedure pausa() ' Pausa para el retardo NTP y recepcion de Paquetes
for i=0 to 100
spi_ethernet_dopacket() ' aun en la Pausa escuchamos peticiones UDP o TCP
delay_ms(100)
spi_ethernet_dopacket()
next i
end sub
'/////////////////// Datos del Paquete UDP explicacion Gracias a: Andrew Gregory //////////////////////
'
'http://tools.ietf.org/html/rfc1305
'http://tools.ietf.org/html/rfc867
'
'Byte 0: flags:
' Bits 7-6: Leap Indicate (zero for request)
' Bits 5-3: Version (4)
' Bits 2-0: Mode (i.e. 3 for client (or maybe 1 for symmetric active))
'Byte 1: stratum (zero for request)
'Byte 2: poll (zero for request)
'Byte 3: precision (zero for request)
'Bytes 4-7: root delay (zero for request)
'Bytes 8-11: root dispersion (zero for request)
'Bytes 12-15: reference id (zero for request)
'Bytes 16-23: reference timestamp (zero for request)
'Bytes 24-31: originate timestamp (zero for request)
'Bytes 32-39: receive timestamp (zero for request)
'Bytes 40-47: transmit timestamp (set to current time)
'
'////////////////////////////////////////////////////////////////////////////////////////////
sub procedure req_ntp() ' Construccion de Paquete NTP
NTP_Pack[0]= 0x23 ' Enviamos modo Cliente, sin estrato
for dum=1 to 47 ' Todos los demas Bytes son 0
NTP_Pack[dum]=0
next dum
spi_ethernet_sendudp(IPD,123,123,@NTP_Pack,48) 'Enviamos el paquete NTP al Servidor
end sub
'//////////////////////////////////// Configuracion de Variables ////////////////////////////
main:
adcon0=0 ' Sin ADC's, Sin Comparadores PORTA Entrada
adcon1=15
cmcon=7
trisa=255
porta=0
trisd=0 ' PORTD de Salida =0
portd=0
mymacaddr[0]= 0x00 ' MAC del PIC
mymacaddr[1]= 0x00
mymacaddr[2]= 0x00
mymacaddr[3]= "M"
mymacaddr[4]= "A"
mymacaddr[5]= "X"
myipaddr[0]=20 ' IP del PIC
myipaddr[1]=0
myipaddr[2]=4
myipaddr[3]=20
' Mascara del PIC
ipmask[0]=255
ipmask[1]=255
ipmask[2]=255
ipmask[3]=0
dnsipaddr[0]=20 'DNS y GW del PIC
dnsipaddr[1]=0
dnsipaddr[2]=4
dnsipaddr[3]=1
gwipaddr[0]=20
gwipaddr[1]=0
gwipaddr[2]=4
gwipaddr[3]=1
IPD[0]=20'148
IPD[1]=0'243 'IP del Servidor NTP
IPD[2]=4'7
IPD[3]=10'30
LCD_CONFIG(PORTB,7,6,5,4,PORTB,0,2,1) 'Configuramos el PORTB para el LCD
LCD_OUT(1,1,"INICIALIZANDO")
DELAY_MS(3000)
spi_init() 'iniciamos SPI en el PIC
spi_ethernet_init(portc,0,portc,1,mymacaddr,myipaddr,1) 'Configuramos e Iniciamos el Ethernet del PIC
spi_ethernet_confnetwork(ipmask,gwipaddr,dnsipaddr)
for i=0 to 2 ' Blink para ver si esta vivo Termina con RD7 en ON
portd.7=0
delay_ms(500)
portd.7=1
delay_ms(500)
next i
tryntp: ' empezamos la recepcion de paquetes
while true
spi_ethernet_dopacket() ' Escuchamos peticiones TCP y UDP
req_ntp() ' Pedimos la hora UTC cada 10s.
cls ' Limpiamos el LCD
lcd_out(1,1,fecha.str1) ' Mostramos en la primer linea el dia, mes y año
lcd_out(2,1,fecha.str2) ' Mostramos en la segunda linea la Hora sin puntitos
pausa() ' Llamamos a Pausa
spi_ethernet_dopacket() ' Escuchamos peticiones TCP y UDP
wend
goto tryntp ' Loop
end.
MODULO 1:
module enc_ss
include "eth_enc28j60_api" ' modulo del compilador
include "unixtime"
dim getRequest as byte[20] ' variables de uso general
dyna as byte[30]
NTPr as byte[48] ' Variable donde se guarda los datos provenienes del Server
txt as string[20]
i,l as byte
dim IPD as byte [4]
const httpHeader as string[31] = "HTTP/1.1 200 OK"+chr(10)+"Content-type: " ' HTTP header
const httpMimeTypeHTML as string[13] = "text/html"+chr(10)+chr(10) ' HTML MIME type
const httpMimeTypeScript as string[14] = "text/plain"+chr(10)+chr(10) ' TEXT MIME type
const httpMethod as string[5] = "GET /"
'///////////////////////////// ' Pagina a mostrar ////////////////////////////////
const pagina as string [837]=
""+
""+
""+
"PIC NTP "+
""+
""+
"
"+
"
"+
"
"+
"
"+
"
"+
"Actualice la Configuración
"+
"
"+
""+
"
"
'/////////////////////////// Implementacion TCP
sub function Spi_Ethernet_UserTCP(dim byref remoteHost as byte[4], dim remotePort, localPort, reqLength as word) as word
result=0
if localport<>80 then 'escuchamos puerto 80
result=0
end if
for i = 0 to 23
getRequest[i] = Spi_Ethernet_getByte()
next i
getRequest[i] = 0
i = 0
while (httpMethod[i] <> 0)
txt[i] = httpMethod[i]
i = i + 1
wend
if(memcmp(@getRequest, @txt, 5)<>0) then ' Solo se soporta en metodo GET
result = 0
exit
end if
if(getRequest[5] = "x") then 'Si el byte 5 corresponde a "x" mostramos los valores
'el texto puede interpretarse como javascritp /x
result = Spi_Ethernet_putConstString(@httpHeader) ' HTTP header
result = result + Spi_Ethernet_putConstString(@httpMimeTypeScript) ' MIME type
'Mostramos Fecha Contruyendo una variable tipo string JS: var= " fecha";
dyna = fecha.str1
txt = "var Fecha= "
result = result + Spi_Ethernet_putString(@txt)
txt = ""+chr(34)
result = result + Spi_Ethernet_putString(@txt)
result = result + Spi_Ethernet_putString(@dyna)
txt = ""+chr(34)
result = result + Spi_Ethernet_putString(@txt)
txt = ";"
result = result + Spi_Ethernet_putString(@txt)
' Mostramos Hora Contruyendo una variable tipo string JS: var= " Hora";
txt = "var Hora= "
result = result + Spi_Ethernet_putString(@txt)
dyna = fecha.str2
txt = ""+chr(34)
result = result + Spi_Ethernet_putString(@txt)
result = result + Spi_Ethernet_putString(@dyna)
txt = ""+chr(34)
result = result + Spi_Ethernet_putString(@txt)
txt = ";"
result = result + Spi_Ethernet_putString(@txt)
end if
if(result = 0) then 'Mostrar por defalt
result = Spi_Ethernet_putConstString(@httpHeader) ' HTTP header
result = result + Spi_Ethernet_putConstString(@httpMimeTypeHTML) ' HTML MIME type
result = result + Spi_Ethernet_putConstString(@pagina) ' Pagina HTML
end if
end sub
'//////////////////////////// Implementacion UDP
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 = 123 then ' Escuchamos por el puerto 123 para capturar datos NTP
for i=0 to 47
NTPr[i]=spi_ethernet_getbyte() 'Grabamos los datos en la variable
next i
FSR2Ptr = @UTCseg ' Converimos los valores separados en una variable de 32bits
POSTINC2 = NTPr[43]
POSTINC2 = NTPr[42]
POSTINC2 = NTPr[41]
INDF2 = NTPr[40]
actualdate() ' Llamamos al Procedimiento para convertir la hora.
end if
end sub
end.
Modulo 2:
module UnixTime
dim diat as string[3] ' Variables para convertir a cadena
mdt as string[3]
mes as string[3]
yyt as string[5]
hht as string[3]
mmt as string[3]
sst as string[3]
UnixTimec as longword ' Variable para tiempo UNIX
UTCseg as longword ' Variable que contiene los segundos UTC de 32bits
const USRGMT = 18000 ' Constante GMT para Mexico
structure TIEMPO
dim ss as byte ' segundos
dim mn as byte ' minutos
dim hh as byte ' Horas
dim md as byte ' Dia del mes de 1 a 31
dim wd as byte ' Dia de la Semana Lunes=1....Domingo=6
dim mo as byte ' Mes del año de 1 a 12
dim yy as word ' Año YK2
dim str1 as string[17] 'Donde guardamos la Fecha
dim str2 as string[16] 'Donde Guardamos la Hora
end structure
dim fecha as TIEMPO ' variable para la fecha
const offset = 2208988800 ' Diferencia en segundos entre 1900 y 1970
sub procedure cls
lcd_cmd(lcd_clear) ' Rutina para limpiar LCD
delay_ms(200)
end sub
'//////////////////////////////////////// Procedimiento Para obtener Fecha en Formato Humano /////////////////////////////
sub procedure ActualDate()
UnixTimec = ((UTCseg - USRGMT)+ 9) - offset ' Calculamos el TiempoUnix restando a los segundos UTC el gmt del usuario y el offset UNIX
Time_epochToDate(UnixTimec,fecha) ' Obtenemos la fecha actual en Formato Humano
select case fecha.wd ' Escogemos el Dia segun su valor
case 0
diat="Lun"
case 1
diat="Mar"
case 2
diat="Mie"
case 3
diat="Jue"
case 4
diat="Vie"
case 5
diat="Sab"
case 6
diat="Dom"
end select
select case fecha.mo 'Escogemos el mes segun su valor
case 1
mes="Ene"
case 2
mes="Feb"
case 3
mes="Mar"
case 4
mes="Abr"
case 5
mes="May"
case 6
mes="Jun"
case 7
mes="Jul"
case 8
mes="Ago"
case 9
mes="Sep"
case 10
mes="Oct"
case 11
mes="Nov"
case 12
mes="Dic"
end select
' convertimos a cadena la Fecha
bytetostr(fecha.md,mdt)
wordtostr(fecha.yy,yyt)
bytetostr(fecha.hh,hht)
bytetostr(fecha.mn,mmt)
bytetostr(fecha.ss,sst)
fecha.str1= diat 'Asignamos el dia a la variable Fecha.str1 y anexamos despues los demas valores
strcat(fecha.str1,mdt)
strcat(fecha.str1,mes)
strcat(fecha.str1,yyt)
fecha.str2= hht 'Asignamos la hora a la variable Fecha.str2 y anexamos despues los demas valores
strcat(fecha.str2,mmt)
strcat(fecha.str2,sst)
end sub
end.
Y Aqui unas Imagenes de como se veia:
No hay comentarios:
Publicar un comentario