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