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; }
3 Réponses :
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--; } }
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
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; } } }
Vous pouvez résoudre ce problème avec une fonction d'assemblage en ligne avec quelques boucles. Regardez ici: exemple: 30 min de retard