Intervalos del temporizador MSP430G2553

Después de leer el texto unas cinco veces y buscar en Google, decidí buscar ayuda. Actualmente estoy en el proceso de usar la interrupción Timer_A para encender / apagar dos LEDS en intervalos de 1 segundo / 10 segundos / 1 minuto de uno en uno. El progtwig predeterminado encenderá / apagará los LEDS cada segundo, pero no puedo encontrar una manera de apagarlos después de 10 segundos y un minuto. Puedo usar __delay_cycles (xxxx) para lograr esto, pero aparentemente hacerlo anularía el propósito del temporizador. Este es mi código.

#include  #define RedLED BIT0 #define GreenLED BIT6 #define RedLEDToggle (P1OUT ^= RedLED) #define GreenLEDToggle (P1OUT ^= GreenLED) unsigned int counter = 0; void main(void) { WDTCTL = WDTPW | WDTHOLD; //WDTCTL = WDT_MDLY_32; P1DIR = RedLED | GreenLED; P1OUT = RedLED | GreenLED; TACTL = TASSEL_2 | ID_3 | MC_3 | TAIE; TACCR0 = 62500; _enable_interrupts(); LPM1; } #pragma vector=TIMER0_A1_VECTOR __interrupt void Timer_A(void) { if ( counter == 10) { switch (TAIV) { case 0x02: break; case 0x04: break; case 0x0A: RedLEDToggle | GreenLEDToggle; break; } } else { counter ++; } } 

Para lograr un intervalo de interrupción de 10 segundos, debe aplicar el divisor de entrada al temporizador. No es posible lograr 1 minuto sin soporte periférico (consulte las otras respuestas sobre cómo implementar eso con un contador de software).

El problema es que los microcontroladores msp430 tienen registros de 16 bits, que no pueden contener valores numéricos mayores que 65535. El uso del oscilador de baja frecuencia a 32768 Hz (como es habitual, no proporciona detalles sobre las fonts de reloj del hardware de su sistema, si tienen una frecuencia diferente, mencione que) el registro se desborda una vez cada 2 segundos a menos que se aplique un divisor de entrada. El valor máximo del divisor de entrada en las MCU de la familia MSP430x2xxx es 8, por lo que no es posible configurar un temporizador de hardware más de 8 * 2 = 16 segundos en el futuro. Consulte la guía del usuario de la familia MSP430x2xxx para obtener más detalles.

Este código llama a la interrupción una vez 10 segundos:

 #include  #define RedLED BIT0 #define GreenLED BIT6 #define RedLEDToggle (P1OUT ^= RedLED) #define GreenLEDToggle (P1OUT ^= GreenLED) // 10 seconds, assuming 32768 Hz ACLK source and divider 8 #define TIMER_PERIOD (10u * (32768 / 8)) void main(void) { WDTCTL = WDTPW | WDTHOLD; P1DIR = RedLED | GreenLED; P1OUT = RedLED | GreenLED; // reset timer A config (not strictly needed) TACTL = TACLR; // ACLK as clock source, divider 8, continuous mode, interrupt enabled TACTL = TASSEL_1 | ID_3 | MC_2 | TAIE; // set the period TACCR1 = TIMER_PERIOD; // enable capture/compare interrupts for CCR1 TACCTL1 = CCIE; _enable_interrupts(); LPM1; } #pragma vector=TIMER0_A1_VECTOR __interrupt void Timer_A(void) { switch (TAIV) { case 0x02: // CCR1 interrupt RedLEDToggle; GreenLEDToggle; // set the time of the next interrupt TACCR1 += TIMER_PERIOD; break; } } 

es bastante simple, \

Tiene un temporizador de 1 segundo, que causa una interrupción cada 1 segundo.

Tus otros tiempos son múltiplos de ese 1 segundo.

Entonces, al inicio de su progtwig, configure un contador de 10 segundos a 0 y establezca un contador de 1 minuto a 0.

En cada interrupción de 1 segundo, incremente ambos contadores.

Cada vez que el contador de 10 segundos pasa de 9 a 10

  1. restablecer ese contador a 0
  2. procesar la 10 segunda actividad

Cada vez que el contador de 1 minuto pasa de 59 a 60.

  1. restablecer ese contador a 0
  2. procesar la actividad de 1 minuto

El encabezado define símbolos para los valores TAIV ; usalos, usalos a ellos.

Las XxxLEDToggle son declaraciones completas; No debe tratarlas como expresiones combinándolas con | .

El manejador de interrupciones puede ser llamado desde múltiples fonts. En este momento, su progtwig no habilita ningún otro, pero es probable que esto cambie, por lo que debe ejecutar su código específico de TAIFG solo cuando TAIFG realmente fue configurado.

Una vez que haya alcanzado el límite, debe restablecer el contador a cero.

Cuando tienes múltiples intervalos de temporizador, necesitas múltiples contadores. De lo contrario, el primer reinicio restablecerá el conteo para todos los intervalos.

Necesitas algo como esto:

 static unsigned int counter_10 = 0; static unsigned int counter_60 = 0; #pragma vector=TIMER0_A1_VECTOR static __interrupt void Timer_A0(void) { switch (TA0IV) { case TA0IV_TACCR1: break; case TA0IV_TACCR2: break; case TA0IV_TAIFG: if (++counter_10 >= 10) { counter_10 = 0; RedLEDToggle; } if (++counter_60 >= 60) { counter_60 = 0; GreenLEDToggle; } break; } }