# Temporizador para insoladora con PIC



## mikeekim (Ago 19, 2011)

Buenas compañeros del foro, estoy montando mi propia insoladora con leds UV pero tengo un problema con la programacion del pic 16F628A en picbasic pro, que consta de varias rutinas
una de definicion del tiempo que desea el usuario, otra de pausa, otra de isolado y otra de completado.
Usando el comando pause 1000 realiza el descuento de tiempo desde 100 horas hasta completado, pero el usuario puede definir el tiempo deseado al poner en marcha la isoladora,
mostrando digito a digito el tiempo que le vas introduciendo mediante los pulsadores sumar y seleccionar digito, hasta que al introducir el valor del ultimo digito pasa automaticamente a la rutina de preparado, esperando una pulsacion de START para iniciar el isolado.
En ese momento manteniendo pulsada la tecla START empieza la isolacion.
Pero tengo un problema.
En proteus (isis) la simulacion del programa funciona bastante bien ya que hace lo que yo deseo, pero en la protoboard no lo hace, el programa no espera a que yo introduzca el tiempo saltando de digito a digito a la hora de definir el tiempo deseado sin dejarme hacerlo y pasando de la rutina de la definicion del tiempo deseado para isolar a la rutina de START, ademas salta de la rutina de isolado a la rutina de pausa, le he dado mil vueltas y no comprendo que tengo mal en la programacion del pic para que en proteus me funcione bien y en la protoboard no.
Que me podeis ayudar a resolver el problema porfavor?
Os adjunto el programa en picbasic pro y el esquema en proteus con su respectivo HEX para que en la medida de lo posible me ayudeis a resolver mi problema.
Un saludo.

Ver el archivo adjunto temporizador insoladora.rar
Esquema en proteus con el HEX


```
' Temporizador microcontrolado con 16F628A de 100 horas hasta 0
' utilizando pausas de 1000 ms para crear el decremento de 1 seg
' portb.3 sera usado para activar la carga, un opto moc 3020 que a su vez activara
' un triac con amperaje suficiente para soportar una carga de unos 5 amp
' ya que la finalidad del temporizador es activar un trafo de 220v -->12v +/-5a
' y este alimentara a una placa tamaño din A4 con 200 leds UV con sus respectivas resistencias de 470H.
' o tambien activar 2 placas de din A5 con 100 leds por placa para crear isolacion a doble cara.
' los fuses debo definirlos en el programador ya que PBP con MPLAB solo permite definirlos asi
' usando el valor de config word 3F0D
' FUSES XT, WDT ON, PWRT OFF, MCLRE OFF, BOREN OFF, LVP OFF, CPD OFF, CP OFF
DEFINE XT
DEFINE WDT_ON
DEFINE PWRT_OFF
DEFINE MCLRE_OFF
DEFINE BOREN_OFF
DEFINE LVP_OFF
DEFINE CPD_OFF
DEFINE CP_OFF 
DEFINE OSC 4
DEFINE LCD_DREG PORTB  'Define el puerto de los datos del LCD
DEFINE LCD_DBIT 4      'Utilizamos RB4 RB5 RB6 RB7 del PIC
DEFINE LCD_RSREG PORTB 'Define el puerto de RS
DEFINE LCD_RSBIT 0     'Numero de puerto de RS
DEFINE LCD_RWREG PORTB 'Puerto de RW
DEFINE LCD_RWBIT 1     'Numero de puerto de RW
DEFINE LCD_EREG PORTB  'Puerto de Enable
DEFINE LCD_EBIT 2      'Numero de puerto de Enable
DEFINE LCD_BITS 4      'BITS DE DATOS
DEFINE LCD_LINES 2     'LINEAS DEL LCD EN ESTE CASO 2
p var byte             ' tiempo de pausas
hd var byte            ' unidades de horas
hi var byte            ' decenas de horas
md var byte            ' unidades de minutos
mi var byte            ' decenas de minutos
sd var byte            ' unidades de segundos
si var byte            ' decenas de segundos
carga var portb.3
rled var porta.0       ' led rojo de marcha
vled var porta.1       ' led verde de pausa
paus var porta.2       ' pulsador de start
sele var porta.3       ' pulsador de seleccion tiempo y pausa
suma var porta.4       ' pulsador de añadir tiempo y continuar

p=100
sd=0
si=0
md=0
mi=0
hd=0
hi=0
CMCon=7
trisb=0
trisa=1
gosub ledson
pause 500
gosub clean
  lcdout $FE,1, "Inicializando"
  lcdout $FE,$C0,"Temporizador."
  pause 2000
setsd:                               ' inicio de rutina de definicion de tiempo
                                        ' Se añade tiempo digito a digito
                                        ' se cambia de digito pulsando CAMBIAR DIGITO / PAUSA
                                        ' tras pasar los 6 digitos de tiempo pasa a modo
                                        ' PREPARADO automaticamente esperando pulsacion
                                        ' del pulsador START para iniciar la isolacion.
if suma=0 then
 sd=sd+0
 gosub pins1
 else
 sd=sd+1
 gosub pins1
    if sd=10 then
    sd=0
    endif
endif
gosub clean
  lcdout $FE,1, "Definir tiempo."
  gosub lcd
  pause 500
  gosub clean
  lcdout $FE,1, "Definir tiempo."
  lcdout $FE,$c0, dec (hi), dec (hd), ":", dec (mi), dec (md), ":" ,dec (si)," "
  pause 500
if sele=1 then
gosub pins1
 goto setsi
 endif
goto setsd
setsi:
if suma=0 then
 si=si+0
 gosub pins1
 else
 si=si+1
 gosub pins1
    if si=6 then
    si=0
    endif
endif
gosub clean
  lcdout $FE,1, "Definir tiempo."
  gosub lcd
  pause 500
  gosub clean
  lcdout $FE,1, "Definir tiempo."
  lcdout $FE,$c0, dec (hi), dec (hd), ":", dec (mi), dec (md), ":"," ", dec (sd)
  pause 500
  if sele=1 then
  gosub pins1
 goto setmd
 endif
goto setsi
setmd:
if suma=0 then
 md=md+0
 gosub pins1
 else
 md=md+1
 gosub pins1
    if md=10 then
    md=0
    endif
endif

gosub clean
  lcdout $FE,1, "Definir tiempo."
  gosub lcd
  pause 500
  gosub clean
  lcdout $FE,1, "Definir tiempo."
  lcdout $FE,$c0, dec (hi), dec (hd), ":", dec (mi)," ", ":",dec (si), dec (sd)
  pause 500
  if sele=1 then
  gosub pins1
 goto setmi
 endif
goto setmd
setmi:
if suma=0 then
 mi=mi+0
 gosub pins1
 else
 mi=mi+1
 gosub pins1
    if mi=6 then
    mi=0
    endif
endif

gosub clean
  lcdout $FE,1, "Definir tiempo."
  gosub lcd
  pause 500
  gosub clean
  lcdout $FE,1, "Definir tiempo."
  lcdout $FE,$c0, dec (hi), dec (hd), ":"," ", dec (md), ":",dec (si), dec (sd)
  pause 500
  if sele=1 then
  gosub pins1
 goto sethd
 endif
goto setmi
sethd:
if suma=0 then
 hd=hd+0
 gosub pins1
 else
 hd=hd+1
 gosub pins1
    if hd=10 then
    hd=0
    endif
endif

gosub clean
  lcdout $FE,1, "Definir tiempo."
  gosub lcd
  pause 500
  gosub clean
  lcdout $FE,1, "Definir tiempo."
  lcdout $FE,$c0, dec (hi)," ", ":", dec (mi), dec (md), ":",dec (si), dec (sd)
  pause 500
  if sele=1 then
  gosub pins1
 goto sethi
 endif
goto sethd
sethi:
if suma=0 then
 hi=hi+0
 gosub pins1
 else
 hi=hi+1
 gosub pins1
    if hi=10 then
    hi=0
    endif
endif

gosub clean
  lcdout $FE,1, "Definir tiempo."
  gosub lcd
  pause 500
  gosub clean
  lcdout $FE,1, "Definir tiempo."
  lcdout $FE,$c0," ", dec (hi), ":", dec (mi), dec (md), ":",dec (si), dec (sd)
  pause 500
  if sele=1 then
  gosub pins1
 goto start
 endif
goto sethi                     ' finalizacion de la rutina de definicion del tiempo de isolacion

start:                           ' rutina de preparado para isolar
gosub pins1
high vled
low rled
gosub clean
  lcdout $FE, 1, "Preparado."
  gosub lcd
  pause 500
  gosub clean
  lcdout $FE,1, "Pulse Start."
  gosub lcd1
  pause 400
gosub pins1
if porta.2 = 1 then   
goto inicio0
else
goto start
endif
inicio0:   ' conmuta los puertos de los leds de preparado (verde) e insolacion (rojo)
gosub pins
gosub pins1
gosub ledsoff
inicio:                 ' inicio de la rutina de descuento de tiempo y activa el puerto de carga
high portb.3
if porta.3 =1 then pausa
gosub clean
  lcdout $FE, 1, "Tiempo restante."
 gosub lcd
pause 500
gosub clean
  lcdout $FE, 1, "Tiempo restante."
 gosub lcd1
pause 500
if sd = 0 then
     if si =0 and sd=0 then    
          if md =0 and si=0 and sd=0 then          
               if mi =0 and md =0 and si=0 and sd=0 then               
                    if hd=0 and mi =0 and md =0 and si=0 and sd=0 then                    
                         if hi=0 and hd=0 and mi =0 and md =0 and si=0 and sd=0 then
                         goto final
                         endif                         
                    hi=hi-1
                    hd=10
                    mi=6
                    md=10
                    si=6
                    endif                    
               hd=hd-1
               mi=6
               md=10
               si=6
               endif               
          mi=mi-1
          md=10
          si=6
          endif          
     md=md-1
     si=6
     endif     
si=si-1
sd=10
endif
sd=sd-1
goto inicio ' finalizacion de la rutina de descuento de tiempo
               ' si el tiempo no es 00:00:00 vuelve a inicio

final:         ' rutina de finalizacion, conmutacion de puertos de leds y carga
low portb.3
high vled
low rled
gosub clean
  lcdout $FE, 1, "Completado."
 gosub lcd
pause 50
low vled
pause 950
goto final
pins: ' barrido de pins para setear puertos de pulsadores
 pause p
 trisa=%11111100
 trisa=%11101100
 trisa=%11110100
 trisa=%11111000
 return
pins1:
  pause p
  trisa=%11111100
  trisa=%10111100
  trisa=%11011100
  trisa=%11101100
  trisa=%11110100
  trisa=%11111000
  trisa=%11111100 
return                      ' fin del barrido de pins

ledson:                    ' leds en modo pausa
high vled
low rled
return

ledsoff:                    ' leds en modo isolado            
low vled
high rled
return

lcd:                         ' subrutinas de LCD para ahorrar espacio
lcdout $FE,$C0, dec (hi), dec (hd), ":", dec (mi), dec (md), ":" ,dec (si), dec (sd)
return

lcd1:
lcdout $FE,$C0, dec (hi), dec (hd), " ", dec (mi), dec (md), " " ,dec (si), dec (sd)
return

clean:
lcdout $FE, 1
  lcdout $FE, 1
  return
pausa:            ' Rutina de pausa se activa con el pulsador CAMBIAR DIGITO /PAUSAR
                     ' Se sale de Pausa activando el pulsador SUMAR TIEMPO / CONTINUAR
gosub ledson
low portb.3
low sele
low suma
low paus
gosub clean
lcdout $FE, 1, "Pausado."
gosub lcd
gosub pins
gosub pins1
pause 1000
gosub clean
lcdout $FE, 1, "Pulse Continuar."
gosub lcd
gosub pins
gosub pins1
pause 1000
if suma =1 then
suma=0
gosub ledsoff
goto inicio
else
suma=0
goto pausa
endif    ' fin de la rutina pausa
end
```


----------



## Meta (Ago 19, 2011)

También voy hacer una insoladora pero no de Led.

Uso este esquema y funciona a la primera, muy ueno.







Con código fuente incluido.

http://www.pic16f84a.org/index.php?...w=article&id=66&Itemid=87#Proteus_Capitulo_18

Saludo.


----------



## mikeekim (Ago 19, 2011)

Yo es que soy bastante novato con los pics y programaciones, agradezco tu aporte pero lo que deseo es aprender a hacerlo por mi mismo en la medida de mis limitaciones, me esfuerzo bastante para no tener que solicitar ayuda porque muchos foreros estan hartos de prestar ayuda y mas de una vez he visto el problema por mi mismo, pero ahora no consigo averiguar donde esta mi fallo, se que esta en la programacion del pic y seguramente en el barrido de puertos que hace el programa para setear los puertos y que los pulsadores no queden cebados para que puedan recibir una nueva pulsacion, pero no consigo averiguarlo.
Gracias de todas formas.


----------



## Meta (Ago 19, 2011)

Siento que no sepa tu lenguaje de programación, el mio es el ASM que muchos les dan quebraderos de cabeza, incluyéndome a mi.


----------



## markitosb (Ene 22, 2012)

amigo aqui hay uno mejorcito programable http://embedded-lab.com/blog/?p=4069
 yo lo probe y  funca de mil 
y aqui  otro http://embedded-lab.com/blog/?p=1378


----------



## Meta (Ene 22, 2012)

markitosb dijo:


> amigo aqui hay uno mejorcito programable http://embedded-lab.com/blog/?p=4069
> yo lo probe y  funca de mil
> y aqui  otro http://embedded-lab.com/blog/?p=1378



Muy bueno, no está hecho en asm.

Gracias por compartir.


----------



## kritter (Feb 19, 2012)

Hola Meta, conozco el circuito del libro del 16f84a, pero donde le añadirias el relay??? 
No controlo de lenguaje ensamblador para nada y no sabría a que i/o meterle el relay de 12V y que codigo meterle


----------



## Meta (Feb 19, 2012)

Hola:

¿Vez un Led rojo encendido?
Va conectado precisamente ahí y ya te funciona.

Precisamente haré ese temporizador para la insoladora que haré como buen proyecto y vale la pena.
Pones el .hex generado que puedes descargar y todo listo.

Saludo.


----------



## kritter (Feb 19, 2012)

Gracias Meta!!! 

Soy bastante novato y no había caido...mi libro esta en pdf y blanco y negro, se ve fatal!!!

Pero lo que no entiendo es que es LS1, ya que el buzzer si lo veo y LS1 tiene forma de altavoz, perdona mi ignorancia...


----------



## Meta (Feb 19, 2012)

Hola:

LS1 es un altavoz de PC y el otro un zumbador.
En el código de ASM escoges que vas a usar, el zumbador o el altavoz. En este ejemplo está predeterminado el zumbador que recuerde. No hace falta conectar el altavoz.

Si lo montas, funcionará a la primera.

Un slaudo.


----------



## kritter (Feb 19, 2012)

Meta dijo:


> Hola:
> 
> LS1 es un altavoz de PC y el otro un zumbador.
> En el código de ASM escoges que vas a usar, el zumbador o el altavoz. En este ejemplo está predeterminado el zumbador que recuerde. No hace falta conectar el altavoz.
> ...



Gracias Crack!!!

Ultima pregunta, que las salidas RB esten repetidas en el bus como se entiende? es decir, es tal cual? o hay una errata, porque veo que a pesar de estar conectadas al bus, hay puertas RB que no tienen nada conectado como salida....y en cambio otras , tienen bastantes cosas creando unos cuantos paralelos.

y el reloj de cuarzo de 4 MHZ aunque se omite sigue estando ahi con dos caps de 22pF, no?



el esquema difiere un poco del de mi libro, supongo que el mio es una edicion anterior


----------



## Meta (Feb 19, 2012)

Hola:

Sí. el cristal de cuarzo de 4 MHz y los condensadores de 22pF están prtesentes aunque no se muestre en el esquema.

Lo de los puertos no es una errata, si te refieres a que el mismo puerto está conectados dos cosas diferentes, el motivo es, que al tener poco pines se simplifica con truquitos de programación. Está explicado en el .asm, en el mismo puerto funciona como interruptor, cambia de estado se comporta como comunicación al LCD y así sucesivamente a una velocidad pasmosa. Está todo correcto y funciona a la primera, me he preguntado lo mismo hace tiempo.

El último libro es la 3ª edición.

Si lo montas, funciona a la primera, guardas en la EEPROM el tiempo que quieras del temprizador. Vale la pena.

Si te lías, puedes usar un NE555 que también funciona de maravilla.

Eso si, tengo intenciónd e adaptar el código del PIC16F84A al 16F88, otros lo harán directo al 16F628A. Funciona exactmente igual lo que usams PIC más modernos por si acaso el 16F84A lo dejen de fabricar como ocurre con los 16F876A/877A y ahora vinieron los sustitutos mejorados que son el 16F886/887. Microchip ha escogido que esos son los sustitutos, en cuanto al sustituto del F84A Microchip no ha dicho nada, se sigue fabricando y vendiendo. Muchos quieren que sea el 16F628A o el 16F88.

Más información aquí a partir de la página 71.

Descargar:
PDF 5.12 MB.
ZIP 3.19 MB.






Si lo vas ahcer, lo presentas por aquí, ejjee. Haré lo mismo.

Saludo.


----------



## kritter (Feb 20, 2012)

Olé subcompi,
información al poder.

De acuerdo Meta, tengo el layout casi terminado, mañana empiezo el montaje y te cuento...

Respecto al 16f28, era mi segunda opción en cuanto a pic, hay otro timer para insoladora circulando por ahi....de embedd lab, pero no he podido conseguir los 16f628 a tiempo, así que continuo con el del libro RA-MA.

También tengo controlado alguno con atmega 8, y otros que en vez de LCD usan displays (www.turbokeu.com) pero es mucho aparetejo....

Para esta aplicación el problema de la mayoria reside en que el tiempo esta en horas y minutos, y creo que para insolar podemos prescindir de las horas, y ajustar valores de minutos y segundos. 
A mi el ensamblador se me da fatal y no se como convertirlo a C para poder trastearlo.

Tengo que hacerme un tuto acelerado de ensamblador.


----------



## Meta (Feb 20, 2012)

Hola:

No está en horas y minutos, está en minutos y segundos que no es lo mismo y es así para insoladoras. El PIC16F84A funcionará a la primera. 

¿Por qué cambiar a otro PIC?

En mi caso porque el 16F88 es más moderno y cada vez es más aceptado, también que el 16F84A en cualquier momento se puede dejar de fabricar, por ahora resiste a hasta la saciedad y Microchip no tiene nigún tipo de dejarlo de fabricar sobre todoque se usa mucho para aprender y hay libros específicos para ello.

No te líes y primero montas el temporizador que cogerás experiencias y con ello soltura.

Un saludo.


----------



## kritter (Feb 21, 2012)

Desde luego tengo que terminar el proyecto si o si,

gracias por tus consejos y soporte, tienes razón, primero el 0 y luego el 1.

Te cuento en un par de dias.


----------



## Meta (Feb 21, 2012)

Entendido, cuanod me llegue a correos los LCD, haré también pruebas. Ahora con los Carnavales correo se ha parado.


----------



## kritter (Feb 25, 2012)

Meta dijo:


> Entendido, cuanod me llegue a correos los LCD, haré también pruebas. Ahora con los Carnavales correo se ha parado.




Ya esta montada, pero no me funciona correctamente
en la pantalla solo se ve la linea de caracteres de arrriba, pero sin letras, todos los pixels ocupados
no puedo ajustar tiempo y al darle a los botones ninguno me activa el relé

Tengo ke revisar ke okurre, 

Meta, los pines 11 y 12 del lcd van al aire como en el esquema???


----------



## Meta (Feb 25, 2012)

Buenas:

¿Lo estás haciendo con el PIC16F84A y el ejemplo que viene? Usa directamente su archivo .hex.

Si el LCD se ve como dices, es que no está configurado. Revisa cable por cable o móntalo de nuevo, a veces se resuelve así.

Saludo.


----------



## kritter (Feb 25, 2012)

lo hago tal cual tu dibujo....aunnke no entiendo que significan los puntos de colores que hay al lado de las patillas....es un codigo?

Lo he hecho y no me funciona, voy a seguir revisando...te informo kon lo ke sea


----------



## kritter (Feb 26, 2012)

joer, esto falla mas ke una eskopeta de feria, la situación esta asi:

Enciendo>>>La pantalla muestra la fila superior como una cadena de bloques , es decir, todo negro. la fila inferior no tiene nada.

Respecto a la config de la pantalla, lo he mirado unas cuantas veces.

Mis preguntas, dado que el esquemático no ayuda a concretar, son:

Para que ponemos las R3 y R4? como pull up? divisor de tension? que sentido tiene?

el programa que tengo que cargarle cual es? ( por si me he equivocado)

Tengo hecha la cerradura electronica del libro

aunque es practicamente el mismo esquematico, difiere en cuanto a ciertos componentes, no?

POR FAVOR explica el codigo de colores que aparece en los terminales de cada componente, porque los grises me dan a entender que eso no esta conectado, y que es rojo y azul?


Llevo un mareo ke la flipas, estoy por hacerla con el atmega 8....


Saludos Meta


----------



## Meta (Feb 26, 2012)

Hola:

R3 y R4 están ahó por como dices. Se relacionan con los pulsadores R5 y R6 ya que el código como expliqué arriba.



> *en el mismo puerto funciona como interruptor, cambia de estado se  comporta como comunicación al LCD y así sucesivamente a una velocidad  pasmosa.*



Los puntos rojos significan que está el positivo en ese momento, también conocido como 1. Los azules como 0 o como negativo o masa.

Lso grises significa que están desconectados, no se usan o si se usan que pueden ser apagado o encendido en ese momento. También se desactivan solos ni encendido ni apagado, sobre todo la parte LCD.

Un slaudo.


----------



## kritter (Feb 26, 2012)

a no ser, que sean pulsadores normalmente cerrados!

No he leido el programa, pero he hechado un vistazo a mi libro, y usa puertas totalmente distintas.....tb lleva el programa temporizador....

Tengo ke contraatacarle al pic





			
				kritter dijo:
			
		

> No he leido el programa, pero he hechado un vistazo a mi libro...




Porque tu link esta en hex no en asm, no por desprecio, jejejejje.


Pero vamos ke seran el mismo pero con puertas distintas


----------



## Meta (Feb 27, 2012)

Hola:

¿Lo lees?


```
;********************************** INT_Temporizador.asm ********************************
;
;    ===================================================================
;      Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"
;      E. Palacios, F. Remiro y L. López.            www.pic16f84a.com
;       Editorial Ra-Ma.  www.ra-ma.es
;    ===================================================================
;
; Programa de control para un temporizador digital de precisión. La programación del tiempo
; de temporización se realiza mediante dos pulsadores: "AJUSTE" y "ON/INCREM". Funcionamiento:
;     -    En estado de reposo la salida del temporizador está apagada y el pantalla aparece el
;        tiempo deseado para la próxima temporización.
;     - Si se pulsa "ON/INCREM" comienza la temporización.
;     - Cuando acaba la temporización pasa otra vez a reposo.
;     -    Si pulsa "AJUSTE" antes que haya acabado el tiempo de temporización actúa como pulsador
;        de paro: interrumpe la temporización, apaga la carga y pasa al estado de reposo.
;
; Para ajustar la temporización al tiempo deseado. 
;     -    Pulsa "AJUSTE" y ajusta el tiempo deseado mediante el pulsador "ON/INCREM".
;     -    Se vuelve a pulsar "AJUSTE" y pasa a modo de reposo.
;
; Al apagar el sistema debe conservar el tiempo de temporización deseado para la próxima vez
; que se encienda.
;
; ZONA DE DATOS **********************************************************************

    LIST        P=16F84A
    INCLUDE        <P16F84A.INC>
    __CONFIG    _CP_OFF &  _WDT_OFF & _PWRTE_ON & _XT_OSC

    CBLOCK  0x0C
    TiempoDeseado                ; El tiempo deseado de temporización.
    Tiempo                        ; Tiempo que resta de temporización.
    FlagsModos                    ; Guarda los flags con los diferentes
    ENDC                        ; modos de funcionamiento.

    ORG    0x2100                    ; Corresponde a la dirección 0 de la zona
                                ; EEPROM de datos. Aquí se va a guardar el
    DE    0x00                    ; tiempo de temporización deseado.

#DEFINE  F_Temporizador_ON        FlagsModos,2
#DEFINE  F_Temporizador_Ajuste    FlagsModos,1
#DEFINE  F_Temporizador_OFF        FlagsModos,0

#DEFINE  SalidaTemporizador     PORTB,1        ; Salida donde se conecta la carga.
#DEFINE  Zumbador                 PORTB,2        ; Salida donde se conecta el zumbador.
#DEFINE  AjustePulsador            PORTB,7        ; Los pulsadores están conectados a estas
#DEFINE  IncrementarPulsador    PORTB,6        ; líneas del Puerto B.

; ZONA DE CÓDIGOS ********************************************************************

    ORG     0
    goto    Inicio
    ORG    4
    goto    ServicioInterrupcion

Mensajes
    addwf    PCL,F
Mensaje_ON
    DT "   En MARCHA", 0x00
Mensaje_Ajuste
    DT "Tiempo  deseado:", 0x00
Mensaje_OFF
    DT "     PARADO", 0x00

; Instrucciones de inicialización. ------------------------------------------------------
;
Inicio
    call    LCD_Inicializa
    bsf        STATUS,RP0
    movlw    b'10000111'                    ; Prescaler de 256 asignado al TMR0.
    movwf    OPTION_REG
    bsf        AjustePulsador                ; Configurados como entradas.
    bsf        IncrementarPulsador
    bcf        SalidaTemporizador            ; Configurados como salidas.
    bcf        Zumbador
    bcf        STATUS,RP0
    clrw                                ; Lee la posición 0x00 de memoria EEPROM de datos
    call    EEPROM_LeeDato                ; donde se guarda el tiempo deseado de la última vez
    movwf    TiempoDeseado                ; que se ajustó.
    call    ModoTemporizador_OFF        ; Modo de funcionamiento inicial.
    movlw    b'10001000'                    ; Activa interrupciones RBI.
    movwf    INTCON
Principal
    goto    Principal

; Subrutina "ServicioInterrupcion" ------------------------------------------------------
;
; Detecta qué ha producido la interrupción y ejecuta la subrutina de atención correspondiente.

ServicioInterrupcion
    btfsc    INTCON,T0IF
    call    Temporizador
    btfss    INTCON,RBIF                    ; Si es una interrupción RBI lee los pulsadores.
    goto    FinInterrupcion
    btfss    AjustePulsador                ; ¿Está presionado el pulsador de "AJUSTE"?.
    call    CambiarModo                    ; Sí, pues salta a la subrutina correspondiente.
    btfsc    IncrementarPulsador            ; ¿Pulsado "ON/INCREM"?.
    goto    FinInterrupcion                ; No, pues salta al final y sale.
;
    call    Retardo_20ms                ; Espera que se estabilice el nivel de tensión.
    btfsc    IncrementarPulsador            ; Si es un rebote del pulsador "ON/INCREM" sale fuera.
    goto    FinInterrupcion
    btfsc    F_Temporizador_OFF            ; ¿Estaba en reposo cuando pulsó "ON/INCREM"?
    call    ModoTemporizador_ON            ; Sí, pues comienza la temporización.
    btfsc    F_Temporizador_Ajuste        ; ¿Estaba ajustando tiempo?
    call    IncrementarTiempoDeseado    ; Sí, pues pasa a incrementar el tiempo deseado.
FinInterrupcion
    bcf        INTCON,RBIF                    ; Limpia los flags de reconocimiento.
    bcf        INTCON,T0IF
    retfie

; Subrutinas "CambiarModo" y todas las de MODO de funcionamiento ------------------------
;
; Subrutina de atención a la interrupción producida al presionar el pulsador "AJUSTE" que 
; cambia el modo de funcionamiento.

; Hay identificados tres modos de funcionamiento que se diferencian mediante los tres flags:
;    A)    Modo "Temporizador_OFF" o estado inicial. A él se pasa en el estado inicial cada vez
;        que termina una temporización o cuando se aborta la temporización sin esperar a que
;        finalice. Reconocido por el flag F_Temporizador_OFF, bit 0 del registro FlagsModos.
;         una temporización  o cada vez que se aborta la temporización sin esperar a que finalice.
;    B)    Modo "Temporizador_Ajuste", donde se ajusta la temporización deseada cuando funcione
;        como temporizador. Reconocido por el flag F_Temporizador_Ajuste, bit 1 del FlagsModos.
;    C)    Modo "Temporizador_ON", la salida está activada mientras dure la temporización.
;        Reconocido por el flag F_Temporización_ON, que es el bit 2 del registro FlagsModos.
;
; El programa consigue que esté activado uno sólo de los flags anteriores.

; El contenido del registro (FlagsModos) diferencia los siguientes modos de funcionamiento:
; - (FlagsModos)=b'00000001'. Está en el modo "Temporizador_OFF", en reposo.
; - (FlagsModos)=b'00000010'. Está en el modo "Temporizador_Ajuste", ajustando tiempo deseado.
; - (FlagsModos)=b'00000100'. Está en el modo "Temporizador_ON", activa la carga y temporizador.
;
; Al pulsar "AJUSTE" pueden darse tres casos:
; - Si estaba en modo "Temporizador_OFF", pasa a modo "Temporizador_Ajuste".
; - Si estaba en modo "Temporizador_Ajuste", pasa a modo "Temporizador_OFF", pero antes salva
;   el tiempo de temporización deseado en la EEPROM de datos.       
; - Si estaba en modo "Temporizador_ON", pasa a modo "Temporizador_OFF". (Interrumpe la
;   temporización).

CambiarModo
    call    PitidoCorto                    ; Cada vez que pulsa origina un pitido. 
    btfsc    AjustePulsador                ; Si es un rebote sale fuera.
    goto    EsperaDejePulsar
    btfsc    F_Temporizador_OFF            ; ¿Está en reposo?
    goto    ModoTemporizador_Ajuste        ; Sí, pues pasa a ajustar la temporización.
    btfss    F_Temporizador_Ajuste        ; ¿Está ajustando?
    goto    ModoTemporizador_OFF        ; No, pues pasa a reposo.
                                        ; Sí, pues antes de pasar a reposo salva en la
    clrw                                ; posición 00h de memoria EEPROM de datos el tiempo 
    movwf    EEADR                        ; de temporización deseado. Se conserva aunque se
    movf    TiempoDeseado,W                ; apague la alimentación.
    call    EEPROM_EscribeDato
ModoTemporizador_OFF
    bcf        SalidaTemporizador            ; Apaga la carga y resetea tiempo deseado.
    call    Pitido
    movlw    b'00000001'                ; Actualiza el registro FlagsModos pasando al
    movwf    FlagsModos                ; modo inicial "Temporizador_OFF".
    bcf        INTCON,T0IE                ; Prohíbe las interrupciones del TMR0.
    movf    TiempoDeseado,W            ; Repone otra vez el tiempo que se desea para la 
    movwf    Tiempo                    ; próxima temporización.
    call    LCD_Borra                ; Borra la pantalla.
    movlw    Mensaje_OFF                ; En pantalla el mensaje correspondiente.
    goto    FinCambiarModo

ModoTemporizador_Ajuste
    bcf        SalidaTemporizador        ; Apaga la carga
    movlw    b'00000010'                ; Actualiza el registro FlagsModos pasando al
    movwf    FlagsModos                ; modo "Temporizador_Ajuste".
    clrf    Tiempo                    ; Resetea el tiempo.
    clrf    TiempoDeseado
    bcf        INTCON,T0IE                ; Prohíbe las interrupciones del TMR0.
    call    LCD_Borra
    movlw    Mensaje_Ajuste            ; En pantalla el mensaje correspondiente.
    goto    FinCambiarModo

ModoTemporizador_ON
    movf    TiempoDeseado,W            ; Si el tiempo deseado es cero pasa a modo
    btfsc    STATUS,Z                ; de trabajo "Temporizador_OFF".
    goto    ModoTemporizador_OFF
    movwf    Tiempo
    call    PitidoCorto
    movlw    b'00000100'                ; Actualiza el registro FlagsModos pasando al
    movwf    FlagsModos                ; modo "Temporizador_ON".
    movlw    TMR0_Carga50ms            ; Carga el TMR0.
    movwf    TMR0
    movlw    CARGA_1s                ; Y el registro cuyo decremento contará los
    movwf    Registro50ms            ; segundos.
    bsf        INTCON,T0IE                ; Autoriza las interrupciones de TMR0.
    call    LCD_Borra
    bsf        SalidaTemporizador        ; Enciende la carga.
    movlw    Mensaje_ON                ; En pantalla el mensaje correspondiente.
FinCambiarModo
    call    LCD_Mensaje
    call    VisualizaTiempo
EsperaDejePulsar
    btfss    AjustePulsador            ; Espera deje de pulsar.
    goto    EsperaDejePulsar
    return

; Subrutina "Temporizador" ----------------------------------------------------------------
;
; Esta subrutina va decrementando el tiempo de temporización y visualizándolo en la pantalla.
; Se ejecuta debido a la petición de interrupción del Timer 0 cada 50 ms exactos, comprobado
; experimentalmente con la ventana "Stopwatch" del simulador del MPLAB.

    CBLOCK
    Registro50ms                    ; Guarda los incrementos cada 50 ms.
    ENDC

TMR0_Carga50ms    EQU    d'256'-d'195'            ; Para conseguir la interrupción cada 50 ms.
CARGA_1s        EQU    d'20'            ; Leerá cada segundo (20 x 50ms = 1000 ms).    

Temporizador
    call    Retardo_50micros        ; Ajuste fino de 71 microsegundos para
    call    Retardo_20micros        ; ajustar a 50 milisegundos exactos.
    nop
      movlw    TMR0_Carga50ms            ; Carga el Timer0.
    movwf    TMR0
    decfsz    Registro50ms,F            ; Decrementa el contador.
    goto    FinTemporizador            ; No ha pasado 1 segundo y por tanto sale.
    movlw    CARGA_1s                ; Repone el contador nuevamente.
    movwf    Registro50ms
    btfss    F_Temporizador_ON        ; Si no está en modo "Temporizador_ON" sale
    goto    FinTemporizador            ; fuera.
    decfsz    Tiempo,F
    goto    VisualizaContador        ; Visualiza el tiempo restante.
    bcf        SalidaTemporizador        ; Apaga la salida
    call    VisualizaTiempo            ; Visualiza cero segundos en la pantalla.
    call    Pitido                    ; Tres pitidos indican final de la temporización.
    call    Retardo_500ms
    call    Pitido
    call    Retardo_500ms
    call    PitidoLargo
    call    Retardo_500ms
    call    ModoTemporizador_OFF    ; Acabó la temporización.
    goto    FinTemporizador
VisualizaContador
    call    VisualizaTiempo
FinTemporizador
    return

; Subrutina "VisualizaTiempo" -----------------------------------------------------------------
;
; Visualiza el registro Tiempo en formato "Minutos:Segundos". Así por ejemplo, si
; (Tiempo)=124 segundos en la segunda línea de la pantalla visualiza " 2:04", ya que 124
; segundos es igual a 2 minutos más 4 segundos.
;
VisualizaTiempo
    movlw    .5                        ; Para centrar visualización en la
    call    LCD_PosicionLinea2        ; segunda línea.
    movf    Tiempo,W                ; Convierte el tiempo deseado (y expresado sólo en
    call    MinutosSegundos            ; segundos) a minutos y segundos.
    movf    TemporizadorMinutos,W    ; Visualiza los minutos.
    call    BIN_a_BCD                ; Lo pasa a BCD.
    call    LCD_Byte
    movlw    ':'                        ; Visualiza dos puntos.
    call    LCD_Caracter
    movf    TemporizadorSegundos,W    ; Visualiza los segundos.
    call    BIN_a_BCD                ; Lo pasa a BCD.
    goto    LCD_ByteCompleto
    return

; Subrutina "MinutosSegundos" -----------------------------------------------------------
;
; Una cantidad expresada exclusivamente en segundos y contenida en el registro W es
; convertida a minutos y segundos. El resultado se guarda en dos posiciones de memoria
; llamadas TemporizadorMinutos y TemporizadorSegundos.
;
; El máximo número a convertir será el 255 que es el máximo valor que puede adquirir el
; número binario de entrada de 8 bits. (255 segundos = 4 minutos + 15 segundos)
;
; El procedimiento utilizado es mediante restas de 60 tal como se explica en el siguiente
; ejemplo que trata de la conversión del 124 segundos a minutos y segundos.
; 124 segundos = 2 minutos + 4 segundos. 
;
; Minutos        Segundos     ¿(Segundos)<60?
; -------        --------    ------------------------------------------------
;     0              124        NO. Resta 60 a (Segundos) e incrementa (Minutos).
;     1               64         NO. Resta 60 e (Segundos) e incrementa (Minutos).
;     2                4        Sí, se acabó. 
;
; Entrada:    En el registro W el número de segundos a convertir.
; Salidas:    En (TemporizadorMinutos) y (TemporizadorSegundos) el resultado.

    CBLOCK
    TemporizadorMinutos
    TemporizadorSegundos
    ENDC
;
MinutosSegundos
    movwf    TemporizadorSegundos    ; Carga el número de segundos a convertir.
    clrf    TemporizadorMinutos        ; Carga los registros con el resultado inicial.
Resta60
    movlw    .60                        ; Resta 60 en cada pasada.
    subwf    TemporizadorSegundos,W    ; (W)=(TemporizadorSegundos)-60.
    btfss    STATUS,C                ; ¿(W) positivo?, ¿(TemporizadorSegundos)>=60?.
    goto     FinMinutosSegundos        ; No, es menor de 60. Acabó.
    movwf    TemporizadorSegundos    ; Sí, por tanto, recupera lo que queda por restar.
    incf    TemporizadorMinutos,F    ; Incrementa los minutos.
    goto    Resta60                    ; Y vuelve a dar otra pasada.
FinMinutosSegundos
    return

; Subrutina "IncrementarTiempoDeseado" --------------------------------------------------
;
; Subrutina de atención a la interrupción por cambio de la línea RB6 a la cual se ha
; conectado el pulsador "INCREMENTAR".
; Estando en el modo "Temporizador_Ajustar" incrementa el valor del tiempo deseado
; expresado en segundos en intervalos de 5 segundos y hasta un máximo de 255 segundos.
;
SALTO_INCR    EQU    .5

IncrementarTiempoDeseado
    call    PitidoCorto                ; Cada vez que pulsa se oye un pitido.
    movlw    SALTO_INCR                ; Incrementa el tiempo deseado de temporización
    addwf    Tiempo,F                ; saltos de SALTO_INCR segundos.
    btfsc    STATUS,C                ; Si pasa del valor máximo lo inicializa.
    clrf    Tiempo
    call    VisualizaTiempo            ; Visualiza mientras espera que deje de pulsar.
    call    Retardo_200ms
    btfss    IncrementarPulsador        ; Mientras permanezca pulsado,
    goto    IncrementarTiempoDeseado ; incrementa el dígito.
    movf    Tiempo,W                ; Actualiza el tiempo deseado.
    movwf    TiempoDeseado            ; Este es el tiempo deseado.
    return
    
; Subrutinas "PitidoLargo", "Pitido" y "PitidoCorto" -------------------------------------
;
PitidoLargo
    bsf        Zumbador
    call    Retardo_500ms
Pitido
    bsf        Zumbador
    call    Retardo_200ms
PitidoCorto
    bsf        Zumbador
    call    Retardo_20ms
    bcf        Zumbador
    return
;
    INCLUDE  <RETARDOS.INC>
    INCLUDE  <BIN_BCD.INC>
    INCLUDE  <LCD_4BIT.INC>
    INCLUDE  <LCD_MENS.INC>
    INCLUDE  <EEPROM.INC>
    END

;    ===================================================================
;      Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"
;      E. Palacios, F. Remiro y L. López.        www.pic16f84a.com
;       Editorial Ra-Ma.  www.ra-ma.es
;    ===================================================================
```

Un cordial saludo.


----------



## kritter (Feb 27, 2012)

Disculpa meta, 
siento haberte hinchado a preguntas, ojalá algun dia pueda yo contestarlas y aportar respuestas en este foro, de momento estoy en el inicio de mi desarrollo.

Gracias por el code voy a revisarlo pero de momento mi problema persiste. poniendo el codigo hex tal cual cuando enchufo se me ve la pantalla negra, la linea superior.

desconozco si los pulsadores tienen que ser normalmente cerrados o normalmente abiertos, he probado puenteando los abiertos para ver si cambiaba su comportamiento y no pasa nada.

el zumbador si que funciona cuando hago pulsaciones pero nunca puedo activar la carga(como tampoco veo nada en la pantalla...)

la pantalla la he conectado correctamente, los dos primeros pines son 15 y 16, no se conectan, los siguientes 6 si se conectan para:
1-gnd
2-5V
3-anclado al variable de un pot de 10k para regular el brillo
En realidad las tres las conecto con el pot, masa, vdd y ajuste de brillo


4>>A pin 17 PIC RA0
5.gnd
6 >>pin 1 del PIC RA2


7,8,9,10 no se conectan

11>>RB4 pin 10 del pic
12>> RB5 pin 11 del pic
13>> RB6 pin 12 del pic
14>>RB7 pin 13 del pic

En el pic:
1 RA2 se conecta a 6 de LCD
2 RA3 no se conecta
3 RA4/TOCKI no se conecta
4 MCLR conectado a dos resistencias(100ohm y pulsador en serie y10K y VDD en serie)
5GND
6RB0/int no se conecta
7RB1 a CARGA(relé 12 V) 
8RB2 a zumbador 6V
9RB3 no se conecta( no voy a poner altavoz, lo he probado en board y da mucho ruido)
10RB4 pin 11 LCD
11RB5 pin 12 LCD
12RB6 pin13 LCD/R de 10K y VDD serie/R de 330 y pulsador serie
13RB7 pin14 LCD/R de 10K y VDD serie/R de 330 y pulsador serie
14 a VDD
15 a Xtal 4MHZ(con su cap de 22micros
15 a Xtal 4MHZ
17 RA0 a pin 4 LCD
18 RA1 no se conecta


Lo he comprobado todo y revisado, cortos etc. no entiendo que puede estar pasando, porke en principio el fallo parece solo en el lcd, porque sin querer he activado la carga desde uno de los pulsadores(no se como) y ha estado durante unos segundos y luego ha hecho 3 zumbidos como alarma de paro, por lo que creo que el programa esta correcto.

Aunque en mi humilde opinion de novato que ignora muchos conocimientos, pienso que puede que el problema esté en el refresco de la imagen, solo asi entenderia que se viese toda la linea en negro, lo se porque estuve intentando montar la insoladora con este proyecto:

http://www.turbokeu.com/myprojects/countdown3.htm

tenia ese problema de refresco con los displays por una metida de gamba mia con los transistores, luego el propio autor aclaraba que los mandos de los pulsadores, funcionaban raro debido a los tiempos de espera, 

Si quieres te envio al mail una captura de mi esquematico y del pcb.(privado)

Muchas Gracias por tu atencion.

Salud!!!


----------



## Meta (Feb 27, 2012)

Hola de nuevo:

El programa está bien. Efectivamente, son tres pitidos al acabar de contar. El LCD cámbialo por otro por probar, quizás no lo tengas bien. La pantalla como aparece la primera línea todo negro y abajo nada, significa que no está configurado, es como si lo conectaras sin PIC.







Pulsadores son normalmente abierto.

Un saludo.


----------



## kritter (Feb 28, 2012)

Justo estaba pensando lo de la pantalla, pero tambien he pensado en si he quemado el pic...

aunque el zumbador zumba cuando aprieto los botones...no se como comprobarlo, intentaré usar uno que sepa que funciona ademas de la pantalla....

Gracias por la ayuda


----------



## kritter (Mar 14, 2012)

Bueno Meta, 

Al final me llegaron unas pantallas LCD de Futurlec ....(tiene buenos precios pero si pueden te encaloman cosas sin pedirlo, y por supuesto te las cobran, ademas del inconveniente de la aduana que me ha tenido esperando semana y media)...y bueno, era justo y simplemente eso, la pantalla LCD esta petada, no lo he probado en tu esquema, hice uno nuevo a partir de la edición antigua del libro, que solo cuenta con dos botones, es decir, no tiene el reset, omite algunas resistencias y tiene las puertas asignadas de otra forma. Pero es lo mismo, lo he probado en Board y funcionaba con las nuevas LCD.

Luego he probado ahi la pantalla vieja y seguia igual, solo saca la barra negra de arriba, como si no le llegara info del PIC.

Ademas, los PIC que usaba antes apenas se les lee las letras que tienen escritas indicando su modelo, lo cual me hace sospechar ke tuvo algun rekalentón y perecieron....

Debo de añadir que en el libro viejo el programa en .asm no se compila bien por algun motivo, incluso desde un cd original ocurre esto, aunque su version compilada en .hex si que es funcional. Subiré el esquemático en cuanto pueda.

Ahora, solo me queda decidir la forma de alimentarlo, si con trafo externo o trafo interno, porque ya tengo la placa de la fase de alimentación y relé de 12V pero ocupan mucho espacio y me gustaría minimizarlo....

...me imagino que habrá alguna forma de evitar poner relé con otro PIC u otro programa.

De todas formas, GRACIAS POR TODO EL SOPORTE Y APOYO, ahora me voy 3 meses a Polonia y veré si alli pruebo con tu esquema, aunque lo veo complicado, no tengo programador....mi eclipse se ha escacharrao....


----------



## Meta (Mar 15, 2012)

Hola:

El LCD puedes comprarlo por Bilbao y lo traen si problemas.

LCD verde

LCD azul

¿Qué te han puesto que no has pedido y encima te cobran?

Es bueno hacerlo notificar a ellos que no estás de acuerdo con el trato, con el tiempo se lo pensarán mejor si la gente hace estar reclamaciones.

El esquema funciona bien, me funciona y hasta lo probaré con PIC16F84A, subiré un vídeo para que te guedes tranquilo.

Que tengas buen viaje en Polonia.

PD: _Con el tiempo, en algún momento encerrado en una casa ta aburrirás y te meterás por Internet, puedes que pases por aquí desde Polonia. Es bueno que tengas el grabador de PIC como el TE20x o el TE20-SE por menos de 20€, funciona a la primera. _


----------



## Meta (Mar 17, 2012)

Hola de nuevo.

Me pasaba lo mismo que a ti, volví a montarlo desde cero y con tranquilidad.

En este ejemplo ya es un módulo montado.






Más adelante te monto el que hice el temporizador de prueba en la protoboard.


----------



## jhorevil (Jun 24, 2012)

Meta dijo:


> Hola:
> 
> ¿Lo lees?
> 
> Un cordial saludo.



soy nuevo en esto de la programacion...quiciera me pudieran ayudar e tratado de copilar este ejercicio en el mplab pero me da muchos errores me dice que no encuentra unas librerias o al asi.



estos son los errores:

```
Clean: Deleting intermediary and output files.
Clean: Done.
Executing: "C:\Program Files (x86)\Microchip\MPASM Suite\MPAsmWin.exe" /q /p16F84A "INT_Temporizador.asm" /l"INT_Temporizador.lst" /e"INT_Temporizador.err"
Warning[215] C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 27 : Processor superseded by command line.  Verify processor symbol.
Message[301] C:\PROGRAM FILES (X86)\MICROCHIP\MPASM SUITE\P16F88.INC 40 : MESSAGE: (Processor-header file mismatch.  Verify selected processor.)
Error[108]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 29 : Illegal character (,)
Error[108]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 30 : Illegal character (,)
Error[118]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 30 : Overwriting previous address contents (2007)
Error[118]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 30 : Overwriting previous address contents (2007)
Error[113]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 79 : Symbol not previously defined (LCD_Inicializa)
Message[302] C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 82 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Message[302] C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 84 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Error[113]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 92 : Symbol not previously defined (EEPROM_LeeDato)
Error[113]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 95 : Symbol not previously defined (EEPROM_LeeDato)
Error[113]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 117 : Symbol not previously defined (Retardo_20ms)
Message[302] C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 168 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Error[113]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 170 : Symbol not previously defined (EEPROM_EscribeDato)
Message[302] C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 171 : Register in operand not in bank 0.  Ensure that bank bits are correct.
Error[113]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 173 : Symbol not previously defined (EEPROM_EscribeDato)
Error[113]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 184 : Symbol not previously defined (LCD_Borra)
Error[113]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 197 : Symbol not previously defined (LCD_Borra)
Error[113]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 221 : Symbol not previously defined (LCD_Borra)
Error[113]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 225 : Symbol not previously defined (LCD_Mensaje)
Error[113]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 246 : Symbol not previously defined (Retardo_50micros)
Error[113]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 247 : Symbol not previously defined (Retardo_20micros)
Error[113]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 272 : Symbol not previously defined (Retardo_500ms)
Error[113]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 274 : Symbol not previously defined (Retardo_500ms)
Error[113]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 276 : Symbol not previously defined (Retardo_500ms)
Error[113]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 292 : Symbol not previously defined (LCD_PosicionLinea2)
Error[113]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 299 : Symbol not previously defined (BIN_a_BCD)
Error[113]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 300 : Symbol not previously defined (LCD_Byte)
Error[113]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 302 : Symbol not previously defined (LCD_Caracter)
Error[113]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 304 : Symbol not previously defined (BIN_a_BCD)
Error[113]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 305 : Symbol not previously defined (LCD_ByteCompleto)
Error[113]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 357 : Symbol not previously defined (Retardo_200ms)
Error[113]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 370 : Symbol not previously defined (Retardo_500ms)
Error[113]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 373 : Symbol not previously defined (Retardo_200ms)
Error[113]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 376 : Symbol not previously defined (Retardo_20ms)
Error[105]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 380 : Cannot open file (Include File "RETARDOS.INC" not found)
Error[105]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 381 : Cannot open file (Include File "BIN_BCD.INC" not found)
Error[105]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 382 : Cannot open file (Include File "LCD_4BIT.INC" not found)
Error[105]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 383 : Cannot open file (Include File "LCD_MENS.INC" not found)
Error[105]   C:\PIC\16F84A\INT_TEMPORIZADOR.ASM 384 : Cannot open file (Include File "EEPROM.INC" not found)
Halting build on first failure as requested.
BUILD FAILED: Sun Jun 24 00:50:41 2012
```


----------



## Meta (Jun 24, 2012)

Porque faltan las librerías que no incluí.
INCLUDE  <RETARDOS.INC>     INCLUDE  <BIN_BCD.INC>     INCLUDE  <LCD_4BIT.INC>     INCLUDE  <LCD_MENS.INC>     INCLUDE  <EEPROM.INC>


----------



## jhorevil (Jun 28, 2012)

Meta dijo:


> Porque faltan las librerías que no incluí.
> INCLUDE  <RETARDOS.INC>     INCLUDE  <BIN_BCD.INC>     INCLUDE  <LCD_4BIT.INC>     INCLUDE  <LCD_MENS.INC>     INCLUDE  <EEPROM.INC>



gracias Meta: ya encontré las librerías,me  podrías decir como cambiar los minutos solo me cuenta hasta 4:15 (minutos/seg) y vuelve a cero quisiera aumentarle el rango en donde podría modificar eso.


----------



## Meta (Jun 28, 2012)

Ahora mismo no puedo porque no lo tengo en este PC, si no en otro y no puedo acceder hasta que compre una conmutada nueva.

Lo he logrado hasta los 99:99.

Saludo.


----------



## jhorevil (Jun 28, 2012)

Meta dijo:


> Ahora mismo no puedo porque no lo tengo en este PC, si no en otro y no puedo acceder hasta que compre una conmutada nueva.
> 
> Lo he logrado hasta los 99:99.
> 
> Saludo.



uy te agradecería me colaboraras con eso, es muy urgente para mi, tengo que poner a contabilizar unos equipos  pero necesito que se apaguen en cierto tiempo...meta agradeceria mucho tu apoyo.


----------



## Meta (Jun 29, 2012)

Colaborar en eso significa ir  a comprar una conmutada, buscar donde lo tengo, comprobarlo y más cosas que ahora no estoy en la labor. Se que en este foro lo he subido, lo que no recuerdo el tema.


----------



## jhorevil (Jun 29, 2012)

Meta dijo:


> Colaborar en eso significa ir  a comprar una conmutada, buscar donde lo tengo, comprobarlo y más cosas que ahora no estoy en la labor. Se que en este foro lo he subido, lo que no recuerdo el tema.



 bueno de todas maneras muchas gracias.


----------



## alex26 (Jul 18, 2014)

Hola @mikeekim, quisiera saber por que no puedo generar el archivo hex del temporizador, que es lo que estoy haciendo mal, adjunto la imagen con los errores de antemano gracias...


----------



## D@rkbytes (Jul 18, 2014)

_El último mensaje de mkeekim_ fue el 31/03/2012 y tal vez no te responda.

Pero para poder compilar el programa del post#1, elimina o comenta las primeras 8 definiciones dejando únicamente las definiciones desde *DEFINE OSC 4* en adelante.

En vez de las definiciones eliminadas, agrega esta palabra de configuración:
*@ Device XT_OSC, PWRT_ON, BOD_OFF, LVP_OFF*

Con eso ya lo debes poder compilar.

Suerte.


----------



## alex26 (Jul 19, 2014)

Gracias por responder D@rkbytes, se ve que mikeekim no ingresa hace mucho...quería aprovechar para decirte si has armado alguna vez este temporizador en el protoboard, porque mikeekim se queja en el armado  no le funcionaba; pero en la simulación si  trabaja correctamente.

Espero me des una respuesta pronto, ya que eres de gran ayuda; siempre solucionando problemas...


----------



## D@rkbytes (Jul 19, 2014)

alex26 dijo:


> Gracias por responder D@rkbytes, se ve que mikeekim no ingresa hace mucho...quería aprovechar para decirte si has armado alguna vez este temporizador en el protoboard, porque mikeekim se queja en el armado  no le funcionaba; pero en la simulación si  trabaja correctamente.
> 
> Espero me des una respuesta pronto, ya que eres de gran ayuda; siempre solucionando problemas...


Nop, la verdad nunca he armado ese proyecto, pero viendo el esquema, no se ve complicado.
Móntalo sobre un protoboard para que hagas pruebas de su funcionamiento.


----------



## alex26 (Ago 12, 2014)

D@rkbytes dijo:


> Nop, la verdad nunca he armado ese proyecto, pero viendo el esquema, no se ve complicado.
> Móntalo sobre un protoboard para que hagas pruebas de su funcionamiento.



Hola D@rkbytes estuve simulando el código de la insoladora, cuando le doy el boton star me sale el mensaje pause, es como que hubiera presionado  el boton  pause, yo quiero que corra como debe ser cuando se presiona star decrementar el tiempo y no pasar por pause para que recien corra el temporizado, a ver si me das una mano de ante mano gracias por la ayuda que me puedas brindar.


----------



## D@rkbytes (Ago 12, 2014)

alex26 dijo:


> Hola D@rkbytes estuve simulando el código de la insoladora, cuando le doy el botón start me sale el mensaje pause, es como que hubiera presionado  el botón  pause, yo quiero que corra como debe ser cuando se presiona start decrementar el tiempo y no pasar por pause para que recién corra el temporizado.
> A ver si me das una mano.
> De ante mano gracias por la ayuda que me puedas brindar.


Como te había mencionado anteriormente, no he probado ese circuito pero vi que tiene algunos problemas.
Faltan colocar resistencias pull-down en los pines de los pulsadores del puerto A.
El código tiene muchas redundancias y le falta mejorar bastante.

Pero mira, le hice algunos cambios al esquema y también al código.
Espero que con los cambios realizados ya te funcione.

Suerte.


----------



## alex26 (Ago 14, 2014)

D@rkbytes dijo:


> Como te había mencionado anteriormente, no he probado ese circuito pero vi que tiene algunos problemas.
> Faltan colocar resistencias pull-down en los pines de los pulsadores del puerto A.
> El código tiene muchas redundancias y le falta mejorar bastante.
> 
> ...



Gracias D@rkbytes, te agradezco solucionaste mi problema...


----------



## alex26 (Ago 27, 2014)

alex26 dijo:


> Gracias D@rkbytes, te agradezco solucionaste mi problema...



Hola estimado amigo aquí de nuevo incomodando un poco, migre todo el codigo a un pic mas grande como es el pic 16f876a, necesitaba mas puertos para activar otras cosas mas... al compilarlo todo normal carga el el hex generado sale el mensaje, pero cuando presiono el boton  para desplazar de digito se queda ahi estático y solo el botón que suma el digito funciona, aqui te dejo adjunto  la simulacion, te dejo un link de como ahorrar pines en un pic 16f628a el problemas es que no logre compilarlo, espero me ayudes...


----------



## D@rkbytes (Ago 27, 2014)

alex26 dijo:


> Hola estimado amigo, aquí de nuevo incomodando un poco.
> Migré todo el código a un pic mas grande como es el pic16f876a.
> Necesitaba mas puertos para activar otras cosas más.
> Al compilarlo todo normal, carga el el hex generado, sale el mensaje, pero cuando presiono el botón  para desplazar de dígito se queda ahí estático y sólo el botón que suma el dígito funciona.


Para usar ese PIC, ahora tienes que reemplazar el registro CMCON por el registro ADCON1.
Deja el mismo valor (7), eso hará funcionar los puertos con ADC como entradas digitales.

También debes fijarte el lugar en dónde van los pulsadores.
El pulsador para cambiar de dígito va en el pin RA3 y tú lo pusiste en RA5


alex26 dijo:


> te dejo un link de como ahorrar pines en un pic16f628a.
> El problemas es que no logré compilarlo, espero me ayudes.


Olvidaste poner el link.

Suerte.


----------



## alex26 (Ago 28, 2014)

D@rkbytes dijo:


> Para usar ese PIC, ahora tienes que reemplazar el registro CMCON por el registro ADCON1.
> Deja el mismo valor (7), eso hará funcionar los puertos con ADC como entradas digitales.
> 
> También debes fijarte el lugar en dónde van los pulsadores.
> ...



Una vez mas... gracias D@rkbytes, este es el
link http://www.picbasic.co.uk/forum/showthread.php?t=18972
esto es basado en la idea de myke predko y consta  en hacer un interface con shift register  para el display lcd y ahorrar pines en el pic, a ver si logras compilarlo y hacerlo correr, te adjunto imagen del Ckto mas simulación con los archivos pbp.

Logre generar el archivo hex para hacerlo correr a 8mhz, pero en el display lcd no sale nada.

espero alguna respuesta...


----------



## D@rkbytes (Ago 28, 2014)

alex26 dijo:


> Una vez más... Gracias D@rkbytes.
> Este es el link.
> http://www.picbasic.co.uk/forum/showthread.php?t=18972
> Esto es basado en la idea de myke predko y consta  en hacer un interface con shift register  para el display lcd y ahorrar pines en el pic.
> ...


Para que ese programa funcione se necesita modificar la librería pbppic14.lib
Esta librería se encuentra en la carpeta de instalación de PICBasic Pro.

Dentro del archivo que adjunto viene la librería modificada para que funcione el "HighJack" que se requiere.

Ahora lo que tienes que hacer es lo siguiente:
Reemplaza la librería original pbppic14.lib por la librería adjunta que modifiqué.
Este reemplazo y modificación no afecta a los programas que usen la instrucción LCDOUT
Tan sólo será usado el HighJack de la librería con los programas que usen el archivo One_Wire_74HC595.bas o LCD_AnyPin.pbp que es el archivo original de donde parte este proyecto de Darrel Taylor.
Éste archivo hace un redireccionamiento de la instrucción LCDOUT hacia LCDsend.

Recuerda que el PIC16F628A no puede trabajar a 8MHz con el oscilador interno, tan sólo a 4MHz máximo.

Bien, adjunto el proyecto funcionando con la librería modificada y la simulación para hacer funcionar una pantalla LCD 16x2 con un solo cable. (One-Wire) y un 74HC595.

Suerte.


----------



## alex26 (Ago 30, 2014)

D@rkbytes dijo:


> Para que ese programa funcione se necesita modificar la librería pbppic14.lib
> Esta librería se encuentra en la carpeta de instalación de PICBasic Pro.
> 
> Dentro del archivo que adjunto viene la librería modificada para que funcione el "HighJack" que se requiere.
> ...






muchas gracias D@rkbytes, cualquier inquietud volveré a consultarte


----------



## Arsenic (Abr 24, 2015)

Hola, no sé si siguen interesados en esto, pero estoy trabajando en una y necesito ayuda. Estaba haciendo una pero el código en C me tira un error en el compilador CSS: "Error 71 Out of ROM. A segment of the program is too large."

El código es el siguiente:


```
#include <16F628A.h>

#FUSES WDT                      //Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES PUT                      //Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT                 //Reset when brownout detected
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection

#use delay(clock=4000000,RESTART_WDT)
#use I2C(master, sda=PIN_B3, scl=PIN_A4)

#rom 0x2100={0,185,1}

#include <LCD.C>

// Pinout
#byte PORTA=5
#bit CARA_SUPERIOR=PORTA.0
#bit CARA_INFERIOR=PORTA.1
#bit BUZZER=PORTA.2
#bit SW_ARRIBA=PORTA.7
#bit SW_ABAJO=PORTA.6
#bit SW_INTRO=PORTA.3

// Mensajes
#define STOP 0
#define PAUSA 1
#define MUESTRACARAS 2
#define MSG_MINUTOS 3
#define MSG_SEGUNDOS 4

// Control estado entrada datos
#define ENTRADAMINUTOS 1
#define ENTRADASEGUNDOS 2

// Control tecla pulsada
#define ARRIBA 1
#define ABAJO 2
#define INTRO 3

const char car[32] =   {17,17,0,0,0,0,17,17,31,31,0,0,0,0,31,31,31,31,0,0,0,0,17,17,17,17,0,0,0,0,31,31};

int8 OpcionMenu=1, ConfCaras, HayMensaje;
int1 Estado=0, EnPausa=0;
int16 Tiempo, Ticks, TiempoPredefinido;
int8 MinutosPre, SegundosPre,TicksMensaje, EstadoEntradaTiempo;



void CargaConfiguracion() {
   TiempoPredefinido = ((int16)read_eeprom(0) * (int16)256) + (int16)read_eeprom(1);
   MinutosPre=TiempoPredefinido/60;
   SegundosPre=TiempoPredefinido - MinutosPre*60;
   ConfCaras=read_eeprom(2);
   TicksMensaje=0;
   Tiempo=TiempoPredefinido;
   EstadoEntradaTiempo=0;
   CARA_INFERIOR=0;
   CARA_SUPERIOR=0;
   HayMensaje=0;
}

void GrabaConfigEeprom() {
   Write_Eeprom (0,TiempoPredefinido >> 8); // graba el byte alto
   Write_eeprom (1,TiempoPredefinido & 0xFF); // graba el byte bajo
   Write_Eeprom (2,ConfCaras);
}

void LCD_DefineCaracter () {
   char i;
   lcd_send_byte (0,0x40);
     for (i=0;i<32;i++) {
      lcd_send_byte (1,car[i]);
   }
}


void menu() {
   lcd_gotoxy(1,2);
   switch (OpcionMenu) {
      case 1:
         if (Estado || EnPausa)
            lcd_putc ("     Parar      ");
          else
            lcd_putc ("    Arrancar    ");
         break;
      case 2:
         lcd_putc ("Cfg tiempo      ");
         break;
      case 3:
         lcd_putc ("Cfg caras       ");
         break;
      case 4:
         if (EnPausa)
            lcd_putc ("   Continuar    ");
          else
            lcd_putc ("     Pausar     ");
         break;
   }
}

void Pitido (int16 Duracion) {
   Duracion*=3;
   while (Duracion>0) {
      BUZZER=1;
      delay_us(162);
      Duracion--;
      BUZZER=0;
      delay_us(162);
   }
}

void PitidoGrave (int16 Duracion) {
Duracion/=2;
   while (Duracion>0) {
      BUZZER=1;
      delay_us(1000);
      Duracion--;
      BUZZER=0;
      delay_us(1000);
   }
}

void ArrancaInsolado() {
   Estado=1; // la encendemos
   EnPausa=0;
   CARA_SUPERIOR=(ConfCaras<3);
   CARA_INFERIOR=(ConfCaras!=2);
   Ticks = Tiempo * 2;
   set_timer1(3036);  // hasta 65536 son 62500 ciclos
   // 62500 con prescaler de 8 y a 1MHz es medio segundo
   // 62500*8/1000000=0,5s.
   enable_interrupts(GLOBAL);
   OpcionMenu=4;
}

void FinalizaInsolado(int Modo) {
char i;
   Estado=0; // la paramos
   CARA_SUPERIOR=0;
   CARA_INFERIOR=0;
   disable_interrupts(GLOBAL);
   if (Modo==STOP){
      Tiempo=TiempoPredefinido;
      EnPausa=0;
      if (OpcionMenu==4) // si está parado no puede entrar en la opción 4
         OpcionMenu=1;
   }
    else {
      EnPausa=1;
      HayMensaje=PAUSA;
    }
   for (i=0;i<3;i++) {
      Pitido (100);
      PitidoGrave (200);
   }
}

void MuestraTiempo() {
   int Minutos, Segundos;


   if (EstadoEntradaTiempo) {
      lcd_gotoxy(12,2);
      Minutos=MinutosPre;
      Segundos=SegundosPre;
   } else {
      lcd_gotoxy(12,1);
      Minutos = Tiempo / 60;
      Segundos = Tiempo - Minutos*60;
   }

   printf (lcd_putc,"%2u:%02u",Minutos,Segundos);
}

void MuestraEstado() {
char i;
   lcd_gotoxy(1,1);
   switch (HayMensaje) {
      case 0: // no hay mensaje
         for (i=0;i<11;i++)
            printf (lcd_putc,"%c",ConfCaras*Estado);
         break;
      case MUESTRACARAS:
         lcd_gotoxy(12,2);
         for (i=6;i<11;i++)
            printf (lcd_putc,"%c",ConfCaras);
         break;
      case PAUSA:
         printf(lcd_putc,"  Pausado   ");
         break;
      case MSG_MINUTOS:
         printf(lcd_putc,"Minutos....");
            lcd_send_byte (0,0x0F);
         break;
      case MSG_SEGUNDOS:
         printf(lcd_putc,"Segundos...");
         //lcd_gotoxy(15,1);
         break;

   }
   if (HayMensaje)
      TicksMensaje++;
      if (TicksMensaje==4) {
         HayMensaje=0;
         TicksMensaje=0;
      }
   MuestraTiempo ();
}


void EjecutaOpcion() {
   switch (OpcionMenu) {
      case 1:
         if (Estado || EnPausa)  // estaba encendida
               FinalizaInsolado(STOP);
          else  // estaba apagada
               ArrancaInsolado();
         break;
      case 2:
         EstadoEntradaTiempo++;
         HayMensaje=MSG_MINUTOS;
//         lcd_send_byte(0,0xC); // parpadeo
//         lcd_gotoxy(1,12);
         break;
      case 3:
         ConfCaras++;
         if (ConfCaras==4)
            ConfCaras=1;
         if (Estado) {
            CARA_SUPERIOR=(ConfCaras<3);
            CARA_INFERIOR=(ConfCaras!=2);
         }
         lcd_gotoxy(1,1);
         HayMensaje=MUESTRACARAS;
         break;
      case 4:
         if (EnPausa)
            ArrancaInsolado();
          else
            FinalizaInsolado  (PAUSA);
         break;
   }
}



#int_TIMER1
TIMER1_isr()
{
   set_timer1(3036);  // hasta 65536 son 62500 ciclos
   // 62500 con prescaler de 8 y a 1MHz es medio segundo
   // 62500*8/1000000=0,5s.
   Ticks--;
   if (!Ticks) // se acabó
      FinalizaInsolado(STOP);
   else {
      Tiempo=Ticks/2;
   }
   menu();
   MuestraEstado();
}

void ConfiguraTiempo(int Modo) {
   switch (EstadoEntradaTiempo) {
      case ENTRADAMINUTOS:
         switch (Modo) {
            case ARRIBA:
               MinutosPre++;
               if (MinutosPre>99)
                  MinutosPre=0;
               break;
            case ABAJO:
               if (MinutosPre==0)
                  MinutosPre=100;
               MinutosPre--;
               break;
            case INTRO:
               EstadoEntradaTiempo++;
               HayMensaje=MSG_SEGUNDOS;
               TicksMensaje=0;
         };
         break;
     case ENTRADASEGUNDOS:
         switch (Modo) {
            case ARRIBA:
               SegundosPre++;
               if (SegundosPre>59)
                  SegundosPre=0;
               break;
            case ABAJO:
               if (SegundosPre==0)
                  SegundosPre=60;
               SegundosPre--;
               break;
            case INTRO:
               EstadoEntradaTiempo=0;
               TiempoPredefinido = (int16)MinutosPre*(int16)60+(int16)SegundosPre;
               HayMensaje=0;
               if (!Estado && !EnPausa)
                  Tiempo=TiempoPredefinido;
               GrabaConfigEeprom();
         }
   }
//MuestraEstado();
MuestraTiempo();
}

void main()
{
   set_tris_a(0b11001000);
   setup_timer_0(RTCC_INTERNAL);setup_wdt(WDT_2304MS);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   lcd_init();
   enable_interrupts(INT_TIMER1);
   disable_interrupts (GLOBAL);
   setup_oscillator(OSC_4MHZ);

   printf(lcd_putc,"Temporizador v.1\n");
   lcd_putc("Nocturno -- 2007");
   LCD_DefineCaracter ();
   CargaConfiguracion();
   delay_ms(500);
   pitido(50);
   CARA_INFERIOR=0;
   CARA_SUPERIOR=0;
   menu();
   MuestraEstado();

   while(1){

//   pitido(50);
      restart_wdt();
      if (!SW_ARRIBA) {// sube en el menú
         pitido(20); // antirrebotes
         while (!SW_ARRIBA); // esperamos que suelte tecla
         if (EstadoEntradaTiempo)
            ConfiguraTiempo(ARRIBA);
          else {
            OpcionMenu--;
            if (!OpcionMenu)
               OpcionMenu=(3+Estado+EnPausa);
            if (OpcionMenu==3)
               HayMensaje=MUESTRACARAS;
              else
               HayMensaje=0;
            TicksMensaje=0;
            menu();
            MuestraEstado();
          }
      }

      if (!SW_ABAJO) {// baja en el menú
         pitido(20); // antirrebotes
         while (!SW_ABAJO); // esperamos que suelte tecla
         if (EstadoEntradaTiempo)
            ConfiguraTiempo(ABAJO);
          else {
            OpcionMenu++;
            if (OpcionMenu==(4+Estado+EnPausa))
               OpcionMenu=1;
            if (OpcionMenu==3)
               HayMensaje=MUESTRACARAS;
              else
               HayMensaje=0;
            TicksMensaje=0;
            menu();
            MuestraEstado();
          }
      }
      if (!SW_INTRO) {// acepta opción
         pitido(20); // antirrebotes
         while (!SW_INTRO); // esperamos que suelte tecla
         if (EstadoEntradaTiempo) {
            ConfiguraTiempo(INTRO);
           } else {
            HayMensaje=0;
            TicksMensaje=0;
            EjecutaOpcion();
           }
         menu();
         MuestraEstado();
      }

   }
}
```


----------



## D@rkbytes (Abr 24, 2015)

Eso quiere decir que ya no hay espacio para el programa en la ROM.
Trata de optimizar el código o cambia de PIC, por ejemplo, al PIC16F648A que tiene el doble de ROM.


----------



## leemkapoh (May 2, 2018)

Hola a todos,
Aquí hay un proyecto de proteus y mikroC, si usted quiere construir Ultra Violeta PCB entonces necesitas contador aquí es el temporizador, usted encontrará también código fuente en mikroC.

Disfrute de su tiempo.

Gracias
Kapoh.


----------

