Skocz do zawartości

[C] [Atmega8 + btm 222] Krzaczki w terminalu


klawiszu

Pomocna odpowiedź

Witam.

Po zainicjowaniu komunikacji UART, ustawiam moduł w nieskończoną pętlę, wysyłającą co pewny okres czasu jeden znak.

Prędkość ustawiona w BTM - 19200, tak samo inicjuje tą prędkość w programie (25.04666=25). Po wgraniu programu do mikrokontrolera(ATMEGA8) rozpoczyna sie wysyłanie danych. I w rzeczywistości komunikacja następuje. Jednak nie wygląda tak jakbym sobie tego życzył. W terminalu zamiast litery 'a' pojawiają się za każdym razem krzaczki. Próbowałem podłączać się w terminalu z różnymi prędkościami. Efekt zawsze ten sam. Gdzie popełniam błąd?

#include <avr/io.h>
#include <util/delay.h>

#define BAUD 19200
#define MYUBRR F_CPU/8/BAUD-1

void USART_Init( unsigned int baud );
void USART_Transmit( unsigned char data );
unsigned char USART_Receive ( void );
void USART_String(const char *s );
const char c[] = "Hello World";
int * txt = c;

void main(void)
{ 
DDRB = 0X00;		// Wejście
PORTB = 0XFF;
DDRC = 0xFF;		// Z podciągnieciem do Vcc
PORTC = 0xFF;
USART_Init(25.041);

while(1){
	USART_Transmit("a");
	_delay_ms(330);
}

}





void USART_Init( unsigned int baud ){
/* Set baud rate */
UBRRH = ( unsigned char )(baud>>8); // baud rate
UBRRL = ( unsigned char )baud;
/* Enable Reciver and transmiter */
UCSRB = (1<<RXEN)|(1<<TXEN);
/* Set ferame format: 8data, 2bit stop */
UCSRC = (1<<URSEL)|(3<<UCSZ0);
}

void USART_Transmit ( unsigned char data ){
/* Wait for empty transmit buffer */
while (!( UCSRA & (1<<UDRE) ))
	;
/* Put data into buffer, sendds the data */
UDR = data;
}

unsigned char USART_Receive ( void ){
/* Wait  for data to be  received */
while ( !( UCSRA & (1<<RXC) ))
	;
/* Get and return recived data from buffer */
return UDR;
}

void USART_String(const char *s )
{
while (*s) 
	USART_Transmit(*s++);
}
Link do komentarza
Share on other sites

Sądząc po komentarzach po angielsku zgaduję, że kod pochodzi z jakiegoś przykładu. Dlatego podstawowe 3 pytania:

- czy fusebity są ustawione na poprawny zegar?

- czy definicja F_CPU jest poprawna z zegarem?

- jakiego używasz konwertera USB-RS232?

Link do komentarza
Share on other sites

Kody pochodzą z noty katalogowej ATMEGA8, są to przykłąowe kody w C pozwalające na inicjalizacje połączenia UART oraz transmisje w obu kierunkach. Co do fusebitów, nigdy sie tym nie intertesowałem, a z atmegą8 jestem juz prawie rok. Stworzyłem na niej prostego linefollowera, sterowałem diodami led, bawiłem sie pwm-em i wszystko działało sprawnie. Szczerze mówiąc nie widziałem potrzeby ingerowania w fusebity. Które fusebity powinienem zmienić?

Komunikowałem się juz z modułem za pomocą przejsciówki usb+ putty. Po wydawaniu komend at, btm222 pięknie na wszystko odpowiadał. Po tym sądzę iż błędem będzie prędkość transmisji, różniąca się pomiedzy tą zainicjowaną w mikrokontrolerze, a tą ustawioną w module (19200). Lecz niestety nie mam pomysłu z której strony ugryść ten problem.

F_CPU deklarowany jest w make file, ustawiony jest na 8000000. Jednakże w w inicjacji nie korzystam z żadnych wyliczeń wymagających używania stałem F_CPU, wpisuje na sztywno wartość wyliczoną (25).

Link do komentarza
Share on other sites

Co do fusebitów, nigdy sie tym nie intertesowałem, a z atmegą8 jestem juz prawie rok.

Jakoś trudno mi w to uwierzyć.

To teraz bardzo edukacyjnie: poczytaj sobie dokładnie rozdział o USART zamiast przepisywać nie myśląc. Następnie poczytaj o zegarach w tym procesorze. F_CPU to nie jest tylko jakaś tam stała, to bardzo ważna wartość - to częstotliwość taktowania zegara. Ty masz prawdopodobnie ustawioną na 1MHz wewnętrznego zegara (ale kto wie na pewno, skoro "Co do fusebitów, nigdy sie tym nie intertesowałeś" - ciekawe więc jak zrobiłeś PWM, też na czuja?) . Więc możliwe, że jakbyś ustawił prędkość 2400 to był widział komunikację.

Komunikowałem się juz z modułem za pomocą przejsciówki usb+ putty.

Co prawda nie ma to pewnie znaczenia, ale nei odpowiedziałeś na pytanie o rodzaj konwertera.

  • Pomogłeś! 1
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Czytałem note katalogową dot. USART.

To jest kawałek opisu podczas kompilacji avr-gcc "-DF_CPU=8000000UL". Czy to wystarczy do utwierdzenia Cię w fakcie że procesor pracuje z częstotliwością 8Mhz?

Bądź:

#define F_CPU 8000000
#include <avr/io.h>
#include <util/delay.h>


void USART_Init( unsigned int baud );
void USART_Transmit( unsigned char data );
unsigned char USART_Receive ( void );
void USART_String(const char *s );

void main (void)
{ 
DDRB = 0X00;		// Wejście
PORTB = 0XFF;
DDRC = 0xFF;		// Z podciągnieciem do Vcc
PORTC = 0xFF;
USART_Init(25.041);

while(1){
	USART_Transmit('a');
	_delay_ms(330);
}

}





void USART_Init( unsigned int baud ){
/* Set baud rate */
UBRRH = ( unsigned char )(baud>>8); // baud rate
UBRRL = ( unsigned char )baud;
/* Enable Reciver and transmiter */
UCSRB = (1<<RXEN)|(1<<TXEN);
/* Set ferame format: 8data, 2bit stop */
UCSRC = (1<<URSEL)|(3<<UCSZ0);
}

void USART_Transmit ( unsigned char data ){
/* Wait for empty transmit buffer */
while (!( UCSRA & (1<<UDRE) ))
	;
/* Put data into buffer, sendds the data */
UDR = data;
}

unsigned char USART_Receive ( void ){
/* Wait  for data to be  received */
while ( !( UCSRA & (1<<RXC) ))
	;
/* Get and return recived data from buffer */
return UDR;
}

void USART_String(const char *s )
{
while (*s) 
	USART_Transmit(*s++);
}
Link do komentarza
Share on other sites

Nie myl tego:

#define F_CPU 8000000

z prawdziwą częstotliwością CPU.

#define F_CPU to tylko informacja dla kompilatora, która wykorzystuje np, dla wyliczania wartości dla np. DELAYów.

Prawdziwa częstotliwość taktowania CPU jest zaszyta w fuse bitach, ewentualnie można ją zmieniać programowo, w odpowiednim rejestrze CPU.

  • Lubię! 1
Link do komentarza
Share on other sites

Spróbuj czegoś takiego:

#define MYUBRR ((F_CPU+BAUD*8UL) / (16UL*BAUD)-1)

Gdy zdefiniowałem MYUBRR tak jak ty, niestety nie chciało mi to do końca działać. Ten sposób u mnie śmiga aż miło. Zalecam używanie zewnętrznego kwarca, jest stabilniejszy.

Link do komentarza
Share on other sites

Dzięki, faktycznie fusebit low był ustawiony na 0xE1, a powinien być ustawiony na 0xE4. Moja niewiedza dotycząca fusebitów wyszła na jaw i dała mi w kość. Obiecuję zgłębić ją bardziej. Wielkie dzięki, dla moderatora za poprawianie mej poprawnej polszczyzny, jaki za wszelkie wskazówki uzyskane na tym forum.

Pozdr 😉

Link do komentarza
Share on other sites

Trochę za późno, ale napiszę, tutaj masz link do artykułu: https://www.forbot.pl/forum/topics20/programowanie-terminalowa-aplikacja-serwisowa-do-robota-czesc-3-uart-w-c-vt9104.htm

W drugiej części tego artykułu starałem się wspomnieć o każdym miejscu które można przeoczyć podczas przygotowywania się do wysyłania danych po uarcie.

A o samej konfiguracji fusebitów jeżeli chodzi o taktowanie, możesz poczytać tutaj: https://www.forbot.pl/forum/topics20/dla-poczatkujacych-konfiguracja-fuse-bitow-odpowiadajacych-za-oscylator-vt4025.htm?utm_source=forbot&utm_medium=link_spis_art&utm_content=art_4025&utm_campaign=spis_art

Link do komentarza
Share on other sites

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...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.