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

[Atmega162][C] migająca LED

deviland 30 Sie 2008 14:05 3760 20
REKLAMA
  • #1 5490118
    deviland
    Poziom 10  
    Witam!

    Docelowo musze stworzyc program do transmisji szeregowej wykorzystujacy 2 USARTy. Stad moj wybor padl na Atmega162.

    Poniewaz bedzie to transmisja z predkoscia 9600b/s na zaprojektowanej plytce znalazl sie kwarc 7,3728MHz.

    Poniewaz dopiero zaczynam z uC pierwszym programem jaki wgralem aby sprawdzic czy wszystko dziala byl znaleziony na http://www.avrtutor.com/tutorial/thermo/led.php

    
    
    #include <avr/io.h>    // header file
    
    int main(void)         // program starts here
    {
        DDRB = 255;        // set port B for output
        PORTB = 0;         // set port B pins to 0
    
        return (0);        // return something
    }
    
    


    Po skompilowaniu i wgraniu do atmegi pelnia szczescia, dioda swieci.

    Nastepny krok : migajaca dioda ...

    Probowalem dwa kody:

    
    #include <avr/io.h>
    #include <util/delay.h>               
    
    int main(void)
    {
        DDRD  |= _BV(1);               
        PORTD &= ~_BV(1);                   
        unsigned char i;
        for (;;)
        {
          PORTD ^=_BV(1);           
              for (i = 0; i <100; i++)
                          _delay_ms(10);           
        }
        return 0;
    }
    


    oraz

    
    #include <avr/io.h>
    
    /// Typedefs //////////
    typedef unsigned char u8;
    typedef unsigned int u16;
    typedef unsigned long u32;
    
    /// Defines ///////////
    #define forever         117
    #define LEDOFF          PORTB |= (1<<4)
    #define LEDON           PORTB &= ~(1<<4)
    
    /// Prototypes ////////
    void InitPorts (void);
    void Delay (u32 count);
    
    int main(void)
    {
        InitPorts();
    
        while (forever)
        {
            LEDON; Delay(20000);
            LEDOFF; Delay(20000);
        }
    }
    
    void InitPorts(void)
    {
        DDRB |= 1<<DDB4;
    }
    
    void Delay(u32 count)
    {
        while(count--);
    }
    


    pierwszy z dioda.com.pl, drugi z avrtutor.com obydwa nie dzialaja.

    Bity konfiguracyjne ustawilem nastepujaco:

    [Atmega162][C] migająca LED

    programowane przy pomocy ISPProg.

    Postepujac zgodnie z instrukcja http://www.dioda.com.pl/forum/topics20/szybki-start-z-winavr-vt513.htm

    utworzylem plik makefile zmieniajac na odpowiednie:

    nazwe, typ atmegi, F_CPU oraz rodzaj programatora (uzywam STK200)

    Utworzony plik .hex laduje do atmegi ponyprogiem. Niestety program nie dziala, dioda nie swieci wcale nie mowiac o miganiu. Dodam ze atmega jest ok, po wgraniu ponownie pierwszego prostego programu zapalajacego diode jest ok.

    Zakladam ze kody sa poprawne a problem tkwi w ustawieniu bitow konfiguracyjnych i ewentualnie pliku makefile.

    Prosze o wypowiedz co robie nie tak?

    pozdrawiam,
    deviland
  • REKLAMA
  • #2 5490132
    nocoment
    Poziom 11  
    dodaj Wacpan jeszcze, ze diode przepinales na odpowiednie porty, drugi kod jest na port D, a pierwszy i ostatni na port B :)
  • #3 5490190
    deviland
    Poziom 10  
    Tak oczywiscie dioda byla podpieta zawsz do odpowiedniego portu
  • REKLAMA
  • #4 5490204
    acid12
    Poziom 21  
    nie tylko porty sie różnią ale też końcówki, może tu tkwi problem jak dioda była zawsze do tego samego pinu podłączona

    1) cały PortB
    2) PD.1
    3) PB.4

    EDIT:
    skoro działa pierwszy program (swoją drogą nie powinien bo nie ma tam nigdzie pętli :\ ) spr coś takiego

    #include <avr/io.h>
    #include <util/delay.h>               
    
     int main(void)
    {
        DDRB  = 0xFF;               
        PORTB = 0x00;    
                   
        while(1){
    
        _delay_ms(100);
        PORTB = 0xFF;
    
       _delay_ms(100);
        PORTB = 0x00;
    
    }
        return 0;
    } 


    może coś z lutowaniem jest nie tak, ten program zmienia wyjścia całego portuB na 0 -> 1 -> 0 -> ...
  • #5 5490432
    deviland
    Poziom 10  
    @acid12 dzieki wielkie :) dziala twoj program. Dobra nowina dla mnie - plytka polutowana dobrze i bity fuse w takim razie chyba ok. Teraz sproboje cos wyslac po RS232 :)

    pozdrawiam,
    deviland
  • #6 5490483
    acid12
    Poziom 21  
    musiał działać, zgaduje że dioda do złych pinów była podpięta.

    co do obsługi UARTA, zgaduje że pewnie skorzystasz z jakiś gotowych rozwiązań, ja wykorzystuje bibliotekę Petera Fleury, zresztą do sterowania lcd też wykorzystuje jego bibliotekę.
    http://homepage.hispeed.ch/peterfleury/avr-uart.html

    w AVRlib też jest biblioteka obsługi uarta, no i zawsze możesz napisać sam obsługę jak chcesz mieć pełną kontrole, ale do testów, przynajmniej według mnie, lepiej wykorzystać coś co na pewno działa :]
  • #7 5491810
    bobbyAIR
    Poziom 20  
    acid12 napisał:
    skoro działa pierwszy program (swoją drogą nie powinien bo nie ma tam nigdzie pętli :\ )

    Czemu nie powinien. Startuje, ustawia porty jako wyjścia, zapala diodę i staje dęba (sic!). Ale to co autor chciał robi - zapala diodę :D
  • #8 5491913
    acid12
    Poziom 21  
    całe szczęście że avrki mają zabezpieczenia ;) inaczej na pewno nie stanąłby dęba tylko gnał dalej po flashu zapalając pseudo randomowo diodki :P
  • REKLAMA
  • #9 5503341
    deviland
    Poziom 10  
    Witam ponownie!

    Czytajac pdf'a Atmegi162 stworzylem taki kod odbierajacy znaki z portu szeregowego PC i wysylajacy je z powrotem (echo) do PC. Program dziala bez zarzutu:

    
    #include <avr/io.h>
     
    
    #define USART_BAUDRATE 9600
    #define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
    
    int main (void)
    {
       char ReceivedByte;
    
       UCSR1B |= (1 << RXEN1) | (1 << TXEN1);   // Załącz TX1 i RX1
       UCSR1C |= (1 << URSEL1) | (1 << UCSZ10) | (1 << UCSZ11); // 8 bitów danych, transmisja asynchroniczna
    
       UBRR1L = BAUD_PRESCALE; // Ładuje młodsze 8 bitów wartości rejestru UBRR1 
       UBRR1H = (BAUD_PRESCALE >>8 ) ; // Ładuje starsze 8 bitów wartości rejestru UBRR1
    
       for (;;) // Pętla
       {
          while (!(UCSR1A & (1 << RXC1))); // Odbiór danych z PC
          {
          ReceivedByte = UDR1; // 
           }
    
          while (!(UCSR1A & (1 << UDRE1))); // Wysyłanie danych do PC
          {
          UDR1 = ReceivedByte;
          }
       }   
    } 
    


    Jak juz pisalem wczesniej docelowo zamierzam dojsc do programu wykorzystujacego 2 USARTY i konwertujacego transmisje asynchroniczna na synchroniczna, ale narazie cos prostszego:

    ustawiam oba USARTY w tryb asynchroniczny i RXD1 odbiera dane z PC i wysyla do RXD0 nastepnie echo na USART0 i dane wracaja do PC poprzez TXD1 ...

    kod wyglada tak:

    
    #include <avr/io.h>
    
    
    #define USART_BAUDRATE 9600
    #define BAUD_PRESCALE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
    
    int main (void)
    {
       char ReceivedByte;
       char ReceivedByte2;
    
       UCSR1B |= (1 << RXEN1) | (1 << TXEN1);   					// Załącz TX1 i RX1
       UCSR1C |= (1 << URSEL1) | (1 << UCSZ10) | (1 << UCSZ11); 	// 8 bitów danych, transmisja asynchroniczna
    
       UBRR1L = BAUD_PRESCALE; 			// Ładuje młodsze 8 bitów wartości rejestru UBRR1
       UBRR1H = (BAUD_PRESCALE >>8 ) ; // Ładuje starsze 8 bitów rejestru UBRR1
    
    
       UCSR0B |= (1 << RXEN0) | (1 << TXEN0);   					// Załącz TX0 i RX0
       UCSR0C |= (1 << URSEL0) | (1 << UCSZ00) | (1 << UCSZ01); 	// 8 bitów danych, transmisja asynchroniczna
    
       UBRR0L = BAUD_PRESCALE; 			// Ładuje młodsze 8 bitów wartości rejestru UBRR0
       UBRR0H = (BAUD_PRESCALE >>8 ) ; // Ładuje starsze 8 bitów rejestru UBRR0
       
       
       for (;;) // pętla
       {
          while (!(UCSR1A & (1 << RXC1))) ;	// Odbiór danych z PC
    	  {
          ReceivedByte = UDR1 ; 				// Ładuje zawartość UDR1 do zmiennej ReceivedByte
    	  }
    	  
          
    	  while (!(UCSR1A & (1 << UDRE1))) ;	// Przepisuje zawartość zmiennej ReceivedByte do UDR0
    	  {
          UDR0 = ReceivedByte ; 
    	  }
    	  
    	  while (!(UCSR0A & (1 << RXC0))) ;	// Ładuje zawartość UDR0 do zmiennej ReceivedByte2
    	  {
          ReceivedByte2 = UDR0 ; 
    	  }
    	  
    	  while (!(UCSR0A & (1 << UDRE0))) ;	// Wysłanie danych do PC
    	  {
          UDR1 = ReceivedByte2 ; 
    	  }
    	  
    	  
       }   
    }  
    


    kompiluje sie poprawnie, ale niestety po wgraniu do m162 i wyslaniu znaku z terminala PC nie odbiera go z powrotem.
  • #10 5503407
    rrata
    Poziom 19  
    Spróbuj zrobić odbieranie w przerwaniu. Albo pomiędzy pętle wstaw jakiś delay, żeby urządzenie końcowe miało czas na odpowiedź.

    PS. Wywal te klamry zaraz za pętlami, bo na pierwszy rzut oka wygląda to tak że polecenia np. UDR1=ReceivedByte wykonują się w pętli, a one wykonują się tylko raz.
  • #11 6743904
    rzepcio1987
    Poziom 11  
    Podepnę się pod ten temat...
    Mam diody podpięte w następujący sposób:
    [Atmega162][C] migająca LED
    Napisałem taki program:
    #include <avr/io.h>
    #include <util/delay.h>
    
     int main(void)
    {
        DDRC  = 0xFF;
    	DDRA  = 0xFF;
        PORTC = 0x00;
    	PORTA = 0X00;
    
        while(1)
    	{
    		_delay_ms(100);
    		PORTC = 0xFF;
    		PORTA = 0xFF;
    
    		_delay_ms(100);
    		PORTC = 0x00;
    		PORTA = 0X00;
    	}
        return 0;
    }


    Makefile zrobiłem według tego tutorialu: http://www.dioda.com.pl/forum/topics20/szybki-start-z-winavr-vt513.htm

    I niestety nie działa :P Problem jest od strony uC na pewno, bo jak sobie zrobię połączenie między diodą, a masą, to się zaświeca...

    Dodano po 2 [godziny] 25 [minuty]:

    Łaa :P Udało mi się mrugnąć 6 diodami podpiętymi pod port A... Ale to wszystko co się stało, a ten program powinien się pętlić przecież... Nie mówiąc o tym, że powinny też diody z portu C mrugać...:|

    Dodano po 2 [godziny] 1 [minuty]:

    Diody z PORTC także raz mrugają, problemem był włączony JTAG. Ale nadal nie wiem, dlaczego tylko mrugają, przecież powinny świecić! :(
    #include <avr/io.h>
    #include <util/delay.h>
    
    int main(void)
    {
        DDRC = 0xFF;
    	DDRA = 0xFF;
        PORTC = 0xFF;
    	PORTA = 0XFF;
        unsigned char i;
        while (1)
        {
    		PORTC = 0x00;
    		PORTA = 0x00;
        }
        return 0;
    }
  • REKLAMA
  • #12 6746134
    Brutus_gsm
    Poziom 25  
    rzepcio1987. Przy którym kodzie mrugają? Przy pierwszym na pewno, bo tak został napisany. Przy drugim możesz wyrzucić z pętli wszystkie polecenia a wstawić je przed nią. Pętlę zostaw pustą.
  • #13 6746149
    rzepcio1987
    Poziom 11  
    Tu nie chodzi o to, że mrugają, ale że jest pojedyncze mrugnięcie i nic więcej, tuż po włączeniu zasilania.
  • #14 6746174
    Brutus_gsm
    Poziom 25  
    Zrób tak
    
    #include <avr/io.h>
    #include <util/delay.h>
    
    int main(void)
    {
       DDRC = 0xFF;
       DDRA = 0xFF;
       PORTC = 0x00;
       PORTA = 0x00;
       while (1) {}
    
        return 0;
    }
    I pokaż jak masz ustawione fusebity.
  • #15 6746263
    rzepcio1987
    Poziom 11  
    Mam zewnętrzny kwarc 12MHz, więc fusy mam większość na 1:
    CKSEL = 1111
    SUT = 11
    Oprócz tego wyłączony dzielnik i wyłączony JTAG, bo nachodzi na PORTC. Ale próbowałem też na defaultowych z wewnętrznym 1MHz.

    Aktualnie testuje na tym:
    #define F_CPU 12000000L 
    #include <avr/io.h> 
    #include <util/delay.h> 
    
    int main(void) 
    { 
    	DDRA  = 0xff; 
    	PORTA = 0x7f;
        while(1){} 
    }


    Tylko jedna dioda, wydaje się, że nie powinno być jakichś gwałtownych przeskoków napięcia, a nic z tego, ona też tylko mignie i koniec :|
  • #16 6746282
    Brutus_gsm
    Poziom 25  
    Sprawdź, czy nie masz włączonego watchdog'a.
  • #17 6746571
    rzepcio1987
    Poziom 11  
    Jedyne włączone fusy to isp i boot size, brown out też nieaktywne:
    [Atmega162][C] migająca LED
  • #18 6746742
    Brutus_gsm
    Poziom 25  
    Może zmień źródło zasilania i sprawdź ;) Miałem podobny problem przy sterowaniu wyświetlaczem LED i za nic nie moglem dojść jaki jest problem, a problem był po stronie zasilania. A i podciągnij reset do VCC za pomocą rezystora 1k.
  • #19 6746795
    rzepcio1987
    Poziom 11  
    Jeśli chodzi o źródło zasilania, to próbowałem moje z układu (bateria 9V -> stabilizator z 9 na 5V) oraz przez usbasp z usb i na obu jest tak samo, spróbuje jeszcze podciągnąć ten reset jak piszesz.

    Dodano po 21 [minuty]:

    Jeszcze się tylko zapytam, czy ten reset, który mam jest dobry:

    [Atmega162][C] migająca LED

    Bo widziałem raczej odwrotne rozwiązania (napięcie - opornik - kondensator - masa), niż to, które mam. Zaczerpnąłem je z układu podobnego do tego, który realizuję ;)

    Dodano po 2 [minuty]:

    np. takie z projektu kolegi:
    [Atmega162][C] migająca LED
  • #20 6746986
    Brutus_gsm
    Poziom 25  
    Wystarczy sam rezystor do VCC. Kondensator pomiń.
  • #21 6746994
    rzepcio1987
    Poziom 11  
    :please:

    No i sprawa rozwiązana :D Tak to jest jak się bierze rozwiązania z innych projektów ;/ Podpiąłem sam rezystor i śmiga! :D
    :spoko:

    Dzięki za pomoc, naprowadziłeś mnie na ten reset :)
REKLAMA