Domanda

Sto facendo comunicare in modalità wireless un microcontrollore 8051 con un computer. Il microcontrollore invierà una stringa alla sua porta seriale (DB9) e il computer riceverà questa stringa e la manipolerà.

Il mio problema è che non so come fare in modo che l'8051 trasmetta la stringa una sola volta. Dato che devo manipolare la stringa sul PC, questa deve essere ricevuta una sola volta. Attualmente, anche se nel codice C sto inviando la stringa una volta, sul mio computer ricevo continuamente la stessa stringa. Presumo che ciò sia dovuto al fatto che qualunque cosa sia presente nell'SBUF viene continuamente trasmessa. Esiste un modo per inviare la mia stringa una sola volta? C'è un modo per svuotare SBUF?

Ho provato a usare il pin RTS (Request to Send) (7th pin) sul DB9 perché ho letto da qualche parte che se negassi la tensione su quel pin, fermerebbe il flusso di dati alla porta seriale. Quindi quello che ho fatto è stato programmare il mio microcontrollore per inviare la stringa e quindi inviare il livello logico 0 a un pin di uscita collegato al mio pin DB9 RTS. Tuttavia, non ha funzionato.

Qualcuno ha qualche suggerimento? Li apprezzerei davvero.

Modifica

Il software che sto usando sul PC è X-CTU per i moduli Xbee. Questo è il codice sul mio microcontrollore:

include reg51.h 
void SerTx(unsigned char);  
void main(void)  
{  
  TMOD = 0x20;  
  TH1 = 0xFD;  
  SCON = 0x50;  
  TR1 = 1;   

  SerTx('O');  
  SerTx('N');  
  SerTx('L');  
  SerTx('Y'); 

}

void SerTx(unsigned char x)  
{  
  SBUF = x;  
  while(TI==0);   
  TI = 0;   
}  

Qualcuno potrebbe verificare che in effetti sta inviando la stringa una sola volta?

Modifica

Sembra che Steve, Brookesmoses e Neil abbiano colpito l'unghia alla testa quando hanno detto che era quello che stava succedendo DOPO la mia funzione principale che stava causando il problema. Ho appena provato il codice suggerito da Steve (più specificamente for (;;); e la definizione di serTX al di fuori di main) e ha funzionato perfettamente. Il controller viene probabilmente riavviato e quindi lo stesso codice continua a ripetersi.

Grazie mille per l'aiuto! :)

È stato utile?

Soluzione

Puoi confermare che l'8051 sta davvero inviando i dati una sola volta? Un modo per verificare sarebbe quello di utilizzare un ambito per vedere cosa sta succedendo sul pin TX di UART.

Quale software stai usando sul PC? Suggerirei di utilizzare semplici software di comunicazione come HyperTerminal o PuTTY . Se mostrano più volte la stringa inviata al PC, è probabile che l'errore sia nel software in esecuzione sull'8051.

MODIFICA: Ad essere onesti, questo suona come il tipo di debug che gli ingegneri devono affrontare su base regolare, quindi è una buona opportunità per te per praticare un buon problema metodico vecchio stile- solving.

Se posso essere molto schietto, ti suggerisco di fare quanto segue:

  1. Debug. Prova le cose, ma non indovinare . Sperimentare. Apporta piccole modifiche al tuo codice e guarda cosa succede. Prova tutto ciò che ti viene in mente. Cerca nel Web per ulteriori informazioni.
  2. Se ciò non produce una soluzione, torna qui e forniscici tutte le informazioni di cui abbiamo bisogno. Ciò include parti rilevanti del codice, dettagli completi dell'hardware che stai utilizzando e informazioni su ciò che hai provato nel passaggio 1.

MODIFICA: Non ho il rappresentante per modificare la domanda, quindi ecco il codice pubblicato dall'OP nel commento alla sua domanda:

#include<reg51.h>

void SerTx(unsigned char);

void main(void)
{
    TMOD = 0x20; TH1 = 0xFD; SCON = 0x50; TR1 = 1;
    SerTx('O'); SerTx('N'); SerTx('L'); SerTx('Y');

    void SerTx(unsigned char x)
        { SBUF = x; while(TI==0); TI = 0; } 
}

Come menzionano Neil e Brooksmoses nelle loro risposte, in un sistema incorporato, la funzione principale non può mai terminare. Quindi o devi mettere il tuo codice in un ciclo infinito (che potrebbe essere ciò che sta accadendo inavvertitamente), o aggiungere un ciclo infinito alla fine, quindi il programma si interrompe efficacemente.

