Skocz do zawartości

[C] ATmega88 - Problem z odbiorem danych przez btm222


szpaku

Pomocna odpowiedź

Witam,
testuję komunikację komputera z atmegą przez moduł btm222. Mam pewien problem, dane wysyłane z atmegi bez problemu dochodzą do komputera, jednak atmega w ogóle nie dostaje danych wysyłanych z komputera. Program jest prosty, po otrzymaniu znaku ma zacząć wyświetlać w kółko litery "at" zamiast "ok" i tak na zmianę po otrzymaniu jakiejkolwiek danej po uart. Poniżej zamieszczam kod:

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

#define  F_CPU 8000000UL

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

#define dataLen 8

#define FOSC 8000000
#define BAUD 19200
#define MYUBRR FOSC/16/BAUD-1

#include <util/setbaud.h>

volatile unsigned char odb_flaga = 0;

void clockprescale(void)
{
CLKPR = 0b10000000;
CLKPR = 0b00000000;
}

void usart_init(unsigned int ubrr)
{
UBRR0H = (unsigned char)(ubrr>>8);
UBRR0L = (unsigned char)ubrr;

UCSR0A &= ~(1<<U2X0);
UCSR0A |= (1<<TXC0);
UCSR0A |= (1<<RXC0);

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

UCSR0C = (0<<USBS0)|(3<<UCSZ00);

UCSR0B = (1<<RXCIE0);
}

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

ISR(USART_RX_vect)
{
//przerwanie generowane po odebraniu bajtu
if (odb_flaga)
{
	odb_flaga = 0;
}
else
{
	odb_flaga = 1;
}
}


int main(void)
{
clockprescale();
usart_init(MYUBRR);
sei();

while(1)
{
	if(odb_flaga)
	{
		_delay_ms(500);
		USART_Transmit('t');
		_delay_ms(500);
		USART_Transmit('a');
	}
	else
	{
		_delay_ms(500);
		USART_Transmit('o');
		_delay_ms(500);
		USART_Transmit('k');
	}
}
}

Sprzęt mam raczej podłączony dobrze, wnioskuje tak po tym, że gdy podłączę jakieś urządzenie do modułu on wysyła o tym informację do atmegi i tą informację procesor odbiera, wchodzi do przerwania, jednak wszystkie następne dane wysłane do atmegi już jednak są ignorowane. Już nie mam pomysłu co tu może być źle. W komputerze wszędzie mam ustawione odpowiednie parametry transmisji. Nie ruszałem w ogóle komend AT, btm jest ustawiony domyślnie nic nie zmieniałem. Płytka na której mam btm ma diodę informującą o odbiorze danych, i ona świeci się gdy coś wysyłam z komputera, więc moduł na pewno otrzymuje dane z komputera.

Proszę o pomoc

Link do komentarza
Share on other sites

Moim zdaniem w obsłudze przerwania od odbiornika powinieneś odczytywać z UDR0 odebrany znak. Możesz go natychmiast zapominać, ale dopiero odczyt (lub reset całego UARTa) powoduje wyzerowanie flagi RXC0 i umożliwia zgłoszenie następnego przerwania.

Link do komentarza
Share on other sites

Dzięki za zainteresowanie, niestety nie pomogło.

Teraz moje przerwanie wygląda tak:

ISR(USART_RX_vect)
{
odb_x = UDR0;
if (odb_flaga)
{
	odb_flaga = 0;
}
else
{
	odb_flaga	=	1;	//ustaw flagę odbioru liczby dla main()
}
}

Niestety nie pomogło, wzorując się na dokumentacji atmegi próbowałem też odbierać te dane nie przez przerwanie, a używając funkcji:

unsigned char USART_Receive( void )
{
while ( !(UCSR0A & (1<<RXC0)) );
return UDR0;
}

Niestety też nie pomogło, program zacina się na pętli i nie chce przejść dalej.

Link do komentarza
Share on other sites

Teraz zauważyłem, że w inicjalizacji robisz to:

UCSR0B=(1<

a zaraz potem to:

UCSR0B = (1<

co powoduje, że w sumie w UCSR0B zostaje ustawiony tylko RXCIE0.

Czy nadajnik rzeczywiście działa, skoro jest wyłączony? Może spróbuj zrobić to spokojniej, najpierw ustawiasz wszystkie formaty danych, potem odblokowujesz nadajnik i odbiornik a na końcu włączasz ich przerwania.

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

Wrzuciłem wcześniejszą wersję programu i zapomniałem tego tutaj poprawić, masz rację w kodzie z pierwszego postu nie działało nawet wysyłanie 😳 .

Ta funkcje podzieliłem na dwie osobne uruchamiane po sobie:

void usart_init(unsigned int ubrr)
{
UBRR0H = (unsigned char)(ubrr>>8);
UBRR0L = (unsigned char)ubrr;

UCSR0C = (0<<USBS0)|(3<<UCSZ00);

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

void przewanie_init()
{
UCSR0B |= (1 << RXCIE0);
UCSR0A |= (1 << RXC0);
}

Niestety nadal nie działa odbieranie 🙁 , ale chyba coś w ogóle namieszałem bo teraz nie wchodzi nawet w przerwanie na początku przy połączeniu.

Edit:

W takim ustawieniu działa tak jak mówiłem na początku, czyli ta pierwsza wiadomość wysyłana przy połączeniu wchodzi do przerwania ale następne już nie uruchamiają przerwania:

void usart_init(unsigned int ubrr)
{
UBRR0H = (unsigned char)(ubrr>>8);
UBRR0L = (unsigned char)ubrr;

UCSR0B = (1<<RXEN0)|(1<<TXEN0);
UCSR0C = (0<<USBS0)|(3<<UCSZ00);
}

void przewanie_init()
{
UCSR0B |= (1 << RXCIE0);
}
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.