invio di dati dal microcontrollore al computer utilizzando la serie tiva c

Sto utilizzando Tiva C Series TM4C123GH6PM con Code Composer Studio per ottenere dati da un altro microcontrollore dello stesso tipo. Bene, ottengo i dati in byte. L’objective del progetto è assemblare ogni 8 byte e convertirli in doppio, quindi inviare questi due al computer. Devo usare USART per inviare i dati al computer.

Quando uso USART, ho due metodi:

  1. Uno per ottenere dati da USART_x: UARTCharGet (UART1_BASE)
  2. L’altro per inviare i dati su USART_x: UARTCharPut (UART0_BASE, d)

Il problema consiste nell’avere due metodi che accettano solo caratteri. Quindi, usare questi metodi per il doppio è imansible poiché un doppio è 8 byte e un carattere è un byte. Sto cercando di inviare i doppi al mio computer. Qualche idea?

Il secondo problema è scrivere un programma dal lato del computer per ottenere i dati (byte) dal microcontrollore.

Dovrei scrivere questo programma in c (un’alternativa sta usando Matlab perché userò questi dati per la simulazione)? Come posso accedere a com-Port in c (o in MATLAB se è ansible)?

In generale si sta affrontando qui il problema della serializzazione e l’approccio migliore sarebbe utilizzare una libreria specializzata per questo scopo.

In un modo sporco ma semplice puoi risolverlo in questo modo. Devi semplicemente assemblare correttamente i dati sull’altro lato per raddoppiare.

typedef union _MyDouble { double d; unsigned char bytes[sizeof(double)]; } MyDouble; MyDouble my_double; my_double.d = 1.234; for(i=0; i < sizeof(double); i++) { UARTCharPut(UART0_BASE, (char)my_double.bytes[i]). } 

L'altra cosa è che se stai usando UART dovresti incapsulare questa unione in qualche cornice, per esempio per rimontare con successo questa parte dall'altra parte.

  _____________ ________ __________ ___________ ________ | | | | | | | FRAME_BEGIN | LENGTH | MyDouble | FRAME_END | CRC-8? | |_____________|________|__________|___________|________| 

La prossima cosa è che probabilmente dovresti imporre l'allineamento dei byte su questa struttura che viene eseguita dalle direttive del compilatore. Assicura che la tua struct non abbia padding byte ecc. E assegni dimensioni minime richieste. Questo è molto popolare nelle applicazioni incorporate, casi in cui alcuni oggetti binari verranno trasmessi sull'interfaccia seriale, il che è esattamente il tuo caso. Una soluzione così semplice potrebbe funzionare su specifiche configurazioni hw + sw, ma sicuramente non è portatile e una buona soluzione dal punto di vista professionale.

È necessario trovare un modo per suddividere grandi quantità di dati e inviarli al client, che quindi ha bisogno di un modo per riassemblare i dati e anche sapere quando tali dati vengono inviati.

Un approccio molto semplice sarebbe quello di convertire tutte le cifre del doppio in caratteri. Inefficiente, ma fa il lavoro abbastanza facilmente, come mostrato di seguito. Il motivo per cui è preferibile è perché ti consente di creare facilmente il tuo “set di istruzioni”. Ad esempio, puoi prenotare il carattere '!' come “la lettera che segue ! denota un’istruzione speciale”, quindi quando il client vede la sequenza ” !d “, sa che i seguenti 32 byte di dati rappresentano un double e riassemblarlo.

Se si inviano semplicemente i byte non elaborati, diventa più complicato quando si desidera creare codici di escape o codici operativi per segnalare circostanze particolari al cliente.

Elenco dei codici


 #include  #define BUF_LEN (32) typedef union { float f; struct { unsigned int mantissa : 23; unsigned int exponent : 8; unsigned int sign : 1; } parts; } double_cast; int main(void) { double_cast d1; d1.f = 0.15625; printf("sign = %x\n",d1.parts.sign); printf("exponent = %x\n",d1.parts.exponent); printf("mantissa = %x\n",d1.parts.mantissa); char buf[BUF_LEN+1] = { 0 }; snprintf(buf, BUF_LEN+1, "%01X%08X%023X", d1.parts.sign, d1.parts.exponent, d1.parts.mantissa); // Send over UART printf("Double as string: [%s]\n", buf); //UART_printf("!d%s", buf); return 0; } 

Uscita di esempio


 sign = 0 exponent = 7c mantissa = 200000 Double as string: [00000007C0000000000000000020000] 

Il credito per il codice per rompere un doppio in una stringa va a u / eran.

Un’altra soluzione (simile alla soluzione di Krystian) che funziona per me. Ho definito una funzione che ha come parametri un doppio e una matrice di byte. Il doppio deve essere convertito in una matrice di byte. Ecco perché ho definito una matrice di byte che ha una dimensione di 8 byte. Ecco alcuni codici:

 unsigned char bytesArray[sizeof(double)]; unsigned char * doubleToBytes(double num,unsigned char bytes []){ return memcpy(bytes,&num,sizeof(double)); } 

Dopo aver ottenuto i byte nella matrice, è ansible inviare i dati utilizzando il seguente ciclo:

 for(i=0;i