Inoltre, la funzione SerTx deve essere definita all'esterno di main. Questo può essere sintatticamente corretto, ma mantiene le cose semplici non dichiarando funzioni all'interno di altre funzioni.

Quindi prova questo (ho anche aggiunto alcuni commenti nel tentativo di facilitare la comprensione del codice):

#include<reg51.h>

void SerTx(unsigned char);

void main(void)
{
    /* Initialise (need to add more explanation as to what
        each line means, perhaps by replacing these "magic
        numbers" with some #defines) */
    TMOD = 0x20;
    TH1  = 0xFD;
    SCON = 0x50;
    TR1  = 1;

    /* Transmit data */
    SerTx('O'); SerTx('N'); SerTx('L'); SerTx('Y');

    /* Stay here forever */
    for(;;) {}

}

void SerTx(unsigned char x)
{
    /* Transmit byte */
    SBUF = x;

    /* Wait for byte to be transmitted */
    while(TI==0) {}

    /* Clear transmit interrupt flag */
    TI = 0;
} 

Altri suggerimenti

Il codice che hai pubblicato non ha loop in main (), quindi devi determinare cosa fa il runtime C del tuo compilatore quando main () ritorna dopo aver inviato 'Y'. Dato il tuo problema, immagino che il compilatore generi del codice per fare un po 'di pulizia e quindi riavviare il micro (forse un reset hardware, forse solo riavviando il runtime C). Sembra che il tuo programma funzioni esattamente come l'hai scritto, ma hai ignorato ciò che accade prima e dopo che viene chiamato main ().

Se vuoi che la tua stringa sia inviata una volta e solo una volta, mai, allora hai bisogno di qualcosa come mentre (1) {} aggiunto dopo l'invio dell'ultimo carattere. Ma poi il tuo programma non sta facendo nulla - eseguirà semplicemente un ciclo vuoto per sempre. È necessario un ripristino (come il ciclo di accensione) per ricominciare e inviare la stringa.

Nota che se il tuo micro ha un timer watchdog, potrebbe intervenire e forzare un reset imprevisto. In tal caso, la stringa verrà inviata una volta per ogni ripristino del watchdog (che potrebbe essere simile a una volta al secondo, con una frequenza che dipende dall'hardware).

Inoltre, avere serTx () definito nidificato all'interno di main () probabilmente non è quello che vuoi.

È difficile dire quale sia il problema senza vedere il codice 8051. Ad esempio, un errore logico su quel lato potrebbe portare all'invio più volte dei dati oppure il software 8051 potrebbe attendere un ACK che non viene mai ricevuto, ecc.

Normalmente su un codice 8051 deve inviare esplicitamente ogni carattere, ma suppongo che questo sia gestito per te dal tempo di esecuzione C.

L'uso di RTS / CTS (Request To Send / Clear To Send) è per il controllo del flusso (cioè per prevenire sovraccarichi del buffer - i buffer sono di solito piuttosto piccoli su questi microcontrollori) e non fermare del tutto la trasmissione.

Facendo eco alla risposta di Neil (in una risposta, dato che non ho ancora la risposta per commentare): in una tipica situazione di microcontrollore senza un sistema operativo, non è immediatamente chiaro quale sia la funzione exit () che viene chiamata implicitamente alla fine of main () dovrebbe fare - o, più precisamente, non può fare il solito "fine del programma e tornare al sistema operativo", perché non c'è alcun sistema operativo su cui tornare.

Inoltre, in un'applicazione reale, non si desidera quasi mai arrestare il programma, a meno che non si spenga il sistema. Quindi una cosa che l'implementazione exit () non dovrebbe assolutamente fare è occupare molto spazio nel codice.

In alcuni sistemi su cui ho lavorato, exit () non è effettivamente implementato affatto - se non lo userai, non sprecare nemmeno un byte su di esso! Il risultato è che quando il percorso di esecuzione arriva alla fine di main (), il chip si sposta semplicemente in una terra di lala eseguendo qualunque cosa si trovi nel prossimo bit di memoria, e in genere finisce rapidamente o bloccato in un loop o errore con un codice operativo illegale. E il solito risultato di un errore con un codice operativo illegale è ... riavviare il chip.

Sembra una teoria plausibile per quello che sta succedendo qui.

Questo particolare articolo è per il montaggio, non per C, ma potrebbe rivelarsi utile: http://www.8052.com/tutser.phtml

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top