logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

ATMEGA-8 i RS232 nie chca wspolpracowac

aniasta 07 Lut 2009 19:36 3971 16
  • #1 6117427
    aniasta
    Poziom 10  
    Witam, mam taki projekt do zrobienia w którym muszę miedzy innymi wysłać informacje z ATMEGI-8 do komputera.

    Napisałam krótki program który powinien wysyłać co 5 sekund znak '5' przez TxD procesora:

    
    #include <avr/io.h>
    #include <util/delay.h>
    #define F_CPU		1000000 	//częstotliwość zegara w Hz
    #define UART_BAUD	600   		//prędkość transmisji
    #define UART_CONST	(F_CPU/(16ul*UART_BAUD)-1)
    
    void putchar (char c)
    {
      UDR=c;
      loop_until_bit_is_set(UCSRA,TXC);
      UCSRA |= _BV(TXC);		   //sbi(USR,TXC);
    }
    
    void UART_init(void) 
    {
      UBRRL = (unsigned char)UART_CONST;  // ustaw prędkość transmisji 
      UCSRB = _BV(RXEN)|_BV(TXEN);        // załącz tx, rx
    }
    
    int main(void)
    {
    DDRD=0x02;
    PORTD=0x02;
    UART_init(); 
      while(1)
      {
    	putchar('5');
    	_delay_ms(5000);  
      }
    }
    


    Program jest oparty na przykładach z tej strony:
    http://avr.elektroda.eu/?q=node/16
    przy czym tutaj jest Atmega16 więc są inne rejestry i nie wiem czy dobrze je pozamieniałam.

    oczywiście coś nie działa i właśnie chciałam się zapytać co robię źle?
    program kompiluję w AVR Studio 4 z AVR-GCC
    a stan na RSie sprawdzam programem Terminal v1.9b , który znalazłam tutaj na elektrodzie

    wtyczka i układ są na pewno dobrze połączone bo dostałam je od prowadzącego. Używane są tu tylko piny 2,3,4 i 5 RSa, zgodnie z tym obrazkiem http://pl.wikipedia.org/wiki/RS232
  • Pomocny post
    #2 6117924
    maly_elektronik
    Poziom 23  
    Masz błąd w funkcji usart_init().
    Brakuje Ci ustawień starszegi bajtu danych UBBRH oraz jednej najważnejszej rzeczy nie ustawiłeś ramki danych tzn bitów stopu, kontroli parzystości oraz wielkości ramki :)
    Funkcja usart_init() powinna wyglądać mniejwięcej tak:
    
    
    void USART_Init()
    {
      /* Ustawianie prędkości*/
      UBRRH = (unsigned char)(UART_CONST >>8);
      UBRRL = (unsigned char)UART_CONST ;
      /*Zezwolenie na nadawanie i odbiór danychr */
      UCSRB = (1<<RXEN)|(1<<TXEN);
      /* Ustaienia 1bit stopu i 8bitów danych */
      UCSRC = (1<<URSEL)|(0<<USBS)|(3<<UCSZ0);
    }


    a funkcja wysyłania danych mniejwięcej tak:
    
    
    void putchar(unsigned char c)
    {
      while ( !( UCSRA & (1<<UDRE)) ) ;// albo jeżeli się nie myle to loop_until_bit_is_set(UCSRA,UDRE)
      UDR = c;
    }
  • #3 6118063
    aniasta
    Poziom 10  
    O dziękuje, poustawiałam to tak jak powiedziałeś i uruchomiłam.
    Jest już jakaś transmisja, ale teraz w komputerze otrzymuje cały czas jakieś FF, FF, FF, FF i tak ciągle.. wysyła bez zatrzymania.

    teraz mój kod wygląda tak:
    
    #include <avr/io.h>
    #include <util/delay.h>
    //#define F_CPU		1000000 	//częstotliwość zegara w Hz
    #define F_CPU 1000000UL 
    #define UART_BAUD	1200   		//prędkość transmisji
    #define UART_CONST	(F_CPU/(16ul*UART_BAUD)-1)
    
    void USART_Transmit( unsigned char data )
    {
       while ( !( UCSRA & (1<<UDRE)) );   /* Wait for empty transmit buffer */
       UDR = data;                  /* Put data into buffer, sends the data */
    } 
    
    void USART_Init( unsigned int ubrr )
    {
       UBRRH = (unsigned char)(ubrr>>8);         /* Set baud rate */
       UBRRL = (unsigned char)ubrr;   
       UCSRB = (1<<RXEN)|(1<<TXEN);      /* Enable Receiver and Transmitter */   
       UCSRC = (1<<URSEL)|(0<<USBS)|(3<<UCSZ0);   /* Set frame format: 8data, 2stop bit */
    } 
    
    int main(void)
    {
    DDRD=0x0f;
    USART_Init(UART_CONST);
     
      while(1)
      {
    	USART_Transmit('a');
    	_delay_ms(5000);  
      }
    }
    
  • Pomocny post
    #4 6118246
    MarasK
    Poziom 18  
    jaki masz podłączony kwarc? Ew wewnętrzny rezonator
  • #5 6118280
    aniasta
    Poziom 10  
    mam tylko to co wewnątrz, i z tego co wiem to powinien on mieć częstotliwość 1 MHz, chociaż w symulacji w AVR Studio pokazuje ze niby 4 MHz, wiec nie jestem pewna. W programie napisałam:
    #define F_CPU 1000000UL
    bo gdzieś widziałam ze tak to powinno być opisane.
  • Pomocny post
    #6 6118642
    Freddie Chopin
    Specjalista - Mikrokontrolery
    w symulatorze pokazuje ci 4, bo masz ustawione 4 dla symulatora w opcjach projektu - nie ma to nic wspolnego z prockiem. pogrzeb w opcjach projektu (takie kolko zebate w dolnej linijce po prawej) i sobie to zmien.

    masz ustawione takie same parametry w terminalu? 2 bity stopu, 1200, 8bitow, brak parzystosci i kontroli przeplywu?

    4\/3!!
  • #7 6118932
    aniasta
    Poziom 10  
    tak, mam ustawione w terminalu wszystko tak jak powiedziałeś.
    a nawet podczas transmisji sobie zmieniałam te parametry i wtedy troche inne rzeczy sie wysyłaly ale ciągle to byly wartości z FF i FC FE FD takie tam...

    ale mnie martwi to ze w moim programie ma być nadawany jeden znak raz na 5 sekund. a jak to włączam to te znaki FF sa odczytywane baardzo szybko.. w sekunde to mi sie takich z 20 wyświetla.
  • Pomocny post
    #8 6119335
    maly_elektronik
    Poziom 23  
    W 99% procentach masz złe ustawienia kwarcu w procku (albo jeżeli używasz max232 to źle dobrane jego kondensatorki :idea: ) :) Sprawdź fusy bo jak to bywa w atmegach jeżeli sam ich nie ustawisz to czasem szwankują (sam się z tym meczyłem chyba z tydzień) :) Jeżeli masz taką możliwość to podepnij jakiś kwarc zewnętrzny + 2 kondensatorki, ustaw w opcjach kompilacji że masz kwarc zewnętrzny, jego wartość i nie zapomnij o zmianie fusów na kwarc zewnętrzny :)

    Pozdrawiam maly_elektronik
  • Pomocny post
    #9 6119340
    krzemowy
    Poziom 19  
    Spróbuj takiego kodu. U mnie on działa, tyle że na Atmega8535(nie mam ósmej atmegi luzem).

    
    #include <avr/io.h>
    #include <util/delay.h>
    
    static void uart(void)   //konfiguracja UART wzięta z dokumentacji avr-gcc
    {
    	#define BAUD 1200
    	#include <util/setbaud.h>
    	UBRRH = UBRRH_VALUE;
    	UBRRL = UBRRL_VALUE;
    	#if USE_2X
    	UCSRA |= _BV(U2X);
    	#else
    	UCSRA &= ~_BV(U2X);
    	#endif
    	UCSRB |= _BV(TXEN);
    }
    
    void write_char(unsigned char bajt)
    {
    	while ((UCSRA & _BV(UDRE)) == 0);
    	UDR = bajt;
    }
    
    int main(void)
    {
    	uart();
    	while(1)
    	{
    		write_char('a');
    		unsigned char i;
    		for(i = 0; i < 100; i++) _delay_ms(50);  //starsze wersje gcc miały problem z długimi opóźnieniami
    	}
    }
    


    Pamiętaj żeby w ustawieniach projektu włączyć optymalizację na dowolnym poziomie byle nie zerowym :) W przeciwnym razie kompilator będzie się burzył że będzie problem z opóźnieniami.
    ATMEGA-8 i RS232 nie chca wspolpracowac
    Oczywiście procesor należy ustawić na Atmega8. Menu konfiguracji projektu można znaleźć tak jak Freddie pisał ewentualnie w menu Project -> Configuration options.

    Następna kwestia to taktowanie procesora. Domyślnie jest 1MHz z wewnętrznego generatora RC, sprawdź o ile masz możliwość czy tak rzeczywiście jest.
    ATMEGA-8 i RS232 nie chca wspolpracowac

    Widać przy okazji że skoro procesor chodzi na wewnętrznym generatorze RC to są cztery możliwe częstotliwości, jeżeli nie wiadomo na jakiej pracuje można próbować ustawić na chybił trafił. Nie trzeba pisać #define F_CPU xxxxx, można wpisać częstotliwość pracy w polu Frequency widocznym na rys. 1 ;)
  • Pomocny post
    #10 6119395
    maly_elektronik
    Poziom 23  
    Krzemowy napisał:
    Cytat:
    Nie trzeba pisać #define F_CPU xxxxx

    Nawet należy to pisać bo czasami (nawet często kod nie jest kompilowany tylko i wyłącznie w AVRStudio, czasem jest to WinAVR albo w ogóle na innym systemie operacyjnym) nie zaskakuje #include<util/delay> bez tego i zaczynają się problemy z szukaniem głupiego błędu :)

    Pozdrawiam maly_elektronik
  • #11 6121000
    aniasta
    Poziom 10  
    Już wszystko mi działa, dziękuje za pomoc, faktycznie problem tkwił w fusebitach, mam tam ustawiony zegar 8 MHz i tak już sobie zostawiłam. No i jeszcze był włączony Watchdog, dlatego procesor tak szybko wysyłał te "FF".

    teraz mój program wygląda tak: (wklejam gdyby ktoś miał taki kłopot jak ja)
    działa komunikacja w obie strony,
    a mój procesor to Atmega 8 - 16AU 08096

    
    #include <avr/io.h>
    #include <util/delay.h>
    #define F_CPU 8000000UL 
    #define UART_BAUD	9600   		//prędkość transmisji
    #define UART_CONST	(F_CPU/(16ul*UART_BAUD)-1)
    unsigned char x=0;
    
    void USART_Transmit( unsigned char data )
    {
       while ( !( UCSRA & (1<<UDRE)) );   /* Wait for empty transmit buffer */
       UDR = data;                  /* Put data into buffer, sends the data */
    } 
    
    unsigned char USART_Receive( void )
    {
       while ( !(UCSRA & (1<<RXC)) );            /* Wait for data to be received */
       return UDR;                           /* Get and return received data from buffer */
    }
    
    void USART_Init( unsigned int ubrr )
    {
       UBRRH = (unsigned char)(ubrr>>8);         /* Set baud rate */
       UBRRL = (unsigned char)ubrr;   
       UCSRB = (1<<RXEN)|(1<<TXEN);      /* Enable Receiver and Transmitter */   
       UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);   /* Set frame format: 8data, 2stop bit */
    } 
    
    int main(void)
    {
    DDRD=0x02;
    PORTD=0x00;
    USART_Init(UART_CONST);
    
       while(1)
      {
    	USART_Transmit('a');
    	_delay_ms(500);  
    	x=USART_Receive();
          while(x=='7')
    	  {
    	  USART_Transmit('4');
    	  _delay_ms(500);  
    	  x=USART_Receive();
    	  }
    	  while(x=='1')
    	  {
    	  USART_Transmit('3');
    	  _delay_ms(500);  
    	  x=USART_Receive();
    	  }
      }
    }
    


    Pozdrawiam,
    Ania
  • #12 6303971
    lstaszew
    Poziom 12  
    Niestety tez mam drobny problem z transmisja RS232 i juz nie wiem co może być źle. Kod wzorowany na dokumentacji i jeżeli chodzi o wysyłanie slów czy pojedynczych znaków do komputera to wszystko jest ok, jednakże problem pojawia się gdy chcę te dane odebrać i wyslać je ponownie do terminala. Wtedy też niestety nic się nie dzieje, gdyż program utyka w pętli
    while(!(UCSRA & (1<<RXC)) );

    Poniżej zamieszczam napisany przezemnie kod jeżeli ktoś widzi bląd w tym kodzie proszę o pomoc
    
    #include <avr/io.h> 
    #include <avr/interrupt.h> 
    #include <avr/signal.h>
    #include <util/delay.h>
    #define FOSC 11059200
    #define BAUD 9600
    #define MYUBRR FOSC/16/BAUD-1
    
    void usart_init(unsigned int ubrr)
    {
    UBRRH = (unsigned char)(ubrr>>8);
    UBRRL = (unsigned char)ubrr;
    UCSRB = (1<<RXEN)|(1<<TXEN); 
    UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
    }
    
    void nadaj_znak(unsigned char data)
    {
    while(!(UCSRA&(1<<UDRE)));
    UDR=data;
    }
    
    unsigned char odbierz_znak(void)
    {
    while(!(UCSRA & (1<<RXC)) );
    return UDR;
    }
    
    void wyslij_slowo(char *dana)
    {
    int dlugosc_slowa, k=0;
    dlugosc_slowa=strlen(dana);
    for(k=0;k<dlugosc_slowa;k++)
    	{
    	nadaj_znak(dana[k]);
    	}
    }
    
    int main(void)
    {
    DDRD=0x02; 
    PORTD=0x00;
    usart_init(MYUBRR);
    _delay_ms(100);
    nadaj_znak(0x0D);
    wyslij_slowo("Witam w programie testowym ");
    while(1)
    	{
    	wys=odbierz_znak();
    	_delay_ms(100);
    	nadaj_znak(wys);
    	_delay_ms(100);
    	}
    }
  • #13 6308523
    Redok
    Poziom 13  
    mam pytanie... jak mam atmega z dwoma Uart'ami w jaki sposob moge sczytywac z obydwu wejsc i wysylac rozniez niezaleznie prze dwa wyjascia?
  • #14 6309151
    lstaszew
    Poziom 12  
    Czy spotkal się może ktoś z problemem podobnym do mojego?? siedze już nad tym trochę i już za bardzo nie mam pomysłu gdzie szukać błędu. A więc..
    Korzystam z przejściówki USB=>RS232 i przejściówka ta jest na bank OK bo po zwarciu nóg MAXA232 (nogi 13 i 14) w terminalu i Realterm jest echo. Problem zaczyna się w momencie gdy chce uzyskać echo (Zwierając końcówki 11 i 12 MAXA232) oraz odebrać znaki z kompa. Program zachowuje się tak jakby zawieszał się w pętli while(). Po odcięciu końcówki TXD atmegi8 i zwarciu końcówek 11 i 12 MAXA232 echo już jest;/ Czy jest ktoś w stanie chociaż mi napisać gdzie powinienem szukać błędu??
  • #15 6327474
    lstaszew
    Poziom 12  
    Witam ;) otóż problem rozwiązany. Niestety programowo wszystko jest ok. Problem był po stronie programatora (USBASP) tzn gdy jest on podłączony do układu nie ma możliwości wysyłania i odbierania znaku gdyż USBASP "niby" korzysta z tych pinów jednakże po odłączeniu od programatora pinów RXD oraz TXD wszystko śmiga ;d i o dziwo piny te nie mają znaczenia na pracę programatora.
  • #16 6330434
    OldSkull
    Poziom 28  
    Jak podłączyłeś ten programator? :o On korzysta tylko z Sck, MISO, MOSI, RST i GND układu programowanego. Sam ostatnio z ATmegi8 do kompa (i w druga stronę) robiłem komunikację przy podpiętym stale programatorze i było wszystko ok - uC odsyłał echo.
  • #17 6331353
    lstaszew
    Poziom 12  
    hmm.. skladalem to według schematu znajdującego się na stronie
    http://www.fischl.de/usbasp/
    Nie mam pojęcia czemu te piny są wyprowadzone do złącza programatora skoro tak naprawdę nie są one nawet używane.
REKLAMA