Ok SISPIC, si demenuzo demasiado el codigo voy a convertirlo en ilegible, por lo tanto lo cuelgo aqui mismo a ver si me puedes orientar hoy que es mu cumple, je..je..
Codigo:
"****************************************************************
"* Nombre : Medidor de Presion 1.BAS *
"* Autor : Marcos Lazcano - MGLSOFT *
"* Notice : Copyright (c) 2002 MGLSOFT *
"* : Todos los derechos reservados. *
"* Fecha : 01/10/2002 *
"* Versión : 1.1 *
"* Uso : Medidor de usos multiples con conversor A/D serial*
"* : SPI, con calibracion digital. *
"****************************************************************
" Este programa lee un conversor A/D serial MCP3204 de 12 Bits
" se utilizan 2 de los 4 canales posibles del conversor.
" Utiliza un PIC16F877
INCLUDE "modedefs.bas"
"******************** Seteo del display LCD **************
" El display LCD sera connectado de la siguiente forma:
" Port LCD Port PIC
" DB0-3 No conectar
" DB4 PortC.0
" DB5 PortC.1
" DB6 PortC.2
" DB7 PortC.3
" RS PortA.4
" E PortA.5
" RW Ground
" Vdd +5 volts
" Vss Ground
" Vo potenciometro de 20K (o ground)
DEFINE LCD_DREG PORTC
DEFINE LCD_DBIT 0 " Setear bit de comienzo de dato (0 o 4) si es bus a 4-bit
DEFINE LCD_RSREG PORTA " RS PortA.4
DEFINE LCD_RSBIT 4
DEFINE LCD_EREG PORTA " E PortA.5
DEFINE LCD_EBIT 5
DEFINE LCD_BITS 4 " Tamaño del bus de datos (4 o 8 bits)
DEFINE LCD_LINES 2 " Seteo del numero de lineas en LCD
DEFINE LCD_COMMANDUS 2000 " Seteo del retardo entre comandos en LCD
DEFINE LCD_DATAUS 50 " Seteo del retardo entre datos del LCD
"**************************************************************************
" Definicion de constantes y posiciones EEPROM
BitsConv con 12 "cantidad de bits del convertidor
eeKal con 0 "lugar de la eeprom donde se guarda eeKal
ValLow con eeKal + 2 "lugar donde se almacena el valor bajo
ValHigh con ValLow + 2 "lugar de almacenamiento del valor alto
eeOffset con ValHigh + 2 "lugar de la eeprom donde se guarda Offset
eeSpan con eeOffset + 2"lugar de la eeprom donde se guarda Span
eeFinal con eeSpan + 2 "final de escala del display
TempHigh con eeFinal + 2 "lugar de almacenamiento del valor alto
eeDir con TempHigh + 2 "lugar de almacenamiento de la Id de red
Menu con eeDir + 1 "maxima cantidad de menues activos
"Pines de manejo de conversiones (puede habilitarse el conversor interno)
CS VAR portA.0 "pin de Chip Select del conversor
Din VAR portA.1 "pin de entrada serial del conversor
CLK VAR portA.2 "pin de Clock del convertidor
Dout VAR portA.3 "pin de salida serial del conversor
"Pines a usar con teclado 4 teclas
TeclaClear var portB.7 "tecla borrar (Clear)
TeclaProg var portB.6 "tecla programacion
TeclaDown var portB.5 "tecla abajo (Down)
TeclaUp var portB.4 "tecla arriba (Up)
"Puertos de comunicacion COMM1 y COMM2
TxComm1 var portC.6 "pin de transmicion del COMM1
RxComm1 var portC.7 "pin de recepcion del COMM1
TxComm2 var portB.3 "pin de transmicion del COMM2 (futuro CAN)
RxComm2 var portB.2 "pin de recepcion del COMM2 (futuro CAN)
Habil var portB.1 "habilitacion transmicion RS422 en COMM1
INT var portB.0 "pin de interrupciones (futuro uso en CAN)
"PortC y PortD estan preparados para conectar una placa de 10 entradas / salidas
Ent1 VAR portD.0 "entradas placa I/O
Ent2 VAR portD.1
Ent3 VAR portD.2
Ent4 VAR portD.3
Sal1 VAR portC.4 "salidas placa I/O
Sal2 VAR portC.5
Sal3 VAR portD.4
Sal4 VAR portD.5
Sal5 VAR portD.6
Sal6 VAR portD.7
"Salidas de control a reles
Rele1 VAR portE.0 "salida de control presion baja
Rele2 VAR portE.1 "salida de control presion alta
Rele3 VAR portE.2 "salida de control temperatura alta
"las teclas pueden generar interrupciones, de ser necesario
"******************************************************************
" variables de trabajo del conversor , calibracion y lecturas
Config var byte "palabra de configuracion del conversor A/D
MaxBits var word "numero de divisiones del convertidor
Temperat var word "contiene la temperatura actual leida
Presion var word "contiene el valor actual de la presion
ValorDisp var word "contiene el valor a mostrar en display
CteKal var word "contiene la constante de calibracion
Final var word "contiene el valor final de escala de display
Span var word "maximo de escala luego de calibrar
Offset var word "minimo de la escala luego de calibrar
Rango var word "longitud de escala de medicion
"Prom var word "sumatoria de conversiones
DataIn var word "dato directo de cada conversion A/D
DatoConv var word "dato resultante de las conversiones promediadas
Prom VAR WORD(Promedio)
Filtro var word
Index VAR BYTE
"********************************************************************
" variables de uso general
Var1 var word "variable de uso general1
Var2 var word "variable de uso general2
Z var word "variable de uso general3
"**********************************************************************
" variables usadas en comparaciones
MaxTemp var word "limite de temperatura maxima
MaxPres var word "limite de presion maxima
MinPres var word "limite de presion minima
"***********************************************************************
" variables de usos variados
"Promedio var byte "variable con la cantidad posible de promedios a ejecutar
Promedio CON 12
Medida var byte "valor a mostrar antes del nominal actual
MaxMenu var byte "maximo valor de la cantidad de menues 255
X var byte "variable de contadores pulsacion teclas
I var byte "variable de uso general
J var byte "variable de uso general
Init var bit "marca inicio de programa
ticks var byte "numero de interrupciones
Convert var byte "habilitacion de conversiones
CantConv var word "cantidad de conversiones por segundos acumulada
AuxConv var word "cantidad de segundos acumulada
second var word "cantidad de segundos acumulada
"**********************************************************************
" variables de uso en muestreo en display
B0 VAR BYTE "variable DISPLAY que contiene digito 0
B1 VAR BYTE "variable DISPLAY que contiene digito 1
B2 VAR BYTE "variable DISPLAY que contiene digito 2
B3 VAR BYTE "variable DISPLAY que contiene digito 3
B4 VAR BYTE "variable DISPLAY que contiene digito 4
B5 VAR BYTE "variable DISPLAY que contiene signo
T0 VAR BYTE "variable DISPLAY que contiene digito 0 TEMP
T1 VAR BYTE "variable DISPLAY que contiene digito 1 TEMP
T2 VAR BYTE "variable DISPLAY que contiene digito 2 TEMP
"**********************************************************************
" variables de registros de transmicion y recepcion
ChecKsum var byte "contiene el checksum de transmision
ChecKsum2 var byte "contiene el checksum de transmision 2
ChecKIn var byte "contiene el checksum de recepcion
MiCheck var byte "checksum para comparacion con checkin
Direccion var byte "valor de la direccion de red
Espera var byte "valor del tiempo de espera comunicacion
DirIn var byte "direccion de envio transmicion
ByteDir1 var byte "digitos del checksum de entrada
ByteDir2 var byte "digitos del checksum de entrada
TX0 VAR BYTE "variable TX que contiene digito 0
TX1 VAR BYTE "variable TX que contiene digito 1
TX2 VAR BYTE "variable TX que contiene digito 2
TX3 VAR BYTE "variable TX que contiene digito 3
TX4 VAR BYTE "variable TX que contiene digito 4
TX5 VAR BYTE "variable TX que contiene digito 5
TX6 VAR BYTE "variable TX que contiene digito 6
TX7 VAR BYTE "variable TX que contiene digito 7
RX0 VAR BYTE "variable RX que contiene digito 0
RX1 VAR BYTE "variable RX que contiene digito 1
RX2 VAR BYTE "variable RX que contiene digito 2
RX3 VAR BYTE "variable RX que contiene digito 3
RX4 VAR BYTE "variable RX que contiene digito 4
"Configuracion de puertos
TRISA = %00001000
ADCON1 = 6 "Dout es entrada y el resto son salidas
TRISB = %11111001 "CAN TX y Habil son salidas y el resto son entradas
TRISE = %000 "todas son salidas
TRISD = %00001111 "entrada y salidas
"Inicializacion de la USART para comunicacion
TRISC = %10000000 "RX es entrada TX y el resto son salidas
"SPBRG = 25 " Velocidad a 9600 bps
SPBRG = 12 " Velocidad a 19200 bps
RCSTA = %10010000 "Habilita puerto serial y recepcion continua
TXSTA = %00100100 "Habilita transmicion en modo asincronico
PIE1 = %00100000 "interrupcion de recepcion habilitada
" Set TMR0 to interrupt every 16.384 milliseconds
OPTION_REG = %11000101 " Set TMR0 configuration and not enable PORTB pullups
INTCON = %11100000 "Habilitar interr. generales,perifericos
"y TMR0
Init = 1 "marca de inicio
"*************************************
"Inicio del programa
"*************************************
Inicio:
gosub ApagSalidas
" Guarda CteKal, Set1 y Set2 arrancando en posicion 1 cuando se programa
EEPROM ValHigh,[$F0,$00]
EEPROM ValLow,[$32,$00]
EEPROM TempHigh,[$F0,$00]
EEPROM eeFinal,[$FA,$00]
eeprom eeDir,[$07]
eeprom Menu,[$07]
clear "poner las variables a cero en arranque
"calcular divisiones internas
gosub VerBits
Espera = 20 "carga valor inicial en tiempo de espera Comm
pause 100 "pausa para habilitar el display
for I = 1 to 6
LCDOut $FE,1
pause 200
LCDOut "Inicializando..."
lcdout $FE, $C0 "a segunda linea
LCDOut dec BitsConv, "Bits="
LCDOut $fe, $C9 "seguir en segunda linea
LCDOut dec MaxBits, "Div"
pause 200
next I
PAUSE 1200
LCDOut $fe, 1 "Borrar LCD
lcdout " Controlador de "
LCDOut $fe, $C0 "posicionar en inicio segunda linea
LCDOut " PRESION FILTROS"
pause 2000
"restaurar valores de la EEprom
read eeKal, CteKal.byte0 "levanta el valor de la constante
read eeKal+1, CteKal.byte1 "de calibracion del instrumento
read eeOffset, Offset.byte0 "levanta el valor del Offset
read eeOffset+1, Offset.byte1 "de calibracion del instrumento
read eeSpan, Span.byte0 "levanta el valor del Span
read eeSpan+1, Span.byte1 "de calibracion del instrumento
read eeFinal, Final.byte0 "levanta el valor del maximo de escala
read eeFinal+1, Final.byte1 "de calibracion del instrumento
read ValHigh, MaxPres.byte0 "levanta el valor de maxima presion
read ValHigh + 1, MaxPres.byte1 "de calibracion del instrumento
read ValLow, MinPres.byte0 "levanta el valor de minima presion
read ValLow + 1, MinPres.byte1 "de calibracion del instrumento
read TempHigh, MaxTemp.byte0 "guarda el valor de maxima temperatura
read TempHigh + 1, MaxTemp.byte1 "de calibracion del instrumento
read eeDir, Direccion "levanta direccion de red
read Menu, MaxMenu "levanta el maximo de menues activo
gosub CalcCheckIn "calcula checksum entrada
"rutina de testeo general ante pulsacion de boton UP al inicio
X = 0
" button TeclaUp,1,100,10,X,1,MensInit
ClickUp:
pause 100 "pausa de 100 milisegundos
X = X + 1 "incrementa X
if X > 10 then MensInit "presionada un segundo va a mensaje
if TeclaUp = 1 then ClickUp "repite hasta liberar boton
X = 0 "pongo en cero la variable
"rutina de testeo general ante pulsacion de boton Prog al inicio
ClickProg:
pause 100 "pausa de 100 milisegundos
X = X + 1 "incrementa X
if X > 20 then Calibrar "presionada dos segundos va a calibrar
if TeclaProg = 1 then ClickProg "repite hasta liberar boton
"rutina de testeo general ante pulsacion de boton Left al inicio
X = 0
" button TeclaDown,1,100,10,X,1,PruebaIO
ClickLeft:
pause 100 "pausa de 100 milisegundos
X = X + 1 "incrementa X
if X > 10 then PruebaIO "presionada un segundo va a mensaje
if TeclaDown = 1 then ClickLeft "repite hasta liberar boton
" gosub PruebaIO
"**********************************
"rutina principal
"**********************************
on interrupt goto Interrupcion "ante interrupcion usar handler int.
Loop:
if ticks >= Convert then
disable
gosub Convertir
enable
"if ticks >= Convert then
gosub Calculo "preparo valor a mostrar en display
gosub Display "muestra el resultado en display
Var2 = Var2 + 1 "incrementa conteo de pasadas por aqui
" Convert = ticks + 2 "solo muestra dentro de tres ticks
Convert = ticks + 3 "solo muestra dentro de cuatro ticks
"actualiza display (60/2=30) 30 veces por segundo "28/10/02
endif
gosub Comparar "compara con limites y toma accion
gosub Teclado "atiende acciones del teclado
goto Loop
INCLUDE "calibrac4.bas"
INCLUDE "convertir 12 bits Rev2.bas"
INCLUDE "calculo.bas"
INCLUDE "Display2.bas"
INCLUDE "VerBits.bas"
include "Teclado.bas"
Include "Comparar.bas"
Include "Filtrado.bas"
"************************************
"rutina de puesta a cero salidas I/O
"************************************
ApagSalidas:
High Sal1
High Sal2
High Sal3
High Sal4
High Sal5
High Sal6
Return
"**********************************
"rutina de prueba de reles
"**********************************
PruebaReles:
LCDOut $FE, 1 "Borrar LCD
LCDOut "Probando reles"
lcdout $FE, $C0 "a segunda linea
LCDOut "Relay "
for X = 0 to 2
B0 = 1
high Rele1
lcdout $FE, $C7 "a segunda linea
LCDOut dec B0," ON "
pause 500
low Rele1
lcdout $FE, $C7 "a segunda linea
LCDOut dec B0," OFF"
pause 500
B0 = 2
high Rele2
lcdout $FE, $C7 "a segunda linea
LCDOut dec B0," ON "
pause 500
low Rele2
lcdout $FE, $C7 "a segunda linea
LCDOut dec B0," OFF"
pause 500
B0 = 3
high Rele3
lcdout $FE, $C7 "a segunda linea
LCDOut dec B0," ON "
pause 500
low Rele3
lcdout $FE, $C7 "a segunda linea
LCDOut dec B0," OFF"
pause 500
next X
return
"**********************************
"rutina de prueba de placa I/O
"**********************************
PruebaIO:
for X = 0 to 4
low Sal1
pause 100
high Sal1
pause 100
low Sal2
pause 100
high Sal2
pause 100
low Sal3
pause 100
high Sal3
pause 100
low Sal4
pause 100
high Sal4
pause 100
low Sal5
pause 100
high Sal5
pause 100
low Sal6
pause 100
high Sal6
pause 100
next X
goto Loop
return
"**********************************
"rutina del mensaje de inicio
"**********************************
MensInit: "*******sacado 13/3/2002 por falta de memoria
"mensaje de bienvenida o prueba de display segun modelo
LCDOut $fe, 1 "Borrar LCD
LCDOut "Medidor multipro"
lcdout $FE, $C0 "a segunda linea
LCDOut "posito -MGL 2002"
pause 2000
LCDOut $FE, 1 "Borrar LCD
LCDOut "Pulse Prog para"
lcdout $FE, $C0 "a segunda linea
LCDOut "ver prueba reles"
X = 0
" button TeclaProg,1,100,30,X,1,Loop
"rutina de testeo general ante pulsacion de boton Prog
ClickPRG:
pause 100 "pausa de 100 milisegundos
X = X + 1 "incrementa X
if X > 10 then Sigo "presionada un segundo va a mensaje
if TeclaProg = 1 then ClickPRG "repite hasta liberar boton
" Vuelve1:
" if TeclaProg = 0 then Vuelve1
"ClickProg2:
" if TeclaProg = 1 then ClickProg2 "repite hasta liberar boton
Sigo:
gosub PruebaReles
" gosub Display
"gosub Transmitir
goto Loop
return
disable
Interrupcion:
INTCON.7 = 0 "apago interrupciones generales
INTCON.6 = 0 "idem con perifericas
INTCON.5 = 0 "idem con Int de TMR0
if (PIR1.5 = 1) then "no es interrupcion del TMR0, es TX
hserin Espera,LabelExit2,[WAIT (">"
,hex2 DirIn,SKIP 1,hex2 CheckIn]
" hserin Espera,LabelExit,[WAIT (">",RX4),SKIP 1,hex2 CheckIn]
" hserin Espera,LabelExit,[hex2 DirIn,SKIP 1,hex2 ChecKIn]
gosub CalcCheckIn
if (DirIn = Direccion)and (ChecKIn = MiCheck) then
Gosub PrepDigitos
gosub TXint
endif
endif
if (INTCON.2 = 1) then "Si hay bandera de interrupcion por Timer0
ticks = ticks + 1 " Cuenta partes de segundo
INTCON.2 = 0 " Reseteo bandera de interrupcion por Timer0
IF ticks < 61 Then LabelExit
" 61 ticks por segundo (16.384ms por tick)
ticks = 0 " Paso un segundo - actualizo tiempo
Convert = ticks
second = second + 1
CantConv = AuxConv "guardo cantidad de conversiones por segundo
AuxConv = 0 "limpio auxiliar de conversiones por segundo
Var1 = Var2 "guardo actualizaciones de display por segundo
Var2 = 0 "limpio actualizaciones de display por segundo
IF second >= 3600 Then "si algo no paso antes borro cuenta
second = 0
endif
endif
LabelExit2:
RCSTA.4 = 0 "reparo error de recepcion
LabelExit:
RCSTA.4 = 1 "habilito recepcion continua
INTCON.7 = 1 "enciendo interrupciones generales
INTCON.6 = 1 "idem con perifericas
INTCON.5 = 1 "idem con Int de TMR0
RESUME
enable
"Transmitir:
" ChecKsum2 = "<" + (B4+30) + (B3+30) + (B2+30) + (B1+30) + (B0+30)
" high Habil "habilitacion para usar RS422
" hserout ["MGLSOFT 2002",CR,LF] "Mensaje 1
" hserout ["<",dec B4,dec B3,dec B2,dec B1,dec B0,dec ChecKsum2,CR,LF] "Mensaje 3
" low Habil "RS422 a alta impedancia
" return
TXint:
high Habil "habilitacion para usar RS422
ChecKsum ="<"+(TX4+30)+(TX3+30)+(TX2+30)+(TX1+30)+(TX0+30)+(T2+30)+(T1+30)+(T0+30)
hserout ["<",dec TX4,dec TX3,dec TX2,dec TX1,dec TX0,dec T2,dec T1,dec T0,hex ChecKsum,CR,LF] "Mensaje 3
low Habil "RS422 a alta impedancia
return
CalcCheckIn:
asm
movf _Direccion,w ;cargar direccion en W
andlw 0FH ;comparar eliminando parte alta
movwf _ByteDir1
swapf _Direccion,w ;leer direccion invertida
andlw 0FH ;comparar eliminando parte alta
movwf _ByteDir2
endasm
"read eeDir, Direccion
MiCheck = (ByteDir1+48)+(ByteDir2+48)+"m"
return
Fijate si te es posible orientarme a ver como puedo interrumpir mejor, si observas veras un Label hecho para tratar el error de mala recepcion, lo puse ante la colgada que se me pegaba el PIC por falsa recepcion.
Gracias por colaborar.