Stránka 1 z 1

atmega8 uart

Napsal: 28 pro 2012, 22:51
od jirkasi
zdravím po roce jsem se pokusil vrátit naprogramovat atmegu na přijímání dat ze sériového portu, ale pořád mi to nechodí. Nemám v tom velké zkušenosti a nikdo mi v tom jinak neporadí, takže to dělám pokus omyl. Pokusil jsem se to nataktovat s krystalem, ale povedlo se mi takhle 3 atmegám zablokovat pojistky, zkoušel jsem to podle http://www.engbedded.com/fusecalc/ a na 4 mhz oscilátor jsem nastavil Hfuse d9 a lfuse ec, nevím je to takový zmatený a prý to jde těžko odemknout, asi to není tak jednoduché rozchodit bez dlouholetých zkušeností. Tak jsem se ten problém pokusil obejít tím, že budu do atmegy posílat kód po 2 linkách, jeden bude jako kontrola a jeden bude posílat 0 a jedničky. Takže to funguje tak že TxD zapnu a přes Dtr pošlu jedničku nebo nulu. Atmega to přičte a stojí dokud se Txd nevypne a znovu nezapne. a Chtěl bych s tím řídit zatím jen diodu. Funguje to, ale špatně. Špatně se to sečítá, zkoušel jsem jak dekadicky, tak hexagonálně. Vždycky to dojede jen do 5 iterace a začne blikat, ale ty časy tomu neodpovídají, nevíte co s tím někdo?
Díky

(code)
#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 1000000UL

int main (void)
{

DDRB = 0x13;
int j=0x00;
int k;
loop_until_bit_is_clear(PINB,2);
if(bit_is_set(PINB,3))
{j=0x01;}
loop_until_bit_is_set(PINB,2);
loop_until_bit_is_clear(PINB,2);
if(bit_is_set(PINB,3))
{j = j + 0x02;}
loop_until_bit_is_set(PINB,2);
loop_until_bit_is_clear(PINB,2);
if(bit_is_set(PINB,3))
{j= j + 0x04;}
loop_until_bit_is_set(PINB,2);
loop_until_bit_is_clear(PINB,2);
if(bit_is_set(PINB,3))
{j= j + 0x08;}
loop_until_bit_is_set(PINB,2);
loop_until_bit_is_clear(PINB,2);
if(bit_is_set(PINB,3))
{j = j + 0x10;}
loop_until_bit_is_set(PINB,2);
loop_until_bit_is_clear(PINB,2);
if(bit_is_set(PINB,3))
{j= j+0x20;}
loop_until_bit_is_set(PINB,2);
loop_until_bit_is_clear(PINB,2);
if(bit_is_set(PINB,3))
{j = j+ 0x40;}
loop_until_bit_is_set(PINB,2);
loop_until_bit_is_clear(PINB,2);
PORTB = 0x02;
if(bit_is_set(PINB,3))
{j= j+0x80;}

while(1)
{
PORTB = 0x01;
k=0;
while(1){
_delay_ms(1);
k++;
if(k==j)break;
}
PORTB = 0x00;
k=0;
while(1){
_delay_ms(1);
k++;
if(k==j)break;
}


}

return 0;
}
(/code)

Napsal: 29 pro 2012, 09:47
od AB1
oscilátor jsem nastavil Hfuse d9 a lfuse ec

Vyber vždycky řádek s nejdelším startovacím časem (+64 ms).
Lfuse bude FD.
A pokud nastavíš krystal, tak musí být připojený, jinak čip s programátorem nekomunikuje.

Uart podle mých zkušeností chodí i s novým mega8, který má nastavený vnitřní oscilátor 1 MHz. Ale max. rychlost při 1 MHz je 4800 baudů (9600 pro double speed).

Nezdržuj se nějakým bitbangovým testováním.
Uart zkoušej s nějakým terminálem. Já používám Hercules
http://www.hw-group.com/products/hercules/index_en.html

1. Na terminálu nastav číslo portu a rychlost 4800 baud. Otevři port.
2. Seriový kabel připoj do PC.
3. Na druhé straně kabelu zkratuj piny 2,3.
4. Znaky které napíšeš v terminálu se vrací a zobrazují.
5. Zapoj MAX 232.
6. U MAX32 zkratuj piny které jdou na TXD, RXD procesoru (procesor zatím není připojený). Terminál musí zase opakovat znaky.

Tím je vyzkoušeno, že cesta z PC k mproc funguje.
Teď zkus program (opět vrací znaky vyslané z terminálu).

Kód: Vybrat vše

#ifndef F_CPU
#define F_CPU 1000000UL
#endif
#include <avr/io.h>

//--------------------------------------------------------------------------
void uart_init(uint32_t baud)
{
   //set baud rate
   UBRRH = ((F_CPU/(16*baud)-1)) >> 8; 
   UBRRL = (uint8_t)((F_CPU/(16*baud)-1));

   //enable receiver and transmitter
   UCSRB = (1<<RXEN)|(1<<TXEN);
   }

//--------------------------------------------------------------------------

// receive a byte
unsigned char uart_getc( void )
{
   while ( !(UCSRA & (1<<RXC)) )
   ;
   return UDR;
}

//--------------------------------------------------------------------------

// send a byte
void uart_putc(unsigned char data )
{
   while ( !( UCSRA & (1<<UDRE)) )
   ;
   UDR = data;
}


unsigned char received_byte;


// ============================================
int main (void)
{
   uart_init(4800);
   
   while(1)
   {
      received_byte = uart_getc();
      uart_putc(received_byte);
   }
}   

Napsal: 29 pro 2012, 10:20
od Panda38
Dá se vystačit i s HyperTerminálem. který je součástí Windows.

Napsal: 29 pro 2012, 13:52
od Atlan
Do pozornosti tabulku v datasite kde su prenosove rychlosti a chyba v zavyslosti pouzitom kristale vid strana 159. Aby nas neobstastnoval chybovym prenosom...

Napsal: 29 pro 2012, 21:24
od jirkasi
díky, vracím se v úterý domů, tak to potom vyzkouším