ATTINY4313 versus USART
Moderátor: Moderátoři
Tady asi nejde o problém hodin.
Píše:
Pokud je délka pouze 3 znaky přijmou se správně
epes:
Kód: Vybrat vše
UCSRB |= (1 << RXEN) | (0 << TXEN |1<<RXCIE); Měl bys používat funkce pro uart, jak je běžné.
Je také nutné nějak detekovat konec zprávy,
nejlepší je když zpráva má nějaký koncový znak.
Posílám vyzkoušený kód, který přijme max 40 znaků, zakončených znakem '*'.
Na připojeném obrázku je vidět test s terminálem Hercules.
Vyslané znaky jsou červené, přijaté černé.
A možná by stálo za úvahu přejít na jiný překladač než MikroC.
Kód: Vybrat vše
#include <avr/io.h>
//--přijmi bajt ---------------------------
unsigned char uart_getc( void )
{
while ( !(UCSRA & (1<<RXC)) )
;
return UDR;
}
//-- pošli bajt ---------------------------
void uart_putc(unsigned char data )
{
while ( !( UCSRA & (1<<UDRE)) )
;
UDR = data;
}
//-- pošli string -------------------------
void uart_puts(char *s )
{
while(*s != 0)
{uart_putc(*s); s++;}
}
//-----------------------------------------
char znaky[41]; // string 40 znaků
unsigned char i;
//=========================================
int main(void)
{
UCSRB = (1<<RXEN)|(1<<TXEN);
UBRRH = 0;
UBRRL = 51; // 9600 baud při 8 MHz
uart_puts("start\r\n");
while(1)
{
if(UCSRA & (1<<RXC)) // jestli přišel znak
{
for(i=0;i<40;i++) // přijmi max 40 znaků
{
znaky[i] = uart_getc();
if(znaky[i] == '*') // přišel koncový znak
{
znaky[i] = 0; // ukonči string nulou
break; // a vystup ze smyčky for()
}
}
uart_puts(znaky); // pošli přijaté znaky
uart_puts("\r\n");
}
}//while(1)
}//main()
//=========================================
- Přílohy
-
uart.gif- (48.1 KiB) Staženo 78 x
Proč tady zapínáš přerušení RXC?
Měl bys používat funkce pro uart, jak je běžné.
Je také nutné nějak detekovat konec zprávy,
nejlepší je když zpráva má nějaký koncový znak.
Přerušení zapínám protože příjem zprávy chci realizovat mimo hlavní program.
Instrukce používám dle datašítu pro ATTINY4313. Nevím jaký je rozdíl mezi UART a USART.
Koncový znak, ač nerad, jsem jsem vyzkoušel již o víkendu (také hvězdičku), navíc jsem přidal časový test, protože nemůžu 100% zajistit, že v SMS zprávě ta hvězdička vždy bude.
Kód: Vybrat vše
while ( !( UCSRA & (1<<UDRE)) )
;
UDR = data; Přesně tuto konstrukci jsem nechtěl použít - 40x volat podprogram nebo přerušení kvůli jedné zprávě mně nepřipadalo jako nejlepší řešení. Ale jak je vidět je na rozdíl od této konstrukce funkční
Kód: Vybrat vše
for(i=0;i<40;i++)
{while ( !( UCSRA & (1<<UDRE)) )
znak[i]=UDR;
}Jinak vidím, že tobě příkaz break funguje. V mém případě příkazy continue a break fungují podivně a raději jsem je nahradil přikazem GOTO.
40x volat podprogram nebo přerušení kvůli jedné zprávě mně nepřipadalo jako nejlepší řešení.
Naopak, od toho přerušení po přijmu znaku je.
Nevím jaký je rozdíl mezi UART a USART
USART - Universal Synchronous / Asynchronous Receiver and Transmitter
UART - Universal Asynchronous Receiver and Transmitter
V praxi se převážně používá asynchronní mód. Synchronní se mě vybavuje momentálně pouze jeden a to PS/2 klávesnice. Synchronní režim je víc odolnější proti chybám, nedochází ke ztrátě znaků, ale potřebuje minimálně o jeden vodič navíc (hodiny). V asynchronním režimu musí přijímač hodiny rekonstruovat, kvůli tomu je potřeba mnohem přesněji dodržet stejnou rychlost na obou stranách přijímač/vysílač.
Rád bych tě požádal, jestli bys nemohl na svých strojích vyzkoušet tuto konstrukci
Kód: Vybrat vše
for(i=0;i<40;i++)
{while ( !( UCSRA & (1<<UDRE)) )
znak[i]=UDR; Díky
problém je, že překladač, který používám tyto fce nezná,
Tyto funkce jsem napsal na začátek kódu, takže každý překladač se je rychle naučí.
Možná by to chtělo přečíst něco o funkcích v C.
má sice jiné fce, ale ty jsou pěkně nenažrané
Nejsou.
Schválně jsem nainstaloval MikroC-demo a použil vestavěné funkce.
Kód má 361 bajtů proti původním 349 bajtům.
Kód: Vybrat vše
//MikroC - Attiny2313 - 8 MHz
char znaky[41]; // string 40 znaků
unsigned char i;
//=========================================
main(void)
{
UCSRB = (1<<RXEN)|(1<<TXEN);
UBRRH = 0;
UBRRL = 51; // 9600 baud při 8 MHz
UART1_Write_Text("start\r\n");
while(1)
{
if (UART1_Data_Ready() == 1) // jestli přišel znak
{
for(i=0;i<40;i++) // přijmi max 40 znaků
{
znaky[i] = UART1_Read();
if(znaky[i] == '*') // přišel koncový znak
{
znaky[i] = 0; // ukonči string nulou
break; // a vystup ze smyčky for()
}
}
UART1_Write_Text(znaky); // pošli přijaté znaky
UART1_Write_Text("\r\n"); //new line
}
}//while(1)
return 0 ;
}//main()
(Nemusí mít platnou revizi.)
(Celkově budu raději, když se to obejde bez papírů.)
Dej sem prosím celý svůj kód, takhle ani není úplně jasné, zda přijaté znaky čteš při přerušení nebo pollingem. A nechceš vyzkoušet AVR studio ? Je zadarmo, na internetu k němu nalezneš tisíce funkčních příkladů a knihoven.