Bueno este ejemplo hace lo que pedias inicialmente, lo he probado y funciona, otro problema será que lo puedas adaptar a tu lenguaje.
Y si necesitas controlar grandes cantidades de led el software como el hardware cambian. Pero bueno, por algo hay que comenzar.
Te dejo el código completo:
'Pic16F628A, oscilador interno 4Mhz
'Configuración de fuses
#define CONFIG = 0x3f50
Define CLOCK_FREQUENCY = 4 'Oscilador a 4Mhz
'Include "_FuncionesPic16F628A.bas"
'Include "_FunctionesTmrBase.bas"
'Call _setup_oscillator(_osc_4Mhz)
PCON.OSCF = 1 'Oscilador interno 4Mhz
'Inicializa Timer1 para generar una interrupción cada 1mSeg.
'Call _setup_timer1(_tmr1_internal, _tmr1_div1) 'Configura TMR1 para 4Mhz
T1CON = 0 'Asigna oscilador interno para el tmr1
T1CON.T1CKPS1 = 0 'Asigna el divisor
T1CON.T1CKPS0 = 0
'Call _set_timer1(0xfc17) 'Carga contador TMr1 para contar 1mSeg.
T1CON.TMR1ON = 0 'Para el contador del TMR1
TMR1H = 0xfc 'Recarga el byte alto
TMR1L = 0x17 'Recarga el byte bajo
T1CON.TMR1ON = 1 'Activa el contador del TMR1
PIR1.TMR1IF = 0 'Flash dosborde a cero
'Call _timer1(_on) 'Pone en marcha el Tmr1
T1CON.TMR1ON = 1 'Activa el contador del TMR1
'Call _enable_interrupts(_int_timer1) 'Permite las interrupciones por desborde Tmr1
PIE1.TMR1IE = 1 'Permite la interrup. TIMER1
'Call _enable_interrupts(_global) 'Permte las interrupciones globales
INTCON.PEIE = 1 'Bit habilita interrupciones perifericos
Enable 'INTCON.GIE habilita las interrupciones
'************************************************************
AllDigital
Symbol led1 = RB0
Symbol led2 = RB1
Symbol sw1 = RA2
Symbol sw2 = RA3
'Contadores para generar las bases de tiempos.
_contador1 = 0
_contador2 = 0
'Flag de control
flag1 = 0
flag2 = 0
WaitMs 20
Main:
'Temporizador no redisparable, para redisparable quitar flag1 = 0
'Para ser bloqueado por el anterior añadir "and flag2 = 0"
IF sw1
= 0 AND flag1
= 0 THEN _contador1 = 1000
flag1 = 1
ELSE
IF _contador1
= 0 AND flag1
= 1 THEN High led1
flag1 = 0
Endif
Endif
'Temporizador no redisparable, para redisparable quitar flag2 = 0
'Para ser bloqueado por el anterior añadir "and flag1 = 0"
IF sw2
= 0 AND flag2
= 0 THEN _contador1 = 2000
flag2 = 1
ELSE
IF _contador1
= 0 AND flag2
= 1 THEN Low led1
flag2 = 0
Endif
Endif
IF _contador2 = 0 THEN
Toggle RB2
_contador2 = 10
Endif
GOTO Main
'****************************
Save
SYSTEM 'Guarda calculos intermedios y otros del sistema 'Detecta interrupción Timer1
IF PIR1.TMR1IF = 1 THEN
'Call _set_timer1(0xfc17) 'Recarga registros TMR1 para desborde 1mSeg. y borra PIR1.TMR1IF
T1CON.TMR1ON = 0 'Para el contador del TMR1
TMR1H = 0xfc 'Recarga el contador byte alto
TMR1L = 0x17 'Recarga el contador byte bajo
T1CON.TMR1ON = 1 'Activa el contador del TMR1
PIR1.TMR1IF = 0 'Flash dosborde a cero
IF _contador1 > 0 THEN _contador1 = _contador1 - 1 '_contador BT
IF _contador2 > 0 THEN _contador2 = _contador2 - 1 '_contador BT
Endif
RESUME
'******************************
Estimado dogflu, agradezco mucho tu tiempo invertido para ayudarme a vencer esta dificultad de los Temporizadores, en verdad es muy amable de tu parte.
Te comento que he adaptado a PBP el código que enviaste, lo revisé de arriba hacia abajo, para ver si cometí algún error, pero todo está correcto, sin embargo solo funciona la parte que dice toggle RB2 que en PBP es toggle portb.2, el resto no trabaja, es decir, presiono SW1 y no enciende el led.
habilité y des-habilité el ENABLE de la rutina de interrupción, y tampoco funcionó.
No tengo duda de que con el lenguaje que tu usas funcione, pero hay algún detallito que le hace falta a PBP para que funcione.
Por si acaso, adjunto el código en formato de texto.
Gran saludo!
Código:
@ __config _INTRC_OSC_NOCLKOUT & _MCLRE_ON & _BODEN_OFF & _LVP_OFF & _WDT_OFF & _PWRTE_OFF
;*******************************************************************************
Define OSC 4
CMCON = 7
Precarga Var Word
_contador1 Var Word
_contador2 Var Word
flag1 Var Bit
flag2 Var Bit
flag1 = 0
flag2 = 0
pAUSE 20
TRISA=%11111111
TRISB=%00000000
Symbol LED1 = PORTB.0
Symbol LED2 = PORTB.1
Symbol SW1 = PORTA.2
Symbol SW2 = PORTA.3
PORTB=0
LED1 = 0
LED2 = 0
_contador1 = 0
_contador2 = 0
T1CON = %00111101
Precarga = 40536
TMR1H = Precarga.HighByte 'Precargar el byte alto
TMR1L = Precarga.LowByte 'Precargar el byte bajo
PIE1.0 = 1 'Habilita la interrupción por desborde
INTCON = %11000000 'Habilita interrupciones globales y periféricas
'Completado = 0 ; bandera en 0
On Interrupt GoTo Interrupcion
Inicio:
'Temporizador no redisparable, para redisparable quitar flag1 = 0
'Para ser bloqueado por el anterior añadir "and flag2 = 0"
IF sw1 = 0 AND flag1 = 0 THEN
_contador1 = 1000
flag1 = 1
ELSE
IF _contador1 = 0 AND flag1 = 1 THEN
High led1
flag1 = 0
Endif
Endif
'Temporizador no redisparable, para redisparable quitar flag2 = 0
'Para ser bloqueado por el anterior añadir "and flag1 = 0"
IF sw2 = 0 AND flag2 = 0 THEN
_contador1 = 2000
flag2 = 1
ELSE
IF _contador1 = 0 AND flag2 = 1 THEN
Low led1
flag2 = 0
Endif
Endif
IF _contador2 = 0 THEN
Toggle PORTB.2
_contador2 = 10
Endif
GoTo Inicio:
Interrupcion:
Disable
If PIR1.0 = 1 Then ; Ocurrió un desborde del Timer 1
'Call _set_timer1(0xfc17) 'Recarga registros TMR1 para desborde 1mSeg. y borra PIR1.TMR1IF
T1CON.0 = 0 'Para el contador del TMR1
TMR1H = Precarga.HighByte 'Recarga el contador byte alto
TMR1L = Precarga.LowByte 'Recarga el contador byte bajo
T1CON.0 = 1 'Activa el contador del TMR1
PIR1.0 = 0 'Flash dosborde a cero
IF _contador1 > 0 THEN _contador1 = _contador1 - 1 '_contador BT
IF _contador2 > 0 THEN _contador2 = _contador2 - 1 '_contador BT
EndIf
Resume
'Enable
End