Hledám zdrojový kód v C pro nastavení USART na ATmega8

Zdravim, hladam code v c pre nastavenie USART na mega8 cisto len aby mi fungovala komunikacia na posielanie dat do PC. A este otazka ci mi bude stacit len vnutorny oscilator ci budme potrebovat externy krystal. Som zaciatocnik a kazda rada bude dobra. Kontakt newmannko@yahoo.com alebo ICQ: 376229986. Vopred dik…

:arrow_right: administrator: přejmenováno z "ATmega8"
:arrow_right: administrator: vrátil se mi tvůj registrační (aktivační) email, máš-li stále zájem o registraci, napiš mi, prosím, na forum (zavináč) mcontrollers (tečka) com z jiného funkčního emailu

Kazdy procesor ma dokumentaciu (datasheet) a v nej su zakladne veci vysvetlene. Okrem ineho aj priklady v ASM a v C pre zakladnu pracu s tou ktorou periferiou. treba si to pozriet, opisat (Ctrl+C a Ctrl+V) a pripadne obkleslit :slight_smile:

kapitola:
USART Initialization

Data Transmission – The USART Transmitter

Data Reception – The USART Receiver

V inej casti fora sa pytas, ako sa nastavi frekvencia oscilatora. Zase len datasheet, kapitola :

Calibrated Internal RC
Oscillator

Tam je uvedena i praca s registrom pre nastavenie inej frekvencie ako je zakladna.

Pre komunikaciu by som Ti urcite doporucil pouzit externy Xtal s frekvenciou 14.7456MHz, alebo 7.3728MHz. Z tychto frekvencii sa lahko odvodzuju bezne prenosove rychlosti pre UART. Interny RC sa za urcitych podmienok pouzit da, ale pre zaciatok musis mat istotu, ze parametre, ktore si nastavil pre UART, vedu k dostatocne presnej prenosovej frekvencii.

Ano rozumiem len by som chcel to viac ozrejmit co vsetko musim nastavit bo som to precital cele a je toho dost a mam v tom chaos. Poste jednoducho povedat tento register na to a tento bit takto…

… normalne z datasheetu :smiling_imp:

Predpokladam, ze je ti jasne, co to vobec je ta seriova asynchronna komunikacia cez UART. Ak nie, najdi si prislusnu literaturu, napriklad na hw.cz.

Ak chces iniciovat komunikaciu, pouzijes rutinu na strane 136 (moj manual)

void USART_Init( unsigned int baud )
{
//  Nastavis si Baudovu rychlost - cislo "baud" si najdi v tabulke Bd rychlosti pre Tvoj Xtal
/* Set baud rate */
UBRRH = (unsigned char)(baud>>8);
UBRRL = (unsigned char)baud;

//Zapni si prijem a vysielanie UARTu
/* Enable Receiver and Transmitter */
UCSRB = (1<<RXEN)|(1<<TXEN);

//NAstav si mod komunikacie 8N2
/* Set frame format: 8data, 2stop bit */
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
}

Ak chces vysielat jednotlive bajty, pouzijes rutinu na strane 137 (moj manual)

void USART_Transmit( unsigned char data )
{
// Cakaj, pokial predchadzajuci byte neopusti transmit bufer, aby si mohol vlozit dalsi byte
/* Wait for empty transmit buffer */
while ( !( UCSRA & (1<<UDRE)) )
;
// vloz dalsi byte
/* Put data into buffer, sends the data */
UDR = data;
}

Ak cakas na nejake bajty, ktore ti maju prist z PC, tak zober rutinu zo strany 140 (moj manual)

unsigned char USART_Receive( void )
{
// cakaj na prijem noveho bajtu
/* Wait for data to be received */
while ( !(UCSRA & (1<<RXC)) )
;
// ked prisiel, tak si ho vyzdvihni a urob si s nim co chces
/* Get and return received data from buffer */
return UDR;
}

Viac, ako skopirovat hotove kody z datasheetu od Atmelu do prispevku uz pre teba spravit neviem. Sorry. :slight_smile:

no uz pochopil, takto by verzeral moj kod:

#include <avr/io.h>

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

int main (void)
{
UCSRB |= (1 << RXEN) | (1 << TXEN);

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

UBRRL = BAUD_PRESCALE;

UBRRH = (BAUD_PRESCALE >> 8);
for (;:wink:
{

while ((UCSRA & (1 << RXC)) == 0) {};

ReceivedByte = UDR;

while ((UCSRA & (1 << UDRE)) == 0) {};

UDR = ReceivedByte;
}
}

Lenze ze frekvencia standartne je nastavena na 1MHz, a ja potrebujem 7372800Hz a taktiez neviem ako na baud rate ten je 9600

respektive moja otazka znie ako nastavim inu hodnotu system clock ako je 1MHz ?

Tak nakoniec som zvolil moznost ext.crystalu 7,3728MHz pri 9600 Baud Rate je hodnota UBRR=47 a ziadny error tak to by malo ist, len otazocka k zapojeniu krystala k mega8. XTAL1 a XTAL2 vratane dvoch 22pF kondikov privedenych na zem. Tak by to malo byt… Len ked to napojim na tu megu tak ta frekv.sa mi nastavi automaticky? ci treba dalsie nastavenia spravit?

Toto je “najnebezpecnejsia” faza nastavenia poistiek, nastastie sa robi v zariadeni iba raz

Tabulka c.4, c.5

Poistky:
CKSEL3…0 nastav do 1
CKOPT nastav do 1
SUT1 nastav do 1
SUT0 nastav do 0 alebo 1

Nebezpecie spociva v tom, ze ak povise procesoru, aby ocakaval externy clock, alebo RC oscilator, uz sa Ti nerozbehne a tym padom ho cez SPI ani nepreprogramujes.
Ak CKSEL naprogrmujes na log.0, to znamena, ze mcu ocakava externy zdroj hodin, nie iba Xtal.

Ak mas PonyProg,alebonieco podobne, tam zaskrtnute policko znamena log.0 (preprogramovanie z log.1 do log.0, lebo log.1 je “kludovy” stav). Tu sa deju najcastejsie chyby.
Obcan si v dobrej viere zaskrta policka aby mal CKSEL na 1 a ajhla, uz su na nule so vsetkymi dosledkami.

Tak si to cele este raz poriadne skontroluj, dufam, ze ani ja som sa v tomtotexte nepomylil. Nerad by som mal na svedomi nejaku fatal error. Ale aj pri zle naprogramovanych poistkach sa s procesorom VZDY da dohodnut cez paralelny programator.

este sa chcem spytat. Ak by som chcel pouzit interny oscilator pre usart, tak ako by som mal najlepsie nastavit frekvenciu a baud rate aby to slapalo?

Nastavovanie postiek(fuses) , kuk stranku.

no uz som prisiel na to. potrebujem nastavit interny oscilator na 8MHz, pri baud rate 9600 UBRR=51, ako nastavit tie bity ? :slight_smile:

no tak z datasheetu: CKSEL 3…0=0100 (8MHz), SUT 1…0=10 (65ms), len neviem co s OSCCAL bo to tam je v percentach a hodnoty 0x00, 0x7F, 0xFF, a najvacsi problem ako to napisat v kode :slight_smile:

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

void USARTInit(uint16_t ubrr_value)
{

UBRRL = ubrr_value;
UBRRH = (ubrr_value>>8);
UCSRC=(1<<URSEL)|(3<<UCSZ0);
UCSRB=(1<<RXEN)|(1<<TXEN);

}

char USARTReadChar()
{

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

}
return UDR;

}

void USARTWriteChar(char data)
{
while(!(UCSRA & (1<<UDRE)))
{

}
UDR=data;

}

void main()
{

char data;

USARTInit(51);		//UBRR = 51

while(1)
{
	data=USARTReadChar();


	USARTWriteChar('');
	USARTWriteChar(data);
	USARTWriteChar(']');
}

}

kde do kodu mam definovat CKSEL, SUT a OSCCAL? a aku hodnotu priradit OSCCAL ? som to nepochopil v tom datasheete

OSCCAL=0xE4 mi zobralo ale ked dam CKSEL3=0 tak napise ze nie je deklarovanane a ani SUT

Fuses nastavujes pomocou programatora.
Tak ako posielas do mcu kod, tak tvoj programator musi mat moznost prepisat Fuses i OSCCAL (Dragon umoznuje OSCCAL programovat samostatne).
Fuses sa neprepisuju “v ramci programu”, ale pomocou programatora.

Tak som sa rozhodol ze pouzijem externy krystal 7,3728 MHz Baud rate 9600, UBRR=47,(dufam ze je to spravne) pripojil som ho na mega8 na 9 a 10 pin (XTAL1, XTAL2) plus na obidve nozisky som dal 22pF kondiky ktore idu na zem ,v avr studio som v nastaveniach fuses nastavil na Externy crystal -high freq.-65ms [CKSEL1111, SUT11] a este CKOPT=1 (to som nasiel aj v datasheete). a zrazu sa nemozem dostat na megu ani zapis nic, resp. je odpalena a neviem v com mohol nastat problem. Nezabudol som na nieco? pripojil som aj pic kde su nastavenia z datasheetu.
A este ked som nsatavil interny oscilator na 8Mhz tak som aspon komunikoval cez hyperterminal lenze mi to nehadzalo tie hodnoty ktore malo, tak neviem kto by mi poradil co s tym… :unamused:

Skus pozriet moj prispevok z 04 březen 2009, 20:14.
Asi si si Fuses nastavil presne opacne ako si chcel (napr. v Ponyprogu zaskrtnute uses znamena nastavenie do 0, neviem aky program pouzivas).
Procesor teraz caka, kedy ze mu to pride z vonku frekvencia, aby sa mohol podla nej riadit (pozdri v datasheete mod “vsetky prislusne fuses na nulu”).
Pomoze tam tu frekvenciu dodat, napr z ineho procesora, ktory moze kmitat nazickou, alebo z generatora napr. s 555. Na stabilite a presnosti frekvencie nezalezi, ale frekvencia musi byt aspon 4x vyssia ako je programovacia frekvencia cez SPI.
Ale na to postvy paralelny programator. Ten si s tym vie rady vzdy.
V ziadnom pripade sa nejedna o nejaku chybu, ci uz programatora, alebo procesora.
Jednoducho, ak ma procesor moznost nastavit rozne zdroje hodin, tak ich musi byt samozrejme mozne i nejak prenastavit a ak si obsluha vyberie kombinaciu, ktoru jej hw neobsahuje, procesor sa to uz nema ako dozvediet a pracuje podla nastavenych fuses (poistiek). Treba vediet co sa robi a ako (polarita poistiek v obsluznom programe)
Ale procesor rozhodne vyhadzovat nemusis :slight_smile:

No tak seriovu linku som uz rozbehal, len mojim dalsim problemom je nastavit casovanie! chcel by som to nastavit na 1ms, pouzivam krystal 7,3728 Mhz, v datasheete som sa docital: treba si zvolit predelicku (8,64,256,1024), z mojej frekvenice potrebujem dostat cas (1/f), tento cas vynasobit tak aby som dostal cca tu 1ms. pri 8bit max 255, , 1ms podelit casom=1/f … a uz sa stracam a ani neviem co som pisal poriadne… vie mi to nekto vysvetlit respektive vypocitat?

Kmitočet krystalu f = 7,3728 MHz.
1 perioda = 1 / f = 1 / 7,3728 = 0,13563 microsec.

1 krok čítače trvá 0,13563 microsec.

Pro 1000 us potřebujeme
1000 / 0,13563 = 7328 kroků.

Pro osmibitový čítač použijeme dělič 64.
Počet kroků je pak 7328 / 64 = 115,2.
Když nastavíme 115, chyba bude 1,7 promile.

dik zxa info, len 1000/0,13563 je myslim 7373 :wink: a este k tej predelicke tu si volim tak aby som mal co najmensie desatine cislo ak som dobre pochopil ?