Software

USART part 1, schrijven naar usart. (Xmega)

Door mad_max234 op donderdag 12 december 2013 20:09 - Reacties (7)
Categorie: Software, Views: 5.433

Deel 1, het schrijven naar usart, deel 2 zal het lezen zijn. Zal in dit deel code bespreken hoe je de usart moet instellen en hoe je met printf een string kan versturen. De code bestaat uit twee functies, uart_intit en uart_putchar, en word met stdio ondersteunt om char één voor één naar de TX buffer te sturen. Voorbeeld code is voor 9600bps uart, uiteraard kan je dat aanpassen. :)

De uart_init functie

Port instellen:
Hier vul je de port in van de uart, TX moet hoog zijn en als output ingesteld worden, RX moet als input ingesteld worden, dat staat bij default goed dus hoeft niet ingesteld te worden, register heeft standaard 0.
C:
1
2
PORTD.DIRSET = PIN3_bm; //TX pin als output.
    PORTD.OUTSET = PIN3_bm; //TX pin hoog.



Bandbreedte instellen:
Om bandbreedte te bepalen is het makkelijkste om calculator te gebruiken.
http://www.avrcalc.elektr...mega/baud_rate_calculator

Je hebt twee waardes, BSCALE (BAUDCTRLB) en BSEL(BAUDCTRLA ). Word aangeraden om binnen de 0.5% error te blijven. Ik heb in voorbeeld code gekozen voor 9600bps usart en de xmega draait op zijn 2Mhz defualt snelheid. Vul bij fper [Hz]: 2000000 in en bij desired baud rate [bps]: 9600. Dan kijk je in de tabel en zoek je geschikte waarde uit. BSCALE 0 met BSEL 12 geeft 0.16% error, prima geschikt.
C:
1
2
USARTD0.BAUDCTRLB = 0;      
USARTD0.BAUDCTRLA = 12;



Modes instellen:
C:
1
2
USARTD0.CTRLA = 0;              // Geen usart interrupts.
    USARTD0.CTRLC = 0x03;           // async, no parity, 8 bit data, 1 stop bit.



Enable USART:
C:
1
USARTD0.CTRLB = USART_TXEN_bm;



De printf functie
Deze code hieronder is eigenlijk niks meer dan marco voor stdout, maakt een buffer tussen printf en uart_putchar. Is nodig om printf stream naar juiste functie te verwijzen. Zal hier nu niet veel verder op ingaan, stdio verdient een eigen post.
C:
1
static FILE mystdout = FDEV_SETUP_STREAM (uart_putchar, NULL, _FDEV_SETUP_WRITE);




De usart_putchar functie

Voordat we gaan zenden moeten we even kijken of de TX buffer klaar is. We kijken of de USART_DREIF(Data Register Empty Flag) gezet is, als buffer vol is blijft de while loop hier net zo lang hangen tot die leeg is.
C:
1
while ( !( USARTD0.STATUS & USART_DREIF_bm) );



We kunnen nu de buffer schrijven naar de USART
C:
1
USARTD0.DATA = c;




Volledige code:
* voorbeeld werkt zonder aanpassingen op de A4 serie, getest op atxmgea16a4, atxmgea32a4 en atxmgea32a4u.
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <stdio.h>
#include <avr/io.h>

static int uart_putchar(char c, FILE *stream);
static void uart_init (void);

static FILE mystdout = FDEV_SETUP_STREAM (uart_putchar, NULL, _FDEV_SETUP_WRITE);


int main (void)
{
    uart_init();
    stdout = &mystdout;
    
    while (1)
    {
        
    printf("Hallo wereld.\n");
    
    }   
}


static int uart_putchar (char c, FILE *stream)
{
    if (c == '\n') /
    uart_putchar('\r', stream);
    
    //Wachten dat de TX buffer leef is
    while ( !( USARTD0.STATUS & USART_DREIF_bm) );
    
    // stuur char naar de TX buffer
    USARTD0.DATA = c;
    
    return 0;
}

static void uart_init (void)
{
    PORTD.DIRSET = PIN3_bm; //TX pin als output.
    PORTD.OUTSET = PIN3_bm; //TX pin hoog.
    
    //Bandbreedte instellen. 
    USARTD0.BAUDCTRLB = 0;      
    USARTD0.BAUDCTRLA = 12;
    
    //Usart mode, 
    USARTD0.CTRLA = 0;              // Geen uart interrupts.
    USARTD0.CTRLC = 0x03;           // async, no parity, 8 bit data, 1 stop bit.
    
    // Enable usart
    USARTD0.CTRLB = USART_TXEN_bm;
}



Links:
http://www.atmel.com/Images/doc8408.pdf