2016-04-13 1 views
2

Je sais que cela semblera absurdement simple. Mais je ne peux pas penser, ou définir de façon adéquate pour rechercher, comment avoir du code en C pour avoir une LED clignotante à une fréquence constante pendant que le reste du programme fonctionne. Réglez et oubliez quelque chose. J'ai vu filetage aujourd'hui, même si cela semblait un peu compliqué pour ma compréhension de base.Courir le code en attendant le code

Je suis en train de développer sur Windows, et en cours d'exécution sur MikroC pour un PIC18, mais j'avais les mêmes pensées quand je travaillais sur un projet différent sur un Arduino.

+0

Regardez dans l'obtention d'un environnement de développement intégré (IDE). Peut-être que Visual Studio aurait déjà une fonctionnalité qui répond à vos besoins (et ils ont aussi une version gratuite). –

+0

Connaissez-vous le multi-threading? –

+1

Sur quel système d'exploitation exécutez-vous le programme? – user3386109

Répondre

1

Voir les réponses à Multithreading using C on PIC18

Pour le développement C standard, cela nécessiterait multithreading, mais this answer suggère d'utiliser une boucle d'événements.

+0

Multi-thread sur les microcontrôleurs 8 bits est un non-sens. Les boucles multi-threading ou événementielles ne sont pas nécessaires pour quelque chose d'aussi trivial et rapide que le basculement d'une broche d'E/S. – Lundin

0

Sur un PIC, vous ne passeriez pas nécessairement directement de quelque chose d'aussi simple que des boucles d'attente occupée à quelque chose d'aussi compliqué que des bibliothèques multithread, comme proposé dans certains commentaires. Supposons que vous clignotiez votre LED chaque seconde dans une boucle - Cela donne du code dans cette boucle (ou appelé depuis l'intérieur de cette boucle) presque 1 seconde pour exécuter quelque chose de différent. Si vous pouvez découper ces tâches en tranches si petites qu'elles rentrent dans l'intervalle "quand vous avez besoin d'être de retour" pour faire clignoter la LED, c'est un début. De toute évidence, si vous exécutez du code arbitraire dans la boucle clignotante, la fréquence de vos clignotements sera affectée par le temps que prennent ces autres parties du code et vous ne pourrez plus utiliser le CPU comme base de temps - Vous avez besoin de quelque chose de différent pour vérifier si le clignotement est dû. La plupart des microcontrôleurs disposent d'une minuterie qui vous permet de le faire. Lire une minuterie libre pour vérifier si vous "devez clignoter" serait la première étape simple. Voir ci-dessous pseudo-code:

while (1){ 
    if (((time = readTimer()) - oldTime) > INTERVAL){ 
    /* Timer run-around ignored for reasons of simplicity */ 
    oldTime = time; 
    blink(); 
    } 
    else 
    doSomethingElse(); 
} 

Notez le somethingElse() doit être terminé dans le moins de temps possible comme temps courir affecte la précision de votre clignements.

Si vous souhaitez toujours que le clignotement soit à des intervalles exacts, vous devez rechercher les routines de service d'interruption. Découvrez comment vous déclenchez une interruption avec la fréquence de clignotement de la minuterie et faites clignoter la routine de service d'interruption. Cela libère votre boucle principale de faire cela et vous pouvez faire toutes les tâches de longue durée que vous voulez là-bas. La minuterie déclenchera une interruption à la fréquence voulue, et la routine de service d'interruption allumera les lumières.

+0

Cela ne donnera aucune performance en temps réel quoi-que-jamais. Même si 'doSomethingElse' est plus rapide que le cycle de clignotement, vous obtiendrez des retards constants dans la fréquence de clignotement dans l'intervalle de 0 <= delay <= time pour exécuter' doSomethingElse'. Et il utilise un microcontrôleur 8 bits avec un ancien noyau de CPU des années 1980, il ne devrait certainement pas regarder dans les bibliothèques multi-threading. – Lundin

+0

J'essayais de faire expérimenter l'OP et, à l'aide de petites étapes, d'arriver à des solutions acceptables. Même s'il * voit * les variations de la fréquence de clignotement, il aurait appris quelque chose (il ne demandait pas de performance en temps réel). En supposant qu'il ne s'agit pas de contrôler un robot Mars, cela semblait être une approche réalisable. – tofro

+0

En fonction de la durée du retard, la boucle peut provoquer un scintillement suffisamment important pour que l'œil humain puisse le remarquer. Cela étant dit, c'est aussi une très mauvaise idée d'introduire _tight coupling_ dans vos programmes. Votre boucle a un couplage étroit entre le code LED et quelque chose de complètement non lié. Un jour quelqu'un va changer un code de socket TCP/IP et soudainement la LED "hors du café" commence à clignoter rapidement. Ce n'est pas comme ça que vous concevez des programmes robustes. – Lundin

1

La plupart des microcontrôleurs disposent de temporisateurs matériels disponibles pouvant être utilisés à de telles fins. Ainsi, votre code dans la minuterie basculera le clignotement et le logiciel principal peut définir des variables qui indique au code minuterie si elle clignote ou non

int shouldblink = 0; 
int ledstatus = 0; 
void OnTimer(void) /* configure your microcontroller to call this on timer */ 
{ 
    if (ledstatus) 
    { 
     turnoffLED(); 
     ledstatus = 0; 
    } 
    else { 
     if (shouldblink) 
     { 
      turnonLED(); 
      ledstatus = 1; 
     } 
    } 
} 

int main() 
{ 
    configure_timer(); 
    shouldblink = 1; 
    do_slow_work(); 
    shouldblink = 0; 
} 
+0

Sur un PIC, votre 'main' devrait mieux ne pas simplement se terminer, mais rester dans une boucle sans fin. – tofro

1

Il suffit d'utiliser le matériel de microcontrôleur destiné à tel. Sortie comparer les minuteries, le matériel PWM, etc. Si vous n'avez pas un tel matériel, basculer le port d'E/S d'une interruption devrait être suffisamment précis dans la plupart des cas.