¡Hola!
ha pasado tiempo que no le dedico al aprendizaje, aprovecharé un tiempito libre que tengo, a ver que se puede hacer con el 18f4550
ahora le toca al módulo Timer1 , ya le había echado el guante para generar demoras en modo temporizador con base de tiempo interno (ver este
tema), pués ahora le toca la temporización con base de tiempo externa e interrumpiendo la cuenta al desborde.
yendo a la página 131 del 39632
D.pdf tenemos lo necesario para hacer arrancar a este señor.
antes de ver registros, etc vamos por el dibujito (FIGURE 12-1), así se hace fácil de entrarle
esa imagen lo dice todo, si yo quiero por ejemplo que el timer1 me cuente x segundos en modo sleep, trayendo como consecuencia que debo usar una base de tiempo externo mediante un cristal e independientemente del ritmo a que vá el micro, entonces a dibujaré mi camino de registros a usar.
siguiendo el camino de la 'culebrita' entonces los bits de los SFR van de esta manera:
T1OSCEN <- b'1'
TMR1CS <- b'1'
T1CKPS1:T1CKPS0 <- b'00'
T1SYNC <- b'1'
TMR1ON <- será tratado para habilitar el timer1 cuando sea requerido
TMR1IF <- será tratado en el servicio de petición a la interrupción
(ISR ó SRI)
y ¿donde estan esos bits? todos estan el el SFR T1CON
¡ah! me faltaron 2
RD16 y T1RUN ¿quienes son esos?
RD16: 16-Bit Read/Write Mode Enable bit
1 = Enables register read/write of Timer1 in one 16-bit operation
0 = Enables register read/write of Timer1 in two 8-bit operations
T1RUN: Timer1 System Clock Status bit
1 = Device
clock is derived from Timer1 oscillator
0 = Device
clock is derived from another source
en mi caso quedaran así:
RD16 <- b'0'
T1RUN <- 0b'0'
ya tenemos lista la parte de configurar el T1CON, falta saber cuanto debo cargar el par TMR1H:TMR1L
usaré un cristal de 32Khz -> d'32000' -> 0x7D00 entonces para completar la cuenta de 1 segundo restaré el máximo permitido d'65535' -> 0xffff - 0x7D00 -> 0x82FF
con esto quiero decir que al encender el timer, éste comenzará a contar o incrementarse a partir de 0x82FF y al llegar a 0xffff + 1 se desbordará el par TMR1H:TMR1L y ocurrirá mi interrupción de 1 segundo
(sumando a los ciclos de las lineas dentro del SRI)
parte del código quedaría así
...
movlw b'00001111' ; Configure for external clock,
movwf T1OSC ; Asynchronous operation, external
oscillator
...
movlw 0xff
clrf TMR1L
movlw 0x82
clrf TMR1H
antes de escribir el programa completo, me conseguí con una piedra nueva en el camino, me refiero al tema de las interrupciones, resulta que en la familia 18, existen 2 tipos de interrupciones, no ahondaré mucho ya que el amigo micro_cadaver lo está desarrollando en este
post (y además estoy empezando, quee voy a está explicando yo jeje)
peero si me remitiré como usarlo en este ejemplo.
(pág 135)
aquí señalé los SFR involucrados con la interrupción
empecemos por el último:
TMR1IP: TMR1 Overflow Interrupt Priority bit
1 = High priority
0 = Low priority
como yo usaré la dirección 0x8 para el ISR, es decir, la ISR de alta prioridad, entonces
TMR1IP <- 0x1
PIE1: ya es conocido de los que vienen de la familia 16, selecciona la fuente de interrupción timer1
TMR1F: la bandera que se activa cuando ocurre el desbordamiento, no es tan necesario en este caso.
GIE: ya es conocido de los que vienen de la familia 16, es el 'papá de los helados' de las interrupciones, sin éste nadie vá pal baile, es decir, no ocurrirá ninguna interrupción.
esto que hice se puede representra graficamente con el camino de la culebrita:
el código completo:
;******************************************************************************************
; haciendo arrancar el timer1 en modo contador externo asincrono (base de tiempo externa)
; a traves de un cristal 32Khz para contar tiempos de 1 Seg poniendo a dormir el micro,
; despertando luego de una interrupcion para encender o apagar un led
; Pedro - PalitroqueZ
; 30-Mayo-2007 10:30 PM
;*****************************************************************************************
#DEFINE LED_RD0 LATD,0,ACCESS ; RD0
;**************************************************************************
LIST P=18F4550 ;directive to define processor
#include <P18F4550.INC> ;processor specific variable definitions
;**************************************************************************
CONFIG FOSC = XTPLL_XT, PLLDIV = 1,CPUDIV = OSC1_PLL2,USBDIV =2,PWRT = ON,BOR = SOFT, VREGEN = OFF CONFIG WDT = OFF ,WDTPS = 1,MCLRE = ON,PBADEN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF
;**************************************************************************
org 0
goto inicio
org 0x8 ;interrupcion alta prioridad
bcf PIR1, TMR1IF ; Clear interrupt flag
btg LED_RD0 ; togglea a rd0 para encender o apagar al led
movlw 0xff ; carga 0x82ff en TMR1
movwf TMR1L
movlw 0x82
movwf TMR1H
retfie
;********************************************************
inicio:
clrf LATA ; limpia los latch
clrf LATB
clrf LATC
clrf LATD
clrf LATE
clrf TRISA
clrf TRISB ; configura RB0<- entrada, el resto -> salida
clrf TRISC
clrf TRISD
clrf TRISE
;//------------------------------------------------------
; ahora viene la deshabilitacion de modulos (pheriperals)
;*******************************************************
clrf ADCON0 ; desactiva el CAD
movlw 0xf
movwf ADCON1 ; todas digitales
bcf INTCON,GIE ; desactiva interrupciones
movlw 0x7
movwf CMCON ;desactiva el modulo comparador
;clrf SPPCON ; desactiva el modulo Streaming Parallel Port (SPP)
clrf SSPCON1 ; desactiva el modulo MSSP,SSPEN
;bcf UCON,USBEN ; desactiva el modulo USB
bsf INTCON2,RBPU ; desactiva las resistencias de amarre en PORTB
;//-------------------------------------------
movlw b'01001000'
movwf OSCCON
movlw b'00001110' ; Configure for external clock, timer1=off
movwf T1CON ; Asynchronous operation, external oscillator
bsf PIE1,TMR1IE ; Enable Timer1 interrupt
movlw 0xff
movwf TMR1L
movlw 0x82
movwf TMR1H
bsf RCON,IPEN ; se acepta las interrupciones prioritarias
bsf IPR1,TMR1IP ; TMR1 Overflow Interrupt Priority bit, High priority
bsf T1CON,TMR1ON ; enciende el timer1
bsf INTCON,GIEH
;sleep
d: nop
goto d
END
correción: al final del programa va así:
...
bsf INTCON,GIEH
d: sleep
goto d
END
el que tenga dudas con las palabras de configuraciones, busque hlpPIC18ConfigSet.chm
notas:
- traté de simular la interrupción en MPLAB-SIM, y en la ayuda está muy confuso, por un lado dicen que si se puede colocando un clock stimulus (haciendo la de clock external):
16-bit Core (PIC18) PeripheralsAlong with core support, MPLAB SIM
supports the following
peripheral modules, in addition to general purpose I/O:
Timers...
Timer0
...
All Other Timers in their various modes are supported, except for
modes using an external crystal. MPLAB SIM supports Timer interrupts
generated on
overflow, and interrupts generated by
wake-up
from sleep. Although the external oscillator is not simulated, a clock
stimulus can be assigned to those pins.
y por el otro dicen:
Depending on device:
Timer1 increments on RC0, not RC1, for Timer1 enabled
tendré que montar el programa en el pic y ensayar
- LOW-POWER TIMER1 OPTION esta opción la dejaré habilitada por defecto (high power)
- para los que quieran probar con otros 18Fxxxx en proteus, a mi no me funcionó en modo sleep. funciona OK con el 18f4525 poniendo un bucle eterno.
ahora se procede a grabar, montar y...
¡ no funciona !
¿porque?
a ver... después de un par de minutos revisando conexiones y el programa, se me ocurrió 'tocar' los cristales estando alimentado el micro. ¡PRENDIÓ!
umm ya me conseguí con una limitación física: el ruido. La mejor fuente de ruidos para ensayar circuitos es el mismo
protoboard, porque incluso acercando los dedos sin tocar los cristales, empezaba a oscilar el led.
haré otro intento para tratar de estabilizar a TOSC1, mirando la pág 134
enrollaré un pedazo de cable en ambos cristales cuyos terminales conectados a gnd.....
nada, intento fallido
bueno que le vamos hacer, no todo es de color de rosa en esta vida jeje
¿y que tal si configuramos el bloque oscilador para que cpu se sincronice de los 4Mhz internos?
esa es otra historia...
PD: que largo, ¡¡ y todo para encender un led durante 1 segundo !!