Stránka 1 z 1

mega8 USART

Napsal: 02 pro 2010, 18:22
od jano80
Zdravim Vas. Uz dva dni sa pasujem s problemom rozchodit USART na mega8-ke no zatial bez uspechu a uz dochadzaju mi vysvetlenia preco to nefachci. Problem je taky ze napisany program v AVR studiu pi odsimulovani v virtual terminal (proteus) funguje podla ocakavani, avsak v skutocnom zapojeni , prijimam uplne nezmyselne znaky (konkretne pri odoslani znaku A prijimam 3x po sebe nasledujuce znaky 0x00. Prepojenie medzi procakom a PC pouzivam prevodnik USB/SERIAL s FT232RL (s TTL urovnami). Diky za kazdy napad...

Kód: Vybrat vše

/*

USART MEGA8
cpu/clk 2MHz (interny RC oscilator)

*/

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

#define USART_BAUD 1200ul
#define USART_UBBR_VALUE ((F_CPU/(USART_BAUD*16))-1)

unsigned char send_byte = 0;

//USART TX / RX DATA

void USART_vInit(void)

{

// Set baud rate

UBRRH = (uint8_t)(USART_UBBR_VALUE>>8);

UBRRL = (uint8_t)USART_UBBR_VALUE;

// Set frame format to 8 data bits, no parity, 1 stop bit

UCSRC = (0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0);


// Enable receiver and transmitter

UCSRB = (1<<RXEN)|(1<<TXEN); 
UCSRA = (0<<U2X);

}


//UASRT TX
void USART_Transmit( unsigned char data )
{
/* Wait for empty transmit buffer */
while ( !( UCSRA & (1<<UDRE)) )
;
/* Put data into buffer, sends the data */
UDR = data;
}

//USART RX
unsigned char USART_Receive( void )
{
/* Wait for data to be received */
while ( !(UCSRA & (1<<RXC)) )
;
/* Get and return received data from buffer */
return UDR;
}


int main ()
{
DDRD |=(1<<1);//PORTD,1 nastaveny ako vystup
USART_vInit();//incializacia USART

send_byte = 'A';	

while(1)
	{
		USART_Transmit(send_byte);//odosle znak A kazdu sekundu
		_delay_ms(1000);
	}


}//end

Napsal: 02 pro 2010, 19:17
od Atlan
aku komunikacnu rychlost pouzivas ...lebo 1200Bd to nepodporuje vid tabulka 60

Napsal: 02 pro 2010, 19:18
od Andrea
Tak nejdřív ten procesor vytáhni z patice a propoj na ní RxD a TxD a data se ti musí nezměněná vracet do PC (nebo tam, odkud je posíláš). Tím vyloučíš/zjistíš případný hw problém.

Napsal: 02 pro 2010, 19:34
od jano80
To ze rychlost 1200 nieje v tabulke neznamena ze ju nepodporuje, predsa je na vypocet nejaky vzorec.

Prepojit TX s RX na pätici som skusal ako prve, data sa vracali nezmenene pri akejkolvek rychlosti.

Napsal: 02 pro 2010, 21:00
od bohumilfulin
tak vem log sondu sondu nebo oscilo a mrkni zda ti pri vysilani data z PC jdou do toho spravneho pinu nebo naopak kdyz vysilas z MCU tak koukni na to zda jdou data na spravny pin toho prevodniku.

jeste jedna drobnost, nebude ten prevodnik vyzadovat handshake tj, propojit rts/cts, dtr/dsr? to muze byt taky problem.

rychlost sice v tabulce neni ale da se, jak rikas, dopocitat. a spocital sis taky odchylku rychlosti tebou napocitanou od normovane? musi byt pod tusim pod 2%

program mas v C a to zatim nemuzu slouzit. to si vygoogluj.

Napsal: 02 pro 2010, 21:06
od bohumilfulin
jo az ted jsem si vsiml ze jedes na interni RC oscilator. a ten vis ze jede na 2MHz nebo jenom veris? tady taky muze byt zakladni problem. proste odchylka rychlosti od normovane je velka a pc jej nevezme. To by vysvetlovalo ze ti loopback chodi. mas rychlost, napr 1168b (chybovost mi vychazi na 2.66%) a pro RX a TX MCU. to funguje, proc ne. Ale pokud to chces pripojit s necim jinym, tak to fungovat nebude.

Napsal: 02 pro 2010, 21:26
od ceeert
Program mas zkompilovany pro 2MHz,mas na procesoru nastavené pojistky pro interní rc oscilátor 2MHz? Rekl bych ze ne,default hodnota je 1MHz. Pokud pošleš z uP jednou znak 0x0A a přijdou ti tři nuly na PC,máš pravděpodobně menší baudrate na uP,nebo pomalejší hodiny.

Napsal: 02 pro 2010, 21:45
od jano80
bohumilfulin píše:jo az ted jsem si vsiml ze jedes na interni RC oscilator. a ten vis ze jede na 2MHz nebo jenom veris? tady taky muze byt zakladni problem. proste odchylka rychlosti od normovane je velka a pc jej nevezme. To by vysvetlovalo ze ti loopback chodi. mas rychlost, napr 1168b (chybovost mi vychazi na 2.66%) a pro RX a TX MCU. to funguje, proc ne. Ale pokud to chces pripojit s necim jinym, tak to fungovat nebude.
mega skutocne bezi na 2MHz. Aj pri tej odchylke ktoru si vypocital, by predsa 97,44% udajov prisla spravne nie?

Napsal: 02 pro 2010, 21:48
od jano80
S baudrate som skusal hybat hore dole a nic. Akurat som skompiloval tento program pre TINY2313, a je zaujimave ze bezi na 1. sup. Tak sa zda je mega ma nejake vyhrady k tomu programu....

Napsal: 02 pro 2010, 22:08
od WLAB
kde je definovano F_CPU ? Pokud ho to bere jako 0, pak se UBRR dostane 0xffff, coz bude ultranizka rychlost, s dlouhy startbitem, ktery PC vyhodnoti jako 0x00, pokud mu nebude vadit, ze nejde stopbit.

Napsal: 02 pro 2010, 22:16
od jano80
F_CPU je definovane v <avr/io.h> nulove nieje , a pokial by nebolo definovane vobec , prekladac by hned hlacil chybu. Ale aj to bola jedna z veci ktore som tipoval ako zavadu, skusal som aj konkretnu frekvenciu CPU

Napsal: 08 pro 2010, 22:18
od bohumilfulin
>>>mega skutocne bezi na 2MHz. Aj pri tej odchylke ktoru si vypocital, by predsa 97,44% udajov prisla spravne nie?

-------------------
to ani nahodou!!! jednoducho se ti nezasynchronizuje port PC a neprijmes ani byte.

Tak ked to nejde lahko vezmi overeny kod a overene zapojenie HW z nejakeho tretieho zdroja a pokus sa postupne zistit kde je chyba.

mrkni oscilom co vysielas a s akymi bitovymi casmi,... Vsetko ostatne je len mudrovanie.

Tvrdis ze FW je OK, HW je OK, seriovy kabel je OK a nefunguje to. Asi nejake tvoje tvrdenie nebude uplne pravdive. V takomto pripade sa asi bez oscila nikam nepohnes. Podla toho co som cital za odpovede, vsetky zakladne moznosti chyby sme vycerpali. Tie nezakladne bez merania nemusis rychle objavit alebo vobec.

Napsal: 08 pro 2010, 22:32
od Andrea
U megy8 sdílí registr UCSRC adresu s registrem UBRRH, rozlišují se nejvyšším bitem zapisovaných dat (URSEL), pro zápis do UCSRC musí být URSEL=1, v tom programu to nevidím.

Napsal: 09 pro 2010, 06:12
od AB1
Jak píše Andrea, zápis
UCSRC = (0<<USBS)|(1<<UCSZ1)|(1<<UCSZ0);
přepíše UBRRH.
Kromě toho je zbytečný . Po resetu je nastaveno UCSZ0=1, UCSZ1=1, jak je vidět v popisu UCSRC v datašítu .

Stačí

Kód: Vybrat vše

void USART_vInit(void)
{
   UBRRH = (uint8_t)(USART_UBBR_VALUE>>8);
   UBRRL = (uint8_t)USART_UBBR_VALUE;
   UCSRB = (1<<RXEN)|(1<<TXEN);
}
Pak kód chodí, pokud je v pořádku nastavení oscilátoru.