1
votes

Comment puis-je ajouter un délai de 90 minutes lorsqu'un port est passé de 0 à 1?

J'ai un PIC12F1822 dont il y a une LED et un relais comme sortie et un déclencheur comme entrée.

Lorsque le déclencheur est égal à un, j'aimerais que la LED et le relais restent allumés pendant 90 minutes.

Le problème est que je ne peux pas utiliser de délai car __delayms a une limite.

Comment cela peut-il être fait?

#include <xc.h>

#define _XTAL_FREQ 4000000

#define LED PORTAbits.RA5
#define RELAY PORTAbits.RA4
#define TRIGGER PORTAbits.RA2

int main()
{

//  OSCCON = 0b01101000 ;
    OSCCONbits.IRCF = 0b1101 ;

  TRISAbits.TRISA5 = 0; //LED Output PIN
  TRISAbits.TRISA4 = 0; //Output for Relay
  TRISAbits.TRISA2 = 1; //INPUT trigger from comparator

  while(1)
  {
      if (TRIGGER == 1)
      { 
          LED = 1;  // LED ON
          __delay_ms(1000); // 1 Second Delay
          LED = 0;  // LED OFF
          __delay_ms(1000); // 1 Second Delay

       }

      else

      {
       LED = 0;  // LED OFF   
      }

  }
  return 0;
}


0 commentaires

3 Réponses :


2
votes

pourquoi ne pas envelopper le délai 1s dans une fonction fournissant un delay_s (uint32_t secondes) et dans une fonction fournissant un delay_m (uint32_t minutes)

void delay_s(uint32_t seconds)
{
  while(seconds){
    __delay_ms(1000);
    seconds--;
  }
}

void delay_m(uint32_t minutes)
{
  while(minutes){
    delay_s(60);
    minutes--;
  }
}


4 commentaires

Merci pour votre réponse. J'ai pensé à faire quelque chose comme ça mais je ne sais pas si c'est une bonne idée.


Comment utiliseriez-vous les interruptions et les minuteries? Y a-t-il des exemples?


Comme vous l'avez noté, cela bloquera tout. Le filetage doit entrer en jeu pour éviter cela.


@ M2T156 vous devez rechercher ceci dans les documents de votre chaîne d'outils, car cela dépend de différentes choses



1
votes

Simple. Machines à états et le minuteur interrompt et un compte à rebours d'une minute. Quelque chose comme ceci:

Clause de non-responsabilité - codée à l'aveugle

#define MINUTES_90 5400UL /* 90 seconds */

typedef enum
{
    /** Code operational */
    p_state_idle,
    /** Code waiting for 90 minutes */
    p_state_waiting
}p_state_t;

static unsigned long gSecondsRemaining = MINUTES_90;

int main()
{
    p_state_t gState = p_state_running;

    OPTION_REGbits.PSA = 0; /* Prescaler assigned */
    OPTION_REGbits.PS = 0b111; /* 256 prescaler */
    OPTION_REGbits.TMR0CS = 0; /* Fosc / 4 */
    INTCONbits.TMR0IE = 1; /* Timer 0 interrupt enabled */
    INTCONbits.PEIE = 1; /* Peripheral interrupts enabled */
    INTCONbits.GIE = 1; /* Global interrupts enabled */

    /** Default LED off */
    LED = 0;

    while (1)
    {
        switch (gState)
        {
        case p_state_idle:
            if (TRIGGER == 1)
            {
                LED = 1;  // LED ON
                gSecondsRemaining = MINUTES_90; /* Reset timer countdown */
                gState = p_state_waiting;
            }
            break;
        case p_state_waiting:
            /** can sleep here */
            if (gSecondsRemaining == 0)
            {
                gState = p_state_idle;
                LED = 0;
            }
            break;
        }
    }
}

void interrupt ISR()
{
    static unsigned char gSecond = 15;

    /** approx 15 Hz ? */
    if (INTCONbits.TMR0IF)
    {
        INTCONbits.TMR0IF = 0;

        if (gSecond > 0)
            gSecond--;

        if (gSecond == 0)
        {
            if (gSecondsRemaining > 0)
                gSecondsRemaining--;

            gSecond = 15;
        }
    }
}


0 commentaires

0
votes

Vous pouvez résoudre ce problème avec une fonction d'assemblage en ligne avec quelques boucles. Regardez ici: exemple: 30 min de retard


0 commentaires