TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: championz en 24 de Abril de 2006, 14:18:37
-
buenas! les hago una pregunta, es posible usar dos interrupciones por rtcc con distintos timers??
la idea seria hacer una interrupcion por ejemplo cada 1 milisegundo con un timer y otra cada 100 milisegundos con otro timer, es posible esto?
gracias!
-
Claro que se puede. Usando CCS:
#int_timer0
void f1()
{
}
#int_timer1
void f2()
{
}
Y configuras los timers como normalmente lo haces.
-
No solo se puede, como te dice el amigo Migsantiago, sino que se hace muchas veces, e incluso con más timers ...
Pero esto me lleva a preguntar otra cosa relacionada con esto ....
Si ponemos una interrupción INT1 para 1 ms y otra INT2 a 100 ms ... aproximadamente cada 100 INT1 (no nos es posible configurar una interrupción para 1 ms EXACTO) saltaran ambas INT1 e INT2 casi al mismo tiempo.
¿Una interrupción interrumpira a la otra? ¿se ejecutaran ambas pero ambas, cuando coincidan, duraran un poco mas?
¿se deshabilitara el "otro" contador mientras está la primera interrupción que llegue ejecutándose? ¿eeeeeh?
¿como se podría comprobar esto?
No se me había ocurrido esta posibilidad ... y es interesante desvelar lo que ocurre en estos casos. :shock:
Se aceptan propuestas :lol:
-
Creo recordar que al abordarse una interrupcion, el compilador, deshabilita todas las interrupciones, por lo tanto no saltaria a la segunda interrupcion hasta terminar la primera...
Suerte!!! :wink:
-
Leyendo la ayuda sobre #INT_xxxx me entero que si uno quiere que una interrupción interrumpa a otra hay que poner #int_xxxx high, para darle prioridad.
Lo que no especifica es si se deshabilitan las otras interrupciones mientras se está atendiendo una (sin usar high). :shock:
Lo recomendable es siempre meter la menor cantidad posible de código en una llamada de interrupción.
Hice un programita muy simple para analizar a nivel ensamblador lo que sucede. Se los dejo, quise analizarlo pero ando un poco oxidado a nivel ensamblador :D
CCS PCM C Compiler, Version 3.245, 28193 24-Abr-06 15:41
Filename: C:\temporal\borra\borra.lst
ROM used: 78 words (8%)
Largest free fragment is 946
RAM used: 9 (13%) at main() level
9 (13%) worst case
Stack: 1 worst case (0 in main + 1 for interrupts)
*
0000: MOVLW 00
0001: MOVWF 0A
0002: GOTO 03A
0003: NOP
0004: BTFSC 03.5
0005: GOTO 00A
0006: MOVWF 0E
0007: SWAPF 03,W
0008: MOVWF 0F
0009: GOTO 00F
000A: BCF 03.5
000B: MOVWF 0E
000C: SWAPF 03,W
000D: MOVWF 0F
000E: BSF 0F.1
000F: MOVF 0A,W
0010: MOVWF 13
0011: CLRF 0A
0012: BCF 03.7
0013: SWAPF 0E,F
0014: MOVF 04,W
0015: MOVWF 10
0016: MOVF 0C,W
0017: MOVWF 11
0018: MOVF 0D,W
0019: MOVWF 12
001A: BCF 03.5
001B: BTFSS 0B.3
001C: GOTO 01F
001D: BTFSC 0B.0
001E: GOTO 036
001F: BTFSS 0B.5
0020: GOTO 023
0021: BTFSC 0B.2
0022: GOTO 032
0023: MOVF 10,W
0024: MOVWF 04
0025: MOVF 11,W
0026: MOVWF 0C
0027: MOVF 12,W
0028: MOVWF 0D
0029: MOVF 13,W
002A: MOVWF 0A
002B: SWAPF 0F,W
002C: MOVWF 03
002D: BCF 03.5
002E: SWAPF 0E,W
002F: BTFSC 0F.1
0030: BSF 03.5
0031: RETFIE
.................... //probando interrupciones
....................
.................... #include "16f84a.h"
.................... //////// Standard Header file for the PIC16F84A device ////////////////
.................... #device PIC16F84A
.................... #list
....................
.................... #use delay(clock=4000000)
.................... #fuses XT,NOWDT,NOPROTECT
....................
.................... int8 i=0;
*
003D: CLRF 14
....................
.................... #int_timer0
.................... void probando(void)
.................... {
.................... i++;
*
0032: INCF 14,F
.................... }
....................
0033: BCF 0B.2
0034: BCF 0A.3
0035: GOTO 023
.................... #int_rb
.................... void rb00()
.................... {
.................... i++;
0036: INCF 14,F
.................... }
....................
0037: BCF 0B.0
0038: BCF 0A.3
0039: GOTO 023
.................... void main (void)
.................... {
003A: CLRF 04
003B: MOVLW 1F
003C: ANDWF 03,F
....................
.................... set_tris_b(0xff);
*
003E: MOVLW FF
003F: TRIS 6
.................... setup_timer_0(RTCC_INTERNAL);
0040: BSF 03.5
0041: MOVF 01,W
0042: ANDLW C0
0043: MOVWF 01
.................... set_timer0(0x00);
0044: BCF 03.5
0045: CLRF 01
.................... EXT_INT_EDGE(L_TO_H);
0046: BSF 03.5
0047: BSF 01.6
.................... enable_interrupts(INT_RB); //rb0
0048: BCF 03.5
0049: BSF 0B.3
.................... enable_interrupts(INT_TIMER0);
004A: BSF 0B.5
.................... enable_interrupts(global);
004B: BSF 0B.7
....................
.................... while(1)
.................... {}
004C: GOTO 04C
....................
.................... }
004D: SLEEP
Configuration Fuses:
Word 1: 3FF9 XT NOWDT NOPUT NOPROTECT
These directives specify the following function is an interrupt function. Interrupt functions may not have any parameters. Not all directives may be used with all parts. See the devices .h file for all valid interrupts for the part or in PCW use the pull down VIEW | Valid Ints
The compiler will generate code to jump to the function when the interrupt is detected. It will generate code to save and restore the machine state, and will clear the interrupt flag. To prevent the flag from being cleared add NOCLEAR after the #INT_xxxx. The application program must call ENABLE_INTERRUPTS(INT_xxxx) to initially activate the interrupt along with the ENABLE_INTERRUPTS(GLOBAL) to enable interrupts.
The keywords HIGH and FAST may be used with the PCH compiler to mark an interrupt as high priority. A high-priority interrupt can interrupt another interrupt handler. An interrupt marked FAST is performed without saving or restoring any registers. You should do as little as possible and save any registers that need to be saved on your own. Interrupts marked HIGH can be used normally. See #DEVICE for information on building with high-priority interrupts.
-
gracias por las respuestas, me sirvieron mucho, pero tengo otra pregunta, como tendria que configurar los 2 timers, osea.. cuando yo uso un timer pongo esto:
setup_counters(RTCC_INTERNAL,RTCC_DIV_4);
pero con 2 timers como tendria que hacer para configurarlos con distintos DIV?
-
Buenas!!!!mirate la help del compilador donde esta bastante bien explicada, tambien te recomiendo que revises el include del pic a usar, ya que podras ver los distintos tipos de configuraciones para cada timer, pero vamos para configurar el timer1 por ejemplo seria algo tal que asi:
enable_interrupts(INT_TIMER1); //interrupcion TIMER1 activada
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8); //configuracion TMR1
set_timer1(un_valor); //carga TMR1 para desvordar
enable_interrupts(GLOBAL); //activadas interrupciones
Y para los distiontos timer's pues la configuracion es parecida, simplemente cambia el numerito el cual indica el timer a configurar...
Suerte!!! :wink: