Skocz do zawartości

Atmega8L Problem z UART


Mateusz

Pomocna odpowiedź

Witam.

Mam układzik z atmega8L i chciałbym wysyłać po uart dane z czujników. Jednak Wszystko ustawiłem a dane wysyłane to same zera. Mam wrażanie, że coś nie tak jest z synchronizacją ale nie jestem pewien 🙂. Fuse bity mam ustawione: hFuse= D9, lFuse=E1 czyli taktowanie wewn oscylatorem 1Mhz.

Do uc podłączony jest kwarc ale nie jest używany.

Program wygląda tak:

main.c:

#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>  
#include <stdio.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <compat/twi.h>
#include "hmc5883l.h"
#include "TWI_lib.h"
#include "UART_ATM8.h"

#define SetBit(x,y)	x |= (1<<y)
#define ClrBit(x,y) x &= ~(1<<y)
#define NegBit(x,y) x ^= (1<<y)

volatile unsigned char bufor_RXD=0;
volatile int receive=0;

ISR (USART_RXC_vect)
{
	bufor_RXD = UDR;
receive=1;
}

int main(void)
{
DDRB =	0b00000111; 
DDRC =	0b00001111; 
DDRD =	0b11000010;
PORTB =	0b00000001;
PORTC =	0b00110000;
PORTD =	0b00111100; 

int HMC_X=100;
int num=1234;
char buf[10];
USART_Init();
sei();
//TWI_Init();

   while(1)
   {
	//HMC_X = HMC_Read('X');
	//char buf[3];
	//itoa(HMC_X, buf, 10);
		sprintf(buf,"%d %d\n ", num, num);
		USART_send_string(buf);
		_delay_ms(1000);
   }
}

UART_ATM8.h

#ifndef UART_ATM8_H_
#define UART_ATM8_H_

#define FOSC 1000000UL// Clock Speed
#define BAUD 2400
#define ubrr (FOSC/(16*BAUD))-1

void USART_Init();
void USART_send_string(char *string);

#endif

UART_ATM8.c

#include <avr/io.h>
#include <stdio.h>
#include "UART_ATM8.h"

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

void USART_send_string(char *string)
{
  char znak;
  while (0!=(znak=*(string++)))
  {
	while ( !( UCSRA & (1<<UDRE)) );
	UDR=znak;
  }
} 

Czy widzi ktoś z was jakiś błąd?

Link do komentarza
Share on other sites

Z przerwanie odbioru na razie nie korzystałem dlatego nie jest ustawione. (metoda małych kroczków 🙂 ).

Co do GND to oczywiście jest podłączone.

A baud obliczam w taki sposób:

#define FOSC 1000000UL// Clock Speed
#define BAUD 2400
#define ubrr (FOSC/(16*BAUD))-1

Czyli wg tego wzoru z datasheet:

Asynchronus Normal Mode, 3 kolumna.

No i wynik przypisuje do rejestr UBRR

	UBRRH = (unsigned char)(ubrr>>8);
UBRRL = (unsigned char)ubrr;

Więc wydaje mi się, że dobrze jest ustawione.

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

Wg mojej oceny problem leży w ciekawym warunku pętli while.

Otóż kiedy do niej wchodzisz, pętla while w kółko sprawdza warunek ale podczas wykonywania obliczenia wartości tego wyrażenia podstawiasz za każdym razem do zmiennej znak KOLEJNY znak ze stringu. Operator ++ wykonuje się wiele razy i de facto robisz poszukiwanie końca łańcucha 🙂 Jak już go znajdziesz i wreszcie nadajnik będzie gotowy, wysyłasz otatni znaleziony znak czyli 0x00.

Nie, chyba bzdury popisałem...

Link do komentarza
Share on other sites

Hmm. A spróbuj wpisać po prostu do rejestru UBRR liczbę 25 (odpowiada prędkości 2400bps).

Czyli zamień

UBRRH = (unsigned char)(ubrr>>8);

UBRRL = (unsigned char)ubrr;

na

UBRRH=0;

UBRRL=25;

I czy na pewno masz ustawiona na kompie prędkość 2400bps??

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

A ile "zer" wypisuje się po wysłaniu stringu o znanej długości?

Takie coś wysyła co sekundę:

<0>˙<0><0><0><0><0><0>˙<0><0><0><0>˙<0><0><0><0>˙<0><0><0><0><0><0>˙<0><0><0><0>˙<0><0><0>˙<0><0><0>

Wg mojej oceny problem leży w ciekawym warunku pętli while.

Otóż kiedy do niej wchodzisz, pętla while w kółko sprawdza warunek ale podczas wykonywania obliczenia wartości tego wyrażenia podstawiasz za każdym razem do zmiennej znak KOLEJNY znak ze stringu. Operator ++ wykonuje się wiele razy i de facto robisz poszukiwanie końca łańcucha 🙂 Jak już go znajdziesz i wreszcie nadajnik będzie gotowy, wysyłasz otatni znaleziony znak czyli 0x00.

Nie, chyba bzdury popisałem...

W innych programach takie coś mi działało więc chyba nie w tym jest problem.

Hmm. A spróbuj wpisać po prostu do rejestru UBRR liczbę 25 (odpowiada prędkości 2400bps).

Czyli zamień

UBRRH = (unsigned char)(ubrr>>8);

UBRRL = (unsigned char)ubrr;

na

UBRRH=0;

UBRRL=25;

I czy na pewno masz ustawiona na kompie prędkość 2400bps??

Działa ! 🙂

Link do komentarza
Share on other sites

Źle byłą przypisywana wartość do UBRRH, UBRRL przez co BaudRate był źle ustawiony 🙂.

Wpisałem tak jak mi napisał davidpi i działa. Nie jest to perfekcyjne i eleganckie ale na razie wystarczy 😉.

Link do komentarza
Share on other sites

Wpisałem tak jak mi napisał davidpi i działa.

Hmm na forum jest możliwość wyrażania wdzięczności 😉

__________

Komentarz dodany przez: Bobby

Nieobowiązkowa 😉

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

Wielkie dzięki za podpowiedź, miałem podobny problem z komunikacją przy uzyciu transmiterów Mobot - RCR2. Po postąpieniu jak powyżej, czyli wpisaniu "od ręki" wartości UBRRL i UBRRH wszystko ruszyło. Dzięki za pomoc!! 🙂

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.