Hola a todos, a ver si me podeis hechar una mano en un problemita que me ha surgido haciendo unas simulaciones.
Resulta que en la 1º simulacion ( llamada '1seg' ) utilizo el tmr1 del 16f877a para encender y apagar un led cada segundo.
El tema es fácil, configuro el tmr1, le doy a TMR1H = 0xFC ( 252 ) TMR1L = 0x46 ( 70 ), activo las interrupciones y el tmr1 desborda cada milisegundo, con lo cual pongo un contador desde 0 hasta 999, cuando contador=999 entoces enciendo el led.
He comprobado que si a TMR1H y TMR1L los pongo a 0 ( cero ) el tmr1 desborda cada 1 minuto y 5 segundos más o menos.
Todo esto según la simulación y el pic a 4Mhz.
Bien, ahora lo curioso viene en la segunda simulación ( llamada 'captura'), ésta no hace más que calcular los hertzios durante 1 segundo con lo cual utilizo las mismas rutinas que en la simulacion anterior... configuro el tmr1 para que desborde cada segundo ( valores 0Xfc y =0x46 ). Configuro el capturador en flanco de subida y cuando detecte el 1º impulso activa el tmr1, mientras, en cada impulso cont=cont+1, lo siguiente que hace es que cuando desborda el tmr1 apaga el capturador, para el tmr1 y muestra el valor de cont por el lcd... vamos, mas sencillo imposible...
El problema está en que en la 1º simulación el tmr1 desborda cada milisegundo, por eso le pongo un contador de 0 a 999, ( 1000 mS = 1S ), bien, pues en la segunda simulación, he tenido que hacer lo siguiente:
TMR1H y TMR1L a 0 ( cero ) y le he tenido que poner un contador de 0 a 15 para que cuante casi exacto un segundo.
La duda es porque tengo que variar el TMR1H y TMR1L en las simulaciones si simplemente cambio el led por un osciloscopio...
Aquí el código de la simulación '1Seg'
Define CONF_WORD = 0x3f71
'Prueba contador 1 segundo
Define LCD_LINES = 4 'LCD de 4 líneas/filas
Define LCD_CHARS = 16 'LCD de 16 caracteres/columnas
Define LCD_BITS = 8 'Comunicacion con LCD a 8 bits
Define LCD_DREG = PORTB 'La comunicación se raliza por el PortB
'Define LCD_DBIT = 0 'A 4 bits, 0 Se utilizan pines del 0 al 3 y el 4 del 4 al 7
Define LCD_RSREG = PORTC 'El bit RS en el PortC
Define LCD_RSBIT = 6 'El bit RS en el pin 0
Define LCD_EREG = PORTC 'El bit E en el PortC
Define LCD_EBIT = 7 'El bit E en el pin 1
'Define LCD_RWREG = PORTC 'El bit RW en el PortC
'Define LCD_RWBIT = 2 'El bit RW en el pin 2
Define LCD_COMMANDUS = 100 'Pausa en microsegundos despues de enviar un comando al LCD
Define LCD_DATAUS = 50 'Pausa en microsegundos despues de enviar datos al LCD
Define LCD_INITMS = 2 'Pausa para esperar la inicialización del LCD
'Define SIMULATION_WAITMS_VALUE = 1 'Convierte todos los WaitMS a WaitMs=1
Lcdinit
WaitMs 100
'Break
CMCON = 0 'comparador a off
Symbol ro = RD0
Symbol am = RD1
Dim a As Bit
Dim cont As Long
Dim th As Byte
Dim tl As Byte
'Un segundo corresponde cada 1.000, aunque en ésta simulación corresponde a 1.004
'1 segundo = 64.582
'th = 252
'tl = 70
'2 segundos = 63.582
'th = 248
'tl = 90
'3 segundos = 62.574
'th = 244
'tl = 110
a = 1
'tmr1
'preescaler:
'11=1:8 10=1:4 01=1:2 00=1:1
T1CON.T1CKPS1 = 0
T1CON.T1CKPS0 = 0
'oscilador
'1=enabled 0=disabled
T1CON.T1OSCEN = 0
'sincronicacion
'1=No external clock
'0=External clock
T1CON.T1SYNC = 0
'clock source
'1=reloj externo (RC0) ( contador )
'0=interno ( Fosc/4 ) ( Timer )
T1CON.TMR1CS = 0
TMR1H = th 'preparo TMR1H para que desborde
TMR1L = tl 'preparo TMR1L para que desborde
INTCON.PEIE = 1 'activo las int de perifericos
PIE1.TMR1IE = 1 'activo int del tmr1
'estado del tmr1
'0=apagado
'1=encendido
T1CON.TMR1ON = 1 'activo el tmr1
Enable 'activo las int globales ( unmasked )
'el preescaler se pierde al escribir en TMR1H y TMR1L
While a = 1
Lcdcmdout LcdLine1Home
Lcdout #TMR1H, " "
Lcdcmdout LcdLine2Home
Lcdout #TMR1L, " "
Wend
End
On Interrupt
Save System
If PIR1.TMR1IF Then
PIR1.TMR1IF = 0
Toggle ro
TMR1H = th
TMR1L = tl
cont = cont + 1
If cont = 999 Then
cont = 0
Toggle am
Endif
Endif
Resume
-----------------------------------
Aqui el código de 'capturador'
'Define SIMULATION_WAITMS_VALUE = 1
Define LCD_LINES = 4 'LCD de 4 líneas/filas
Define LCD_CHARS = 16 'LCD de 16 caracteres/columnas
Define LCD_BITS = 8 'Comunicacion con LCD a 8 bits
Define LCD_DREG = PORTD 'La comunicación se raliza por el PortB
'Define LCD_DBIT = 0 'A 4 bits, 0 Se utilizan pines del 0 al 3 y el 4 del 4 al 7
Define LCD_RSREG = PORTB 'El bit RS en el PortC
Define LCD_RSBIT = 0 'El bit RS en el pin 0
Define LCD_EREG = PORTB 'El bit E en el PortC
Define LCD_EBIT = 1 'El bit E en el pin 1
'Define LCD_RWREG = PORTB 'El bit RW en el PortC
'Define LCD_RWBIT = 1 'El bit RW en el pin 2
Define LCD_COMMANDUS = 100 'Pausa en microsegundos despues de enviar un comando al LCD
Define LCD_DATAUS = 100 'Pausa en microsegundos despues de enviar datos al LCD
Define LCD_INITMS = 50 'Pausa para esperar la inicialización del LCD
Dim datos As Word
Dim cont As Long
Dim timer As Long
Dim tiempo As Bit
Dim th As Byte
Dim tl As Byte
Lcdinit 0
WaitMs 500
'config del timer1
T1CON = 0
'T1CON.T1CKPS0 = 0 'modo del preescaler
'T1CON.T1CKPS1 = 0
'T1CON.T1OSCEN = 0 'activar oscilador
'T1CON.T1SYNC = 0 'sincronizacion con timer1 externo
'T1CON.TMR1CS = 0 'Origen de reloj - 1:Externo, 0:Interno(Fosc/4)
'T1CON.TMR1ON = 0 'Activar Timer1
'config modulo captura
CCP1CON.CCP1M0 = 1 'captura por flanco
CCP1CON.CCP1M1 = 0 '0100 descendente, 0101 ascendente, 0110 captura el 4º ascendente, 0111 cap el 16º ascen
CCP1CON.CCP1M2 = 1
CCP1CON.CCP1M3 = 0
INTCON.PEIE = 1 'activo la int de perifericos
PIE1.CCP1IE = 1 'activo la int de ccp cuando ocurra una captura
PIE1.TMR1IE = 1 'activo la int de desbordamiento del tmr1
'configuro el tmr1 para que desborde cada segundo
th = 0
tl = 0
TMR1H = th '252
TMR1L = tl '70
T1CON.TMR1ON = 0 'activo el tmr1
RC6 = 0 'activo rc6 para que coincida con rc7 en la primera captura ( estetica )
Enable 'activo los perifericos
loop:
Goto loop
End
On Interrupt
Save System 'guardo el estado del sistema
If PIR1.TMR1IF = 1 Then 'interrupcion de desbordamiento del tmr1, desbordado
timer = timer + 1
PIR1.TMR1IF = 0
If timer = 15 Then
timer = 0
T1CON.TMR1ON = 0 'paro el tmr1
PIE1.CCP1IE = 0 'desactivo el capturador
Lcdcmdout LcdLine1Home
Lcdout "Hz-> ", #cont, " " 'muestro el valor de cont
cont = 0 'reinicio el contador
TMR1H = th
TMR1L = tl
Toggle RC7 'cambio el estado de RC7
PIE1.CCP1IE = 1 'activo el capturador
Endif
Endif
If PIR1.CCP1IF = 1 Then 'Interrupcion del registro de captura, captura realizada
PIR1.CCP1IF = 0 'limpio el flag
Toggle RC6 'cambio el estado de RC6
T1CON.TMR1ON = 1 'activo el tmr1
cont = cont + 1 'contador de Hertzios por segundo
Endif
Resume
----------------------------------------
Muchas gracias y saludos.
Resulta que en la 1º simulacion ( llamada '1seg' ) utilizo el tmr1 del 16f877a para encender y apagar un led cada segundo.
El tema es fácil, configuro el tmr1, le doy a TMR1H = 0xFC ( 252 ) TMR1L = 0x46 ( 70 ), activo las interrupciones y el tmr1 desborda cada milisegundo, con lo cual pongo un contador desde 0 hasta 999, cuando contador=999 entoces enciendo el led.
He comprobado que si a TMR1H y TMR1L los pongo a 0 ( cero ) el tmr1 desborda cada 1 minuto y 5 segundos más o menos.
Todo esto según la simulación y el pic a 4Mhz.
Bien, ahora lo curioso viene en la segunda simulación ( llamada 'captura'), ésta no hace más que calcular los hertzios durante 1 segundo con lo cual utilizo las mismas rutinas que en la simulacion anterior... configuro el tmr1 para que desborde cada segundo ( valores 0Xfc y =0x46 ). Configuro el capturador en flanco de subida y cuando detecte el 1º impulso activa el tmr1, mientras, en cada impulso cont=cont+1, lo siguiente que hace es que cuando desborda el tmr1 apaga el capturador, para el tmr1 y muestra el valor de cont por el lcd... vamos, mas sencillo imposible...
El problema está en que en la 1º simulación el tmr1 desborda cada milisegundo, por eso le pongo un contador de 0 a 999, ( 1000 mS = 1S ), bien, pues en la segunda simulación, he tenido que hacer lo siguiente:
TMR1H y TMR1L a 0 ( cero ) y le he tenido que poner un contador de 0 a 15 para que cuante casi exacto un segundo.
La duda es porque tengo que variar el TMR1H y TMR1L en las simulaciones si simplemente cambio el led por un osciloscopio...
Aquí el código de la simulación '1Seg'
Define CONF_WORD = 0x3f71
'Prueba contador 1 segundo
Define LCD_LINES = 4 'LCD de 4 líneas/filas
Define LCD_CHARS = 16 'LCD de 16 caracteres/columnas
Define LCD_BITS = 8 'Comunicacion con LCD a 8 bits
Define LCD_DREG = PORTB 'La comunicación se raliza por el PortB
'Define LCD_DBIT = 0 'A 4 bits, 0 Se utilizan pines del 0 al 3 y el 4 del 4 al 7
Define LCD_RSREG = PORTC 'El bit RS en el PortC
Define LCD_RSBIT = 6 'El bit RS en el pin 0
Define LCD_EREG = PORTC 'El bit E en el PortC
Define LCD_EBIT = 7 'El bit E en el pin 1
'Define LCD_RWREG = PORTC 'El bit RW en el PortC
'Define LCD_RWBIT = 2 'El bit RW en el pin 2
Define LCD_COMMANDUS = 100 'Pausa en microsegundos despues de enviar un comando al LCD
Define LCD_DATAUS = 50 'Pausa en microsegundos despues de enviar datos al LCD
Define LCD_INITMS = 2 'Pausa para esperar la inicialización del LCD
'Define SIMULATION_WAITMS_VALUE = 1 'Convierte todos los WaitMS a WaitMs=1
Lcdinit
WaitMs 100
'Break
CMCON = 0 'comparador a off
Symbol ro = RD0
Symbol am = RD1
Dim a As Bit
Dim cont As Long
Dim th As Byte
Dim tl As Byte
'Un segundo corresponde cada 1.000, aunque en ésta simulación corresponde a 1.004
'1 segundo = 64.582
'th = 252
'tl = 70
'2 segundos = 63.582
'th = 248
'tl = 90
'3 segundos = 62.574
'th = 244
'tl = 110
a = 1
'tmr1
'preescaler:
'11=1:8 10=1:4 01=1:2 00=1:1
T1CON.T1CKPS1 = 0
T1CON.T1CKPS0 = 0
'oscilador
'1=enabled 0=disabled
T1CON.T1OSCEN = 0
'sincronicacion
'1=No external clock
'0=External clock
T1CON.T1SYNC = 0
'clock source
'1=reloj externo (RC0) ( contador )
'0=interno ( Fosc/4 ) ( Timer )
T1CON.TMR1CS = 0
TMR1H = th 'preparo TMR1H para que desborde
TMR1L = tl 'preparo TMR1L para que desborde
INTCON.PEIE = 1 'activo las int de perifericos
PIE1.TMR1IE = 1 'activo int del tmr1
'estado del tmr1
'0=apagado
'1=encendido
T1CON.TMR1ON = 1 'activo el tmr1
Enable 'activo las int globales ( unmasked )
'el preescaler se pierde al escribir en TMR1H y TMR1L
While a = 1
Lcdcmdout LcdLine1Home
Lcdout #TMR1H, " "
Lcdcmdout LcdLine2Home
Lcdout #TMR1L, " "
Wend
End
On Interrupt
Save System
If PIR1.TMR1IF Then
PIR1.TMR1IF = 0
Toggle ro
TMR1H = th
TMR1L = tl
cont = cont + 1
If cont = 999 Then
cont = 0
Toggle am
Endif
Endif
Resume
-----------------------------------
Aqui el código de 'capturador'
'Define SIMULATION_WAITMS_VALUE = 1
Define LCD_LINES = 4 'LCD de 4 líneas/filas
Define LCD_CHARS = 16 'LCD de 16 caracteres/columnas
Define LCD_BITS = 8 'Comunicacion con LCD a 8 bits
Define LCD_DREG = PORTD 'La comunicación se raliza por el PortB
'Define LCD_DBIT = 0 'A 4 bits, 0 Se utilizan pines del 0 al 3 y el 4 del 4 al 7
Define LCD_RSREG = PORTB 'El bit RS en el PortC
Define LCD_RSBIT = 0 'El bit RS en el pin 0
Define LCD_EREG = PORTB 'El bit E en el PortC
Define LCD_EBIT = 1 'El bit E en el pin 1
'Define LCD_RWREG = PORTB 'El bit RW en el PortC
'Define LCD_RWBIT = 1 'El bit RW en el pin 2
Define LCD_COMMANDUS = 100 'Pausa en microsegundos despues de enviar un comando al LCD
Define LCD_DATAUS = 100 'Pausa en microsegundos despues de enviar datos al LCD
Define LCD_INITMS = 50 'Pausa para esperar la inicialización del LCD
Dim datos As Word
Dim cont As Long
Dim timer As Long
Dim tiempo As Bit
Dim th As Byte
Dim tl As Byte
Lcdinit 0
WaitMs 500
'config del timer1
T1CON = 0
'T1CON.T1CKPS0 = 0 'modo del preescaler
'T1CON.T1CKPS1 = 0
'T1CON.T1OSCEN = 0 'activar oscilador
'T1CON.T1SYNC = 0 'sincronizacion con timer1 externo
'T1CON.TMR1CS = 0 'Origen de reloj - 1:Externo, 0:Interno(Fosc/4)
'T1CON.TMR1ON = 0 'Activar Timer1
'config modulo captura
CCP1CON.CCP1M0 = 1 'captura por flanco
CCP1CON.CCP1M1 = 0 '0100 descendente, 0101 ascendente, 0110 captura el 4º ascendente, 0111 cap el 16º ascen
CCP1CON.CCP1M2 = 1
CCP1CON.CCP1M3 = 0
INTCON.PEIE = 1 'activo la int de perifericos
PIE1.CCP1IE = 1 'activo la int de ccp cuando ocurra una captura
PIE1.TMR1IE = 1 'activo la int de desbordamiento del tmr1
'configuro el tmr1 para que desborde cada segundo
th = 0
tl = 0
TMR1H = th '252
TMR1L = tl '70
T1CON.TMR1ON = 0 'activo el tmr1
RC6 = 0 'activo rc6 para que coincida con rc7 en la primera captura ( estetica )
Enable 'activo los perifericos
loop:
Goto loop
End
On Interrupt
Save System 'guardo el estado del sistema
If PIR1.TMR1IF = 1 Then 'interrupcion de desbordamiento del tmr1, desbordado
timer = timer + 1
PIR1.TMR1IF = 0
If timer = 15 Then
timer = 0
T1CON.TMR1ON = 0 'paro el tmr1
PIE1.CCP1IE = 0 'desactivo el capturador
Lcdcmdout LcdLine1Home
Lcdout "Hz-> ", #cont, " " 'muestro el valor de cont
cont = 0 'reinicio el contador
TMR1H = th
TMR1L = tl
Toggle RC7 'cambio el estado de RC7
PIE1.CCP1IE = 1 'activo el capturador
Endif
Endif
If PIR1.CCP1IF = 1 Then 'Interrupcion del registro de captura, captura realizada
PIR1.CCP1IF = 0 'limpio el flag
Toggle RC6 'cambio el estado de RC6
T1CON.TMR1ON = 1 'activo el tmr1
cont = cont + 1 'contador de Hertzios por segundo
Endif
Resume
----------------------------------------
Muchas gracias y saludos.