• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Komunikacja między mikrokontrolerami.

Object Storage Arubacloud
0 głosów
699 wizyt
pytanie zadane 23 marca 2016 w C i C++ przez Mavimix Dyskutant (8,420 p.)
edycja 23 marca 2016 przez Mavimix

Mam dwa mikrokontrolery Atmega8 i podłączony wyświetlacz LCD do jednego z nich. Chciałbym wysłać zdanie "Hello World!" z jednego i wyświetlić na drugim. To są moje kody, które niestety nie działają - na lcd'ku wyświetlają się "krzaki".

Transmiter:

#include <avr/io.h>
//header to enable data flow control over pins
#define F_CPU 8000000UL
//telling controller crystal frequency attached
#include <util/delay.h>
//header to enable delay function in program

int main(void)
{
                DDRD |= 1 << PIND1;//pin1 of portD as OUTPUT
                DDRD &= ~(1 << PIND0);//pin0 of portD as INPUT
                PORTD |= 1 << PIND0;

                int UBBRValue = 51;//AS described before setting baud rate

                //Put the upper part of the baud number here (bits 8 to 11)
                UBRRH = (unsigned char) (UBBRValue >> 8);

                //Put the remaining part of the baud number here
                UBRRL = (unsigned char) UBBRValue;

                //Enable the receiver and transmitter
                UCSRB = (1 << RXEN) | (1 << TXEN);

                //Set 2 stop bits and data bit length is 8-bit
                UCSRC = (1 << USBS) | (3 << UCSZ0);

                while (1)
                {

					   while (! (UCSRA & (1 << UDRE)) );
					   {
						   UDR = "Hello World!";
						}
                }
}

Receiver:

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

int main(void)
{
	LCD_Inicjuj();

                DDRD |= (1 << PIND0);//PORTD pin0 as INPUT
                DDRC=0xFF;//PORTC as OUTPUT

                int UBRR_Value = 51; // 2400 baud rate
                UBRRH = (unsigned char) (UBRR_Value >> 8);
                UBRRL = (unsigned char) UBRR_Value;
                UCSRB = (1 << RXEN) | (1 << TXEN);
                UCSRC = (1 << USBS) | (3 << UCSZ0);

                unsigned char receiveData;

                while (1)
                {
                                while (! (UCSRA & (1 << RXC)) );

                                receiveData = UDR;


                                LCD_Wyswietl(receiveData);
                                _delay_ms(100);

                                LCD_Czysc();
                }
}

 

2 odpowiedzi

+2 głosów
odpowiedź 23 marca 2016 przez Krawiec91 Pasjonat (19,600 p.)
wybrane 24 marca 2016 przez Mavimix
 
Najlepsza

Rejestr UDR jest rejestrem 8 - bitowym, więc możesz do niego przypisać zmienną o rozmiarze 8 bitów, np. typ char.  String "Hello World" musisz rozbić na pojedyńcze znaki i je kolejno wysyłać. Tak samo przy odbiorze, odbierasz kolejne znaki 'H' 'e' 'l' .....

komentarz 23 marca 2016 przez Krawiec91 Pasjonat (19,600 p.)
O kurde, o tej porze to głupi jestem. Wrócę z roboty jutro, to sobie przeanalizuje na spokojnie kody z całego posta. Spróbuj może zrobić, ten układ z linka, który podesłałeś (ten z diodą, już nawet bez przycisku), czy to zatrybi.
komentarz 24 marca 2016 przez Mavimix Dyskutant (8,420 p.)
Tak robiłem - wysyłałem jeden bajt i funkcją if sprawdzałem czy ten bajt przyszedł czy nie - jak tak to wyświetlało "Tak", jak nie to "Nie". To działało. Jak bajt zamieniłem np. na "A" to całość przestawała działać.
komentarz 24 marca 2016 przez Nondzu Obywatel (1,910 p.)
odpiszę na powyższe

Znak "A" to nie to samo co 'A'

znak "A" składa się z dwóch bajtów

spróbuj wpisać 'A' i napisz co się dzieje ;)

Pozdrawiam
komentarz 24 marca 2016 przez Mavimix Dyskutant (8,420 p.)

Poprawiłem kod i napisałem dodatkową funkcję sprawdzającą czy odebrano znak. Na potrzeby util/delay zmieniłem też taktowanie uC na 1MHz:

/////----------Transmiter----------/////

#include <avr/io.h>
//header to enable data flow control over pins
#define F_CPU 1000000UL
//telling controller crystal frequency attached
#include <util/delay.h>
//header to enable delay function in program

int main(void)
{
                DDRD |= 1 << PIND1;//pin1 of portD as OUTPUT
                DDRD &= ~(1 << PIND0);//pin0 of portD as INPUT
                PORTD |= 1 << PIND0;

                int UBBRValue = 12;//AS described before setting baud rate

                //Put the upper part of the baud number here (bits 8 to 11)
                UBRRH = (unsigned char) (UBBRValue >> 8);

                //Put the remaining part of the baud number here
                UBRRL = (unsigned char) UBBRValue;

                //Enable the receiver and transmitter
                UCSRB = (1 << RXEN) | (1 << TXEN);

                //Set 2 stop bits and data bit length is 8-bit
                UCSRC=(1<<UCSZ1) | (1<<UCSZ0) | (1<<URSEL);

                while (1)
                {

                   while (! (UCSRA & (1 << UDRE)) );
                   {
                	   UDR = 'A';//once transmitter is ready sent eight bit data
                   }

                }
}

/////----------Receiver----------/////

#include <avr/io.h>
#define F_CPU 1000000UL
#include <util/delay.h>
int main(void)
{
	LCD_Inicjuj();

                DDRD |= (1 << PIND0);//PORTD pin0 as INPUT
                DDRB |= (1<<PB1);

                int UBRR_Value = 12; // 2400 baud rate
                UBRRH = (unsigned char) (UBRR_Value >> 8);
                UBRRL = (unsigned char) UBRR_Value;
                UCSRB = (1 << RXEN) | (1 << TXEN);

                UCSRC=(1<<UCSZ1) | (1<<UCSZ0) | (1<<URSEL);

                unsigned char receiveData;
                while (1)
                {
                                while (! (UCSRA & (1 << RXC)) );

                                receiveData = UDR;

                                if(receiveData == 'A')
                                {
                                	PORTB ^= (1<<PB1);
                                }

                                LCD_Wyswietl(receiveData);

                                _delay_ms(500);

                                LCD_Czysc();
                }
}

Co ciekawe dioda świeci (miga). Zauważyłem, że jak w funkcji LCD_Wyswietl string dam w 'A' to nic nie wyświetla, a jak w "A" to wyświetla. Da się to jakoś przekonwertować?

komentarz 24 marca 2016 przez Mavimix Dyskutant (8,420 p.)

Pomógłbyś mi jeszcze z tym?

0 głosów
odpowiedź 24 marca 2016 przez Nondzu Obywatel (1,910 p.)
Witam

A jak taktujesz te atmegi ? W kodzie masz F_CPU 8MHz, a czy zmieniłeś fuse bity w nich na 8 MHz ? Do wyliczania wartości do UBRR_Value  służy odpowiednie makro. Puki co nie mam czasu aby sprawdzić czy zapisana wartość jest poprawna dla prędkości 2400, ale jeśli nie zmieniłeś taktowania Atmeg na 8 MHz to będą krzaki.

 

Pozdrawiam
komentarz 24 marca 2016 przez Mavimix Dyskutant (8,420 p.)

Oba procesory chodzą na 8 MHz - wartość UBBR mam z tej strony

Podobne pytania

0 głosów
1 odpowiedź 239 wizyt
pytanie zadane 24 marca 2016 w C i C++ przez Mavimix Dyskutant (8,420 p.)
+1 głos
1 odpowiedź 437 wizyt
pytanie zadane 13 marca 2016 w C i C++ przez Mavimix Dyskutant (8,420 p.)
0 głosów
1 odpowiedź 599 wizyt
pytanie zadane 18 stycznia 2016 w C i C++ przez qwertz Użytkownik (850 p.)

92,761 zapytań

141,685 odpowiedzi

320,482 komentarzy

62,105 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...