Sari la conținut
ELFORUM - Forumul electronistilor

atmel-atmel USART transmisie incompleta


Vizitator Ace29

Postări Recomandate

Vizitator Ace29

Salut. Am o problema cu transmisia seriala. Folosesc doua microcontrollere ATmega32 care comunica pe USART. Am incercat sa transmit numere de pana in 3 cifre si sa le afisez pe LCD si totul mergea perfect. Mentionez ca folosesc o placa de dezvoltare EvB4.3 cu un LCD HD44780. Doresc sa masor valorile date de un accelerometru dar am probleme cu transmisia. Problema este urmatoarea : daca trimit sa zicem un sir de caractere abcdefchi mie pe LCD imi afiseaza doar abci. Prima placuta trimite bine sirul de caractere deoarece am testat pe hyperterminal si acolo imi afiseaza cum trebuie. Functiile de transmisie si receptie sunt cele din datasheetul lui atmega32.char USARTReadChar(){ while(!(UCSRA & (1<

Link spre comentariu
  • Răspunsuri 3
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • mitescu

    1

  • ramsesrr

    1

Top autori în acest subiect

MC-ul transmite la rand toate caracterele. Cel care receptioneaza, dupa ce primeste un caracter , il afiseaza. Asta insemna ca dupa cateva caractere receptionate , se pierde sincronizarea. Cu alte cuvinte se transmite mai des dacat se poate receptiona.

Problema poate avea mai multe solutii. Cea mai simpla e sa introduci dupa fiecare "USARTWriteChar", cate un delay, acoperitor pentru timpul necesar afisarii.

O alta solutie e sa faci receptia pe intreruperi dar intr-un buffer, cu conditia ca dimensiunea bufferului sa fie mai mare sau egala cu numarul de caractere transmise intr-o secventa.

O a treia solutie (si dupa parerea mea , cea mai eleganta) este sa faci un minim protocol de comunicatie. Ceva de genul urmator:

- se transmite un caracter

- MC-ul de la receptie il receptioneaza si "confirma" receptia catre transmitator, prin transmiterea catre acesta , caracterul receptionat

- transmitatorul , va transmite urmatorul caracter abia dupa ce reprimeste caracterul anterior transmis

Simplificat, ar arata cam asa:

//transmisie  USARTWriteChar('a');  USARTReadChar();  USARTWriteChar('b');  USARTReadChar();  USARTWriteChar('c');  USARTReadChar(); ...........
pentru receptie :

// receptie  while(1){data=USARTReadChar();USARTWriteChar(data);LCDsendChar(data);}
Link spre comentariu
Vizitator Ace29

Am folosit niste delayuri si acum imi transmite bine. Dar mai am o mica nelamurire. Eu transmit de pe un microcontroller mai multe informatii. Am 2 senzori pusi, un accelerometru si un senzor de deplasare(encoder). Accelerometrul e pus la ADC0 iar encoderul la INTo si INT1. Pana acu nu am avut probleme dar ma gandesc ca in e posibil asa apara. Cum as putea face sa stiu cum apar informatiile si de la cine? Mentionez ca pana acu nu am avut coliziuni cu codul facut de mine...dar vreau sa aud si o parere.

Codul urmator este pentru accelerometru.

	USARTInit(51);		//UBRR = 51		initializare_intreruperi();	rezultat rezultatFinal,rezultatFinalprev;	int prev;	ADC_init();	rezultatFinalprev=ADC_get(0);	prev=rezultatFinalprev.conv;	while(1)	{				rezultatFinal=ADC_get(0);		if ((rezultatFinal.conv>prev+5)||(prev-5>rezultatFinal.conv))		                  {										prev=rezultatFinal.conv;										USARTWriteChar('a');										_delay_ms(50);								    	        if (rezultatFinal.semn==1) {USARTWriteChar('-');}										_delay_ms(50);										uart_puti(rezultatFinal.degree);										_delay_ms(100);;								   		USARTWriteChar('.');										_delay_ms(50);										if (rezultatFinal.zero==1) {USARTWriteChar('0');}										_delay_ms(50);										uart_puti(rezultatFinal.frac);										_delay_ms(50);										USARTWriteChar('p');										_delay_ms(5000);														} 		 	 }}
Pentru encoder am scis asa pentru int1_vect si in mod asemanator pentru int0: SIGNAL (INT1_vect) //vectorul de intrerupere { USARTWriteChar('b');uart_puti(counter);USARTWriteChar('t');counter--;GIFR=(1<<INTF1);	}

La receptie am urmatorul cod :

void main(){		char data;	LCDinit();	USARTInit(51);		//UBRR = 51    LCDGotoXY(0,0);		LCDsendChar('X');	LCDsendChar(':');	while(1)	{    	data=USARTReadChar();		if (data=='b'){						LCDGotoXY(0,1);    					while (data!='t')									{										data=USARTReadChar();										_delay_ms(10);										if (data!='t') {LCDsendChar(data);_delay_ms(10);}										}						    						LCDGotoXY(0,1);									    	}		if (data=='a') {		                LCDGotoXY(2,0);						while (data!='p') 									{ 									  data=USARTReadChar();									  if (data!='p') {LCDsendChar(data);}									          else {											  		LCDsendChar(' ');													break;											  }									  }						LCDGotoXY(2,0);						}	}}
Mentionez ca pana acu nu au aparut probleme dar vreau sa aflu o parere si de la voi. Eu am mers pe ideea urmatoare:

-la receptie citeste primul caraceter. Daca este caracterul 'b' inseamna ca vine de la encoder si merge pe ramura cu 'b'(si scrie pana ajunge la caracterul de stop t). Daca e 'a' inseamna ca primeste de la accelerometru si merge pe ramura cu 'a'(si scrie pana ajunge la caracterul de stop p). E ok asa? Aveti alte idei de a imbunatati acest cod?

Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări