2017-05-23 1 views
0

J'ai besoin d'aide J'ai ce programme basique de base pour jouer avec les LED dans une séquence d'entre eux en fonction de quel commutateur je pousse, ce que je voudrais savoir: Comment puis-je interrompre un (ou l'arrêter) et exécuter l'autre séquence quand je bascule l'autre commutateur et exécuter la nouvelle séquence mais pas celle avant, je me demandais comment d'autres programmes qui ont besoin d'abandonner les actions le font, car il sera dans la "boucle" avec des retards et des trucs, je suppose que mettre un si entre les lignes dans chaque led on et off le ferait, mais je ne pense pas que ce soit la manière correcte/efficace .. merci!Comment puis-je casser un si une variable change

#include <16f876.h> 
#use delay(clock=4M) 
#fuses XT,NOWDT 
#use standard_io(A) 
#use standard_io(B) 

int16 t0=2000; 
int16 t1=1000; 
int16 t2=1000; 
int16 t3=500; 

void main(){ 
    output_b(0b00000000); 
    while(TRUE){ 
     if(input(PIN_A0)==0){ 
     output_b(0b00000000); 
     output_b(0b00011000); 
     delay_ms(t0); 
     output_b(0b00100100); 
     delay_ms(t0); 
     output_b(0b01000010); 
     delay_ms(t0); 
     output_b(0b10000001); 
     delay_ms(t0); 
     } 
     if(input(PIN_A1)==0){ 
     output_b(0b00000000); 
     output_b(0b00000001); 
     delay_ms(t1); 
     output_b(0b00000011); 
     delay_ms(t1); 
     output_b(0b00000111); 
     delay_ms(t1); 
     output_b(0b00001111); 
     delay_ms(t1); 
     output_b(0b00011111); 
     delay_ms(t1); 
     output_b(0b00111111); 
     delay_ms(t1); 
     output_b(0b01111111); 
     delay_ms(t1); 
     output_b(0b11111111); 
     delay_ms(t1); 
     } 
     if(input(PIN_A2)==0){ 
     output_b(0b10000000); 
     delay_ms(t2); 
     output_b(0b11000000); 
     delay_ms(t2); 
     output_b(0b11100000); 
     delay_ms(t2); 
     output_b(0b11110000); 
     delay_ms(t2); 
     output_b(0b11111000); 
     delay_ms(t2); 
     output_b(0b11111100); 
     delay_ms(t2); 
     output_b(0b11111110); 
     delay_ms(t2); 
     output_b(0b11111111); 
     delay_ms(t2); 
     } 
     if(input(PIN_A3)==0){ 
     output_b(0b00000000); 
     output_b(0b00000001); 
     delay_ms(t3); 
     output_b(0b00000000); 
     delay_ms(t3); 
     output_b(0b00000011); 
     delay_ms(t3); 
     output_b(0b00000000); 
     delay_ms(t3); 
     output_b(0b00000111); 
     delay_ms(t3); 
     output_b(0b00000000); 
     delay_ms(t3); 
     output_b(0b00001111); 
     delay_ms(t3); 
     output_b(0b00000000); 
     delay_ms(t3); 
     output_b(0b00011111); 
     delay_ms(t3); 
     output_b(0b00000000); 
     delay_ms(t3); 
     output_b(0b00111111); 
     delay_ms(t3); 
     output_b(0b00000000); 
     delay_ms(t3); 
     output_b(0b01111111); 
     delay_ms(t3); 
     output_b(0b00000000); 
     delay_ms(t3); 
     output_b(0b11111111); 
     delay_ms(t3); 
     } 
    } 
} 
+0

Peut-il y avoir plusieurs lumières allumées en même temps ou seulement une à la fois? Que se passe-t-il si, au lieu d'utiliser 3 if, vous utilisez une branche if/else? –

+0

c'est un à la fois. –

Répondre

1

Vous pouvez écrire votre propre fonction delay_ms quelque chose comme ceci:

bool my_delay_ms(int mstime) { 
    int current = 0; 
    while (current < mstime) { 
     delay_ms(10); 
     current += 10; 
     if (something?) { 
      return true; 
     } 
    } 
    return false; 
} 

Puis tous delay_ms remplacer avec if (my_delay_ms(t0)) continue;.

Vous pouvez changer le 10 pour le plus souvent que vous voulez interroger pour le signal d'interruption. La condition détecte le signal d'interruption et le continue permet à votre boucle while de passer au cycle suivant pour modifier la séquence si nécessaire.

+0

Salut, merci de répondre, j'ai une question, continue le "if (my_delay_ms (t0));" Attend-il réellement le temps que je l'ai mis en place? ou vérifie-t-il que ce soit vrai ou faux dans ce moment précis et va à la ligne suivante? J'ai ce doute .. –

+0

Il évaluera la fonction entière avant de quitter la fonction. Si l'indicateur d'interruption n'est jamais vrai, la fonction s'exécute pendant tout le temps, si elle se termine tôt, elle déclenchera l'instruction continue. –

+1

simple et travaillé !, Bien que je devais utiliser un int au lieu d'un booléen (bool n'existe pas ici, et retourner 1 et 0), et pour t0, t1, t2, t3 et mstime je devais les déclarer comme int16 (Idk la raison mais juste avec int le temps est allé 10x plus vite, même si int16 et int sont techniquement les mêmes ...) merci –

1

Vous pouvez configurer un minuteur qui se déclenche toutes les millisecondes, puis réécrire le code en tant que machine d'état. De cette façon, vous ne perdez pas de cycles de cpu dans les routines de retard, et vous êtes capable de répondre aux pressions de bouton immédiatement, bien au moins dans une milliseconde, ce qui à l'utilisateur est immédiat.

La machine d'état conserve la trace d'une variable. Le nombre représente l'état dans lequel il se trouve. Chaque fois qu'un état est exécuté, l'état peut changer. L'état modifié est exécuté la prochaine fois que le temporisateur se déclenche. Assurez-vous que votre code s'exécute pendant la période de temporisation, n'utilisez donc pas de délais mais utilisez la machine d'état pour effectuer les retards, ou un autre temporisateur si vous avez besoin d'une résolution différente. timing.

Je vous laisse le soin de configurer les registres de minuterie et d'interruption.

/* global variables */ 
    int state = 0; 
    unsigned char delaycnt = 0; 
    char millisecond_flag = 0; 

    void DoStateMachine() 
    {  
    switch(state) 
    { 
     case 100: 
      output_b(0b00000000); 
      output_b(0b00011000); 
      state++; 
      delaycnt = 10; 
      break; 
     case 101: 
      delaycnt--; 
      if(delaycnt == 0) state = 102; 
      break; 
      case 200: 
      output_b(0b00000000); 
      output_b(0b00000001); 
      state++; 
      delaycnt = 10; 
      break; 
     case 201: 
      delaycnt--; 
      if(delaycnt == 0) state = 202; 
      break; 
     default: 
      state = 0; // do nothing 
      break; 
     } 
    } 

    void CheckButtons() 
    { 
    // Do button debounce here 
    if(BUTTON1 == 1) 
     state = 100; 
    if(BUTTON2 == 1) 
     state = 200; 
    } 

    void main() 
    { 
    //Setup timer here 

    while(1) 
    { 
     if(millisecond_flag == 1) 
     { 
      CheckButtons(); 
      DoStateMachine(); 
      millisecond_flag = 0; 
     } 
     //sleep device? 
    } 
    } 

    // Handle interrupt 
    void interrupt ISR() 
    { 
    if(TMR1IF == 1) 
    { 
     millisecond_flag = 1; 
     TMR1IF = 0; 
    } 
    }