Come posso risolvere questo codice per consentire al mio AVR di parlare tramite la porta seriale?

StackOverflow https://stackoverflow.com/questions/846206

  •  21-08-2019
  •  | 
  •  

Domanda

Ultimamente mi sto strappando i capelli cercando di collegare un ATmega162 al mio STK200 per comunicare con il mio computer tramite RS232.Ho controllato e assicurato che l'STK200 contenga un chip MAX202CPE.

Ho configurato il chip per utilizzare il suo clock interno da 8 MHz e l'ho diviso per 8.

Ho provato a copiare il codice dalla scheda tecnica (e ho apportato modifiche laddove il compilatore si è lamentato), ma senza alcun risultato.

Il mio codice è qui sotto, qualcuno potrebbe aiutarmi a risolvere i problemi che sto riscontrando?

Ho confermato che la mia porta seriale funziona su altri dispositivi e non è difettosa.

Grazie!

#include <avr/io.h>
#include <avr/iom162.h>

#define BAUDRATE 4800

void USART_Init(unsigned int baud)
{
    UBRR0H = (unsigned char)(baud >> 8);
    UBRR0L = (unsigned char)baud;

    UCSR0B = (1 << RXEN0) | (1 << TXEN0);

    UCSR0C = (1 << URSEL0) | (1 << USBS0) | (3 << UCSZ00);
}

void USART_Transmit(unsigned char data)
{
    while(!(UCSR0A & (1 << UDRE0)));

    UDR0 = data;
}

unsigned char USART_Receive()
{
    while(!(UCSR0A & (1 << RXC0)));

    return UDR0;
}

int main()
{

    USART_Init(BAUDRATE);

    unsigned char data;

    // all are 1, all as output
    DDRB = 0xFF;

    while(1)
    {
        data = USART_Receive();

        PORTB = data;

        USART_Transmit(data);


    }
}
È stato utile?

Soluzione 4

Dopo aver letto la scheda tecnica un po 'più a fondo, sono stato in modo non corretto l'impostazione della velocità di trasmissione. La scheda tecnica ATmega162 ha avuto una tabella di frequenze di clock tramato contro velocità di trasmissione e l'errore corrispondente.

Per una velocità di 4800 baud e una frequenza di clock di 1 MHz, l'errore è stato dello 0,2%, che era accettabile per me. Il trucco stava passando 12 alla funzione USART_Init (), invece di 4800.

Spero che questo aiuti qualcun altro fuori!

Altri suggerimenti

Ho commentato la risposta di Greg, ma vorrei aggiungere una cosa. Per questo tipo di problema il metodo gold standard di debug è al primo capiscono di comunicazione seriale asincrona, quindi per ottenere un oscilloscopio e vedere cosa succede sulla linea. Se i caratteri vengono scambiati ed è solo un problema di velocità di trasmissione questo sarà particolarmente utile in quanto è possibile calcolare la velocità di trasmissione che state vedendo e quindi regolare il divisore di conseguenza.

Ecco un super veloce innesco, senza dubbio si può trovare qualcosa di molto più completa su Wikipedia o altrove.

Supponiamo 8 bit, nessuna parità, 1 bit di stop (la configurazione più comune). ( '?' = ASCII) Poi, se il personaggio viene trasmesso è dire 0x3F, poi la linea è simile al seguente;

...--+   +---+---+---+---+---+---+       +---+--...
     | S | 1   1   1   1   1   1 | 0   0 | E
     +---+                       +---+---+

L'elevata (1) livello è + 5V chip e -12V dopo la conversione a livelli RS232.

La bassa (0) è 0V chip e + 12V dopo la conversione a livelli RS232.

S è il bit di start.

Poi abbiamo 8 bit di dati, meno significativo prima, ecco 00.111.111 = 0x3f = '?'.

E è la fermata (e per la fine) bit.

Ora sta avanzando da sinistra a destra, come un display oscilloscopio, se la velocità di trasmissione è 4800, allora ciascuno campate bit (1/4800) secondi = 0,21 millisecondi (circa).

Le opere ricevitore campionando la linea e alla ricerca di un fronte di discesa (una linea quiescente è semplicemente logico '1' tutto il tempo). Il ricevitore conosce la velocità di trasmissione, e il numero di bit di avvio (1), quindi misura una volta mezzo bit dal fronte di discesa per trovare il centro del bit di inizio, poi campioni i tempi di bit linea 8 in successione dopo che per raccogliere i bit di dati. Il ricevitore quindi attende ancora una volta bit (fino a metà strada attraverso il bit di stop) e inizia a cercare un altro bit di inizio (cioè bordo di discesa). Nel frattempo il carattere letto viene messo a disposizione del resto del sistema. Il trasmettitore garantisce che il fronte di discesa successivo non inizia fino a quando il bit di stop è completa. Il trasmettitore può essere programmato per attendere sempre più a lungo (con bit di stop supplementari), ma che è un problema di eredità, bit di stop in più erano tenuti solo con hardware molto lento e / o configurazioni software.

Non ho materiale di riferimento a portata di mano, ma il registro UBRR velocità di trasmissione di solito contiene un valore divisore, piuttosto che la velocità di trasmissione desiderata per sé. Un breve ricerca su Google indica che il valore divisore corretto per 4800 baud può essere 239. Così provare:

divisor = 239;
UBRR0H = (unsigned char)(divisor >> 8);
UBRR0L = (unsigned char)divisor;

Se questo non funziona, verificare con la documentazione di riferimento per la vostra particolare chip per il corretto formula di calcolo divisore.

Per eseguire il debug della comunicazione UART, ci sono due cose utili da fare:

1) Fai un loopback sul connettore e assicurati di poter rileggere ciò che scrivi.Se invii un carattere e lo ricevi esattamente, sai che l'hardware è cablato correttamente e che almeno il set di base della configurazione del registro UART è corretto.

2) Invia ripetutamente il carattere 0x55 ("U") - il modello di bit binario 01010101 ti permetterà di vedere rapidamente la larghezza di bit sull'oscilloscopio, che ti permetterà di verificare che l'impostazione della velocità sia corretta.

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