UART komunikace s PC, propojení PC s AVR-převodník RS232/USB

Každý řetězec končí znakem ‘\0’. Funkce strlen() nedělá nic jiného, než že tuto nulu hledá a vrátí její pozici.
Tedy trocha optimalizace:

void posliString(char retezec]) { unsigned char i = 0; while(retezec* != '\0') { while ( !(UCSR0A & (1<<UDRE0)) ); /* Wait for empty transmit buffer */ UDR0 = retezec*; } }
Parametr funkce (retezec]) se neúčastní žádné asynchronní události, volatile je tedy zbytečné.
Doporučuji pojmout za vlastní automatické odsazování kódu nižší úrovně (např. tělo cyklu, podmínky apod.). Jinak se i velmi jednoduchý kód stane velmi nepřehledným.**

ano, takhle to funguje lépe. A jak na ten nový řádek ? Zkouším něco jako /n ale to jenom vytiskne, na nový řádek nenajede.

Každý systém má jiný přechod na nový řádek (unix, dos, win). Někde se používá \n, jinde \r a do třetice \r\n(oba znaky). Ovšem jesli na některou kombinaci bude reagovat trerminál, to jsem nezkoušel (obvykle text nepřenáším :slight_smile:).

tak jsem odzkoušel snad všechny možnosti (hlavně pozor na opačné lomítko) a nakonec stačí napsat PosliString("\r");
Tak díky moc za rady

teďko mi to začlo nějak chybovat
po zapnutí mikroprocesoru (terminál je již spuštěn a připojen) to samo od sebe odešle a na počítači zobrazí <0>
a ještě - pošlu číslo - třeba 40.0 , ale on napíše 40.0u a za tím jěště následuje znak zabarveného políčka
V čem může být chyba ?

Odeslání znaku po zapnutí se dá vysvětlit pokud nemáš externě definovanou úroveň rx/tx pinů během resetu (zkus 10k pull-upy).
Chyby za chodu může dělat ledasco. Nemáš tam nějakej kvalitní zdroj rušení? Chybu programu taky nelze vyloučit.

tak ty divný znaky za číslicemi jsem již opravil - číslice pocházeli z eepromky a byly nějak divně zformátovaný.
ale <0> mi to po zapnutí dělá stále, zjistil jsem že to naběhne ihned po zapnutí, ještě než udělám inicializaci uartu, ale zas tak moc to nevadí. 4,7k pullupy tam mám.
Jinak o kousek vedle běhá proud cca 8 A, mohl by to dělat on ?

Může to pomáhat náhodným chybám, ale ne pravidelným nulám po startu. To bych viděl spíš na sw nedostatek.

tak problém s tou <0> (někdy tam naběhla i vícekrát) byl opět v zapojení portu - jeden drát jsem tam neměl uzemněný

Jsem tu nový a tenhle článek mě přesvědčil o tom že MikroC PRO for AVR je jenom hračka pro děti. USART jsem tam sice rozchodil ale odmítalo to poslat řetězec korektně i když jsem v podstatě okopíroval vzorový program z helpu. Zato tohle mi chodí a i když trochu složitěji než v MikroC, zato funkčně. AVR si už s PC popovídá krásně a s minimálnímy nároky na *.hex ale chtěl bych se dostat i do fáze kdy já pošlu z PC data do AVR a on je zpracoval :slight_smile: Bohužel nevím kde hledat zdroj vědomostí strýček Google vyhodí většinou složité programy ve kerých se zatím nevyznám. :slight_smile: Nápověda by bodla :slight_smile: Díky moc :slight_smile:

Záleží, jesli chceš z pohledu programu synchronní (blokující) příjem - pro začátek jednodušší, nebo asynchronní (neblokující) přes přerušení (nutné nepatrně hlubší znalosti C).
V případě blokujícího příjmu 1 znaku potřebuješ pouze 2 další řádky kódu (M8 ):
while(!(UCSRA & (1<<RXC))); // wait for received data
promenna = UDR; // read new data

Díky moc přesně tohle jsem hledal :slight_smile: Ale teď pozor rozchodil jsem to :slight_smile:
A díky všem co píšou forum.mcontrollers.com/viewtopic.php?t=2312&start=0&postdays=0&postorder=asc&highlight=uart hlavně uživately Stanley který přiložil funkční program na komunikaci mezi PC a AVR v obou směrech. Všiml jsem si díky tomu pár závažných chyb které jsem dělal :slight_smile: a tady je můj kód. ted se vyskytla chyba v tom ze druha otazka se uz neprovede, kde muze bvejt chyba ?


#include <avr\io.h>
#include <stdio.h>
#include <string.h>
int vyplneno;
char znak;
char udaj;



void prijem()
{
while(!(UCSR0A & (1<<RXC0))); // wait for received data 
znak = UDR0;
}



void otazka (udaj)
{
	while(vyplneno == 0) 
   	{ 
	vyplneno = 0;
	prijem();
	
	
	if (znak == udaj) 
		{
		posliString("Přijato");
		novyradek();
		vyplneno = 1;
		}
	
	if (vyplneno == 0){
		posliString("Špatně");
		novyradek();
		}
   }
}


void posliString(char retezec]) 
{ 
   unsigned char i = 0; 
   while(retezec* != '\0') 
   { 
      while ( !(UCSR0A & (1<<UDRE0)) );     /* Wait for empty transmit buffer */ 
      UDR0 = retezec*; 
   } 
} 


void novyradek(){
posliString("\r\n");
}




void main(void) 
{ 
	
   // ======= UART INIT ====================== 
   // default nastaveni usartu atmega88 je 8N1 
   UCSR0B |= 1<<TXEN0;   // tx enable
   UCSR0B |= 1<<RXEN0;   // rx enable 
   UCSR0B |= 1<<RXCIE0;
   UBRR0L = 51;      // 9600Bd pro 8MHz, 0.2% 
   // ======================================== 

    
	posliString("Vítej v nastavení programu TEMPAVR");
	novyradek();
	posliString("Nyní zadej své uživatelské jméno a heslo.");
	novyradek();
	posliString("@name:");
	novyradek();
   	otazka('o');
   	posliString("@password:");
	novyradek();
	otazka('l'); 
}

:arrow_right: administrator: příspěvek byl upraven*
Upraven zápis odkazu.*

Zdravim,

potreboval by som poradit. Pouzivam Atmegu88 20PU, fuse som ponechal na defaulte teda l=62, h=df, e=01. F_CPU je som nastavil na 8 ale po clkdiv8 to ide na 1 MHz. Toto vsak nemam otestovane, drzim sa len toho co bolo v datasheete

Na programovanie pouzivam USBasp, ten mam odskusany ze pracuje v poriadku. Notebook mam s chipom prepojeny pomocou aktivnej UsbToRS232 redukcie Axago ads-50.

Otestoval som si uart pomocou loopu, posielal som A z tx na rx, no a ak som prijal A na rx tak som rozsvietil diodku. Toto mi fungovalo.

Otestoval som aj kabel, prepojil som RX a TX a na terminaly som videl to co som pisal.

Ked som vsak prepojil notebook s mojou megou nastal problem. Pri stlacani ‘a’ nedostanem ten isty znak ale vrati sa mi ‘X’ vid obrazok.

s25.postimg.org/ylt34rrzz/UARTvystup.jpg

Moj zdrojovy kod vyzera nasledovne:

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

#define USART_BAUDRATE 9600
#define BAUD_PRESCALE ((( F_CPU / ( USART_BAUDRATE * 16UL))) - 1)
int main ( void )

{
DDRD = 0b11111110;
char ReceivedByte ;
UCSR0B = (1 << RXEN0 ) | (1 << TXEN0 ); // Turn on the transmission and reception circuitry
UCSR0C = (1 << UCSZ00 ) | (1 << UCSZ01 ); // (1 << UMSEL00 ) | Use 8- bit character sizes
UBRR0H = ( BAUD_PRESCALE >> 8); // Load upper 8- bits of the baud rate value into the high byte
//of the UBRR0 register
UBRR0L = BAUD_PRESCALE ; // Load lower 8- bits of the baud rate value into the low byte of the
//UBRR register
for (;:wink: // Loop forever
{
while (( UCSR0A & (1 << RXC0 )) == 0) {}; // Do nothing until data have been received and is
//ready to be read from UDR
ReceivedByte = UDR0 ;

	while (( UCSR0A & (1 << UDRE0 )) == 0) {}; // Do nothing until UDR is ready for more data to
	//be written to it
	UDR0 = ReceivedByte ; // Echo back the received byte back to the computer
	
}

}[/code]

Za vsetky duchaplne rady vopred vdaka :slight_smile:

Ak mate nejake otazky, kludne sa pytajte, neviem co vsetko je nutne tu napisat aby ste mi vedeli poradit.

:arrow_right: administrator: příspěvek byl upraven

:arrow_right: administrator: přiloženy externí soubory
UARTvystup.jpg

Pokud jsi neměnil nastavení pojistek a máš ho tak, jak je z výroby, pak mcu jede na 1MHz (CKDIV8 je defaultně naprogramovaná).

Máš 3 možnosti, jak to opravit :

  1. Přeprogramuješ pojistku CKDIV8 - vypne to prescaler a mcu pojede na 8 MHz
  2. F_CPU dáš 1000000UL - Překladači řekneš, že systémové hodiny jsou 1 MHz
  3. Na začátek programu doplníš následující kód :
CLKPR=(1<<CLKPCE);
CLKPR=0;

To vypne prescaler systemových hodin a mcu pojede na těch 8 MHz.

Vdaka Balu, vypol som ckdiv8 pomocou nastavenia fuze, teraz uz bezim na 8MHz… problem to vsak nevyriesilo, neustale mi vypisuje hluposti na terminaly.

Zkus tohle :

#define USART_BAUDRATE 9600UL

Vyskusal som ale ani tento ukon nevyriesil problem.

Zkus ještě za

DDRD = 0b11111110;
přidat

PORTD = 0b00000011;

Zapneš tím interní Pull-Up rezistory pro UART interface.

Případně

PORTD = 0b11111111;

Nastavit všechny výstupy na log. 1 (interní Pull-Up rezistor pro RXD pin).

Jinak bych řekl, že program je OK.

Vdaka ti balu za snahu ale ani toto nepomohlo. Broblem bude asi v hardwari. Treba dat k tej redukcii co som spominal aj MAX232? Na strankach pisali ze je aktivny ten kabel,tak ratam ze je ta elektronika uz tam. Kolko by malo byt napatie na vystupe rs232?

ak pouzivas daky USB->RS232 prevodnik tak musis pouzit aj MAX232. Ak mas napr. FTDI cip, tak MAX232 netreba.