Skocz do zawartości

UART Atmega8A - krzaczki w terminalu


Pomocna odpowiedź

Napisano

Cały dzień już się męczę z tym i nie wiem o co chodzi. Kod skopiowany z datasheet. Jedynie UBRR wpisane z tabelki, bo bez tego w debugerze w Atmel Studio MYUBRR wynosił 0. Dodatkowo, URSEL nie zmienia sposobu zapisu, ale czytałem, że to problem debuggera, w procku jest ok. Coś wysyła, jednak to nie jest to co bym chciał.

#define FOSC 1000000
#include <avr/io.h>
#include <util/delay.h>

//void setAngle(int angle);
//void InitServ(void);

#include <inttypes.h>
#include <avr/interrupt.h>
#include <string.h>
#include <stdint.h>
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1


void main(void)
{
unsigned char z = "a";

USART_Init(12);
//InitServ();
//int i;
while(1) {

	USART_Transmit(z);

	_delay_ms(1000);
}

}


void USART_Init (unsigned int ubrr)
{
// Set baud rate
UBRRH = (unsigned char)(ubrr>>8);
UBRRL = (unsigned char)ubrr;

UCSRB = (1<<RXEN)|(1<<TXEN);
/* Set frame format: 8data, 2stop bit */
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);


}

void USART_Transmit( unsigned char data )
{

/* Wait for empty transmit buffer */
while ( !( UCSRA & (1<<UDRE)) ) ;
/* Put data into buffer, sends the data */
UDR = data;
}

A jak policzyłeś ten UBRR? Skąd wziąłeś 12? Bo mi wydaje się, że (1000000/16/9600)-1 daje w wyniku 5.5

Już tego widać, że przy taktowaniu 1MHz nie możesz osiągnąć prędkości 9600, bo po zaokrągleniu podzielnika do 5 lub 6 błąd będzie zbyt duży.

9600bps bez U2X nie uzyskasz na 1MHz.

A UBBR lepiej makrem wyliczyć niż przepisywać z kalkulatorów.

#define BAUD_CALC(x) ((F_CPU+(x)*8UL) / (16UL*(x))-1UL)

No właśnie nie, bo jak napisał kolega Fifou: "UBRR wpisane z tabelki".

Obie metody - i kalkulatorowa i tabelkowa wymagają uwagi. W każdej może się palec omsknąć i dzień w plecy. Po jakimś czasie z doświadczenia wiadomo, że pewnych prędkości w tak prostym generatorze baud rate'ów nie da się z niskich zegarów uzyskać. Najlepszą metodą jest chyba takie napisanie makra, by samo informowało (np. warningiem podczas kompilacji) o błędzie większym niż powiedzmy 2%

I jak to zwykle bywa: oscyloskop wyjaśnia sprawę jednym pomiarem 😐

Najlepszą metodą jest chyba takie napisanie makra, by samo informowało (np. warningiem podczas kompilacji) o błędzie większym niż powiedzmy 2%

Ale takie makro jest i to w standardowych (dla AVRów) bibliotekach.

W pliku util/setbaud.h

Tolerancja jest w nim ustawiona dokładnie na 2% i są też przykłady kodu właśnie dla Atmegi8.

O! Używałem go wielokrotnie ale nie wiedziałem, że umie zgłaszać błędy. Widocznie bezwiednie korzystałem tylko z sensownych przy danym zegarze prędkości. Zaraz to sprawdzę, dzięki.

Ech, nie ma to jak wynaleźć koło.. A już się ucieszyłem 🙂

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...