Mohl by mi někdo ze znalejšís poradit s tímto problémem?
Příkazy
i=0;
do
{while((UCSRA&(1<<RXC))==0){};
prijato*=UDR;
i++;
…
…
}
while i<10
fungují, tak jak jsem očekával.
Zato příkazy
i=0;
do
{
prijato*=UDR;
i++;
…
…
}
while((UCSRA&(1<<RXC))==1);
nefungují ani náhodou, včetně různých modifikací. Vypadá to, že bit RXC se nechová tak jak se píše v dokumentaci, anebo dokumentaci vůbec nerozumím, což je asi pravděpodobnější.
Díky
administrator: přejmenováno z “ATTINY4313 versus USART”**
(UCSRA&(1<<RXC) není nikdy 1 (protože RXC není nultý bit v registru UCSRA.
Je třeba použít buď
while(UCSRA & (1<<RXC));
nebo
while((UCSRA & (1<<RXC)) != 0);
Pokud v uartu není žádný přijatý znak, je hodnota v UDR nula.
i=0;
do
{
prijato*=UDR;
i++;
....
....
}
while((UCSRA&(1<<RXC))!=0);
Tento kód přečte a uloží UDR ať je v něm přijatý znak nebo ne.
Pokud nebyl přijatý znak (RXC=0), opustí while().
Pokud byl přijatý znak, tak po jeho přečtení se RXC vynuluje a opět opustí smyčku dřív než se stačí přijmout případný další znak.
Pokud nechceš aby byl procesor blokovaný čekáním na znak, tak použij
while(1) // hlavní smyčka
{
if(UCSRA & (1<<RXC))
{
prijato* = UDR;
i++;
}
...
...
}
Další možnost je použít přerušení při příjmu znaku.**
Tento kód se však chová velmi podivně. Do prijato uloží pouze 3 znaky ať je příjmaný řetezec jakkoli dlouhý. Pokud je délka pouze 3 znaky přijmou se správně, pokud je délka přij.řetězce delší, přijmou se první 2 znaky a potom až ten poslední!!! Délka vloženého zpoždění na to nemá vliv.
Bohužel, ze všech pokusů mi zatím funguje jen příkaz
while((UCSRA&(1<<RXC))=0){}; na tom se ale program zasekne jakmilele se přijme celý řetězec.
{*
No je to preto, ze sa obe struktury chovaju principialne inak
Ta prva najprv naozaj caka, kym sa prijme bajt, az potom ho ulozi a az potom caka na dalsi bajt. Ten druhy kod sa naozaj moze spravat nevyspytatelne.
Prvy kod caka na prijem prave 10 bajtov. Pokial ich neprijme, ostane v slucke vysiet. Ten druhy sa uz s poctom prijatych bajtov moc nezapodieva a viac menej si moze robit skoro hocico.
Napriklad podmienka
#define KONCOVY_ZNAK 0x0d // napriklad
#define UVODNY_ZNAK ':' // napriklad
#define MAX_BUFER 100
static uint8_t prijato[MAX_BUFER], i;
i = 0;
do
{while((UCSRA&(1<<RXC))==0){};
prijato*=UDR;
if (prijato[0] == UVODNY_ZNAK) i++;
}
while ((i<MAX_BUFER) && (prijato* != KONCOVY_ZNAK))
if (prijato* == KONCOVY_ZNAK) {
// dobre ukoncena sprava
}
else {
// nejaka blbost sposobila pretecenie bufera
}
by mohla byt omnoho funkcnejsia. Ale neskusal som.
Samozreje do tej podmienky prijmu bajtu sa este da zakomponovat timeout. A pre dany kod je uplne normalne, ze ked raz pride do bodu
while((UCSRA&(1<<RXC))==0){};
tak tam ostane visiet az do skonania svetov, pokial mu medzitym nejaky bajtik nepride.***
Pokud v uart není přijatý znak, RXC je nula (a v UDR je 0).
Po přijetí znaku se RXC nastaví na 1 a v UDR je přijatý znak.
Jakmile přečteme přijatý znak ( prijato* = UDR;), RXC se hned znovu vynuluje (a UDR také).**
Testování počátečního a koncového bitu jsem se chtěl vyhnout, neboť to o co se pokouším by mělo analyzovat přijatou SMS a u té testovat počátek a konec bude trochu obtížnější protože její přesný formát nebudu schopen zajistit. Nicméně vyzkoušel jsem si následunící kód. Cování je opět trochu nevyzpytatrlné.
Pokud se provede příkaz break tak zbytek programu proběhne OK.
Pokud ovšem se cyklus for řádně ukončí, příkazy mezi odtud - sem se neprovedou a program se zablokuje na konci po odeslání temp*.
Ať ten fragment kontroluji sem tam nemohu najít důvod podivného chování. Jestli se něčeho všimnete, budu rád za upozornění.******