Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

AVR Język C Avr Studio Avr gcc- podstawy dla początkujących

wojtekr 13 Apr 2007 18:58 57595 25
  • #1
    wojtekr
    Level 15  
    Witam,
    po czwartym dniu studiowania forum, googli itp. Doszedłem do wniosku, że jak założę nowy temat to ktoś się ulituje i nie pisząc o lenistwie, wyszukiwarkach itp odpowie na parę pytań.

    Do tej pory pisałem w bascomie, ze względu na koszty postanowiłem sie przesiąść na C- i tu zaczął się jakiś koszmar. Przyzwyczajony do bascomowej składni zetknąłem się z jakaś koszmarną składnia C nie mówiąc o asm.

    Przeszukując internet znalazłem jakieś przykłady kodu w C, nawet się kompilują i wgrywają do uC za pomocą Bascomu Demo.
    Ale nie mogę nigdzie znaleźć podstaw C dla AVR- z resztą jak widziałem to nie tylko ja.
    Mam nadzieje, że jak pomożecie zrozumieć kod C dla LCD to jakoś to będzie.
    Pierwszy program ma wyświetlić cokolwiek na LCD

    W bascomie to było jasne:
    Code:

    Config Lcd = 16 * 1a
    Config Lcdpin = Pin , Db4 = Portd.6 , Db5 = Portd.4 , Db6 = Portd.3 , Db7 = Portd.2 , Rs = Portb.0 , E = Portd.7

    lcd "Cos tam"
    lowerline
    lcd "znowu cos"
    upperline

    tu następowała definicja wyprowadzeń uC do LCD i wyświetlenie tekstu.

    Natomiast C (sorry, że taki długi ale nie wiem co jest a co nie jest związane z LCD):

    Code:
    /***************************************************************/
    
    /* Ćwiczenie 4b - sterowanie alfanumerycznym wyświetlaczem LCD */
    /*                16x1 (16 znaków, 1 wiersz)                   */
    /*              - obsługa pojedynczego klawisza                */
    /* J.D. '2003                                                  */
    /***************************************************************/
    #include <io.h>
    #include <progmem.h>

    #define lcd_rs 2
    #define lcd_e 3
    #define CR 0x0a

    volatile unsigned char kolumna;

    void czekaj(unsigned long pt) //procedura wytracania czasu
    {
    #define tau 10.38             //przybliżony przelicznik argumentu na ms
     unsigned char tp1;

     for(;pt>0;pt--)
     {
      for(tp1=255;tp1!=0;tp1--);
     }
    }

    void piszilcd(unsigned char instr) //zapisz instrukcję sterującą do LCD
    {
     cbi(PORTB,lcd_rs);
     sbi(PORTB,lcd_e);
     PORTB=(PORTB&0x0f)|(instr&0xf0);  //przygotuj starszy półbajt do LCD
     asm("nop");                       //wymagane wydłużenie impulsu
     asm("nop");
     asm("nop");
     cbi(PORTB,lcd_e);                 //impuls strobujący
     czekaj(10L);                      //czekaj na gotowość LCD ok. 100us
     sbi(PORTB,lcd_e);
     PORTB=(PORTB&0x0f)|((instr&0x0f)<<4);  //przygotuj młodszy półbajt do LCD
     asm("nop");
     asm("nop");
     asm("nop");
     cbi(PORTB,lcd_e);                 //impuls strobujący
     czekaj(10L);                      //czekaj na gotowość LCD ok. 100us
    }



    void piszdlcd(char dana)           //zapisz daną do LCD
    {
     sbi(PORTB,lcd_rs);
     sbi(PORTB,lcd_e);
     PORTB=(PORTB&0x0f)|(dana&0xf0);   //przygotuj starszy półbajt do LCD
     asm("nop");                       //wymagane wydłużenie impulsu
     asm("nop");
     asm("nop");
     cbi(PORTB,lcd_e);                 //impuls strobujący
     czekaj(10L);                      //czekaj na gotowość LCD
     sbi(PORTB,lcd_e);
     PORTB=(PORTB&0x0f)|((dana&0x0f)<<4); //przygotuj młodszy półbajt do LCD
     asm("nop");
     asm("nop");
     asm("nop");
     cbi(PORTB,lcd_e);                 //impuls strobujący
     czekaj(10L);                      //czekaj na gotowość LCD
    }

    void czysclcd(void)                //czyść ekran
    {
     piszilcd(0x01);      //polecenie czyszczenia ekranu dla kontrolera LCD
     czekaj(1.64*tau);    //rozkaz 0x01 wykonuje się 1.64ms
     kolumna=0;
    }

    void piszznak(char znak)    //procedura umieszcza znak na wyświetlaczu
    {
     unsigned char p;
     if(kolumna<8)
     {
      p=kolumna;
     }
     else
     {
      p=kolumna+56;       //dodatkowe przesunięcie współrzędnych dla LCD 1x16
                          //dla drugiej połówki wyświetlacza
     }
     piszilcd(p|0x80);
     kolumna=kolumna!=15?++kolumna:0;  //ustaw następną kolumnę
     piszdlcd(znak);                   //wyświetl znak na LCD
    }

    void lcdy(unsigned char k)  //ustaw współrzędne kursora
    {
     if(k<8)
     {
      piszilcd(k|0x80);         //standardowy rozkaz sterownika LCD
                                //ustawiający kursor w określonych współrzędnych
     }
     else
     {
       piszilcd((k+56)|0x80);   //dodatkowe przesunięcie współrzędnych dla LCD 1x16
     }
     kolumna=k;
    }

    void pisztekst(char *tekst)  //pisz tekst na LCD wskazywany pointerem *tekst
    {
     char nr=0;
     char zn;

     while(1)
     {
      zn=PRG_RDB(&tekst[nr++]);  //pobranie znaku z pamięci programu
      if(zn!=0)                  //czy nie ma końca tekstu?
      {
       if(zn==CR)                //czy znak nowej linii
       {
        kolumna=0;       //jeśli tak, ustaw obowiązujące po zmianie współrzędne na LCD
       }
       else
       {
        piszznak(zn);            //umieść pojedynczy znak tekstu na LCD
       }
      }
      else
      {
       break;                    //zakończ pętlę, jeśli koniec tekstu
      }
     }
    }

    void klawisz(unsigned char pozkl)  //czekaj na naciśnięcie określonego klawisza
                                       //klawisz jest wybierany poprzez argument pozkl
    {
     while((PIND&pozkl)==pozkl);       //czekaj na naciśnięcie klawisza
     czekaj(30*tau);                   //odczekaj aż ustaną zakłócenia
     while((PIND&pozkl)!=pozkl);       //czekaj na zwolnienie klawisza
    }

    int main(void) //program główny
    {
     unsigned char i;

     //>>>>>>>>>>>>>    definicje tekstów wyświetlanych na LCD   <<<<<<<<<<<<<<
     char *tekst1=PSTR("Wyswietlacz 1x16");
     char *tekst2=PSTR("Hello World!");


    Czy może ktoś napisać gdzie w tym kodzie jest odpowiednik:

    config lcd ..
    (chodzi mi o możliwość dowolnego skonfigurowania portów lcd db4-7, RS,E)
    lcd ...
    (chodzi mi o logikę wyświetlania danych- czy to jest wysyłany cały wyraz, czy operujemy poszczególnymi polami o konkretnych współrzędnych, czy wysyłamy jakieś dane bin jak w VFD)

    Bardzo proszę, że by wpisy były naprawdę jasne dla początkujących bez elokwencji wszystkowiedzących. Ja postaram się bardziej precyzyjnie opisać problem jeżeli będzie taka potrzeba.

    Kolejnym poważnym problemem jest interpretacja kompilatora AVR-GCC ale to może następnym razem.

    Mam nadzieje, że uda się nam stworzyć coś co innym początkującym pomoże rozwiązywać "banalne" i oczywiste problemy.
    dzięki
    wojtekr
  • #2
    kris_gor
    Level 16  
    wojtekr wrote:
    Witam,

    Przeszukując internet znalazłem jakieś przykłady kodu w C, nawet się kompilują i wgrywają do uC za pomocą Bascomu Demo.
    Ale nie mogę nigdzie znaleźć podstaw C dla AVR- z resztą jak widziałem to nie tylko ja.

    Nie ma czegoś takiego jak C dla AVR.



    Mam nadzieje, że jak pomożecie zrozumieć kod C dla LCD to jakoś to będzie.
    Pierwszy program ma wyświetlić cokolwiek na LCD

    W bascomie to było jasne:
    Code:

    Config Lcd = 16 * 1a
    Config Lcdpin = Pin , Db4 = Portd.6 , Db5 = Portd.4 , Db6 = Portd.3 , Db7 = Portd.2 , Rs = Portb.0 , E = Portd.7

    lcd "Cos tam"
    lowerline
    lcd "znowu cos"
    upperline

    tu następowała definicja wyprowadzeń uC do LCD i wyświetlenie tekstu.

    Natomiast C (sorry, że taki długi ale nie wiem co jest a co nie jest związane z LCD):

    Tutaj wszystko jest związane z LCD ;-)



    wojtekr


    Czy może ktoś napisać gdzie w tym kodzie jest odpowiednik:

    Quote:
    config lcd ..
    (chodzi mi o możliwość dowolnego skonfigurowania portów lcd db4-7, RS,E) lcd ...


    Muszę Cię rozczarować ;-) Masz nawyki z bascoma niestety. Tutaj sobie musisz sam napisać wszystkie procedury łącznie z konfiguracją.



    Quote:
    (chodzi mi o logikę wyświetlania danych- czy to jest wysyłany cały wyraz, czy operujemy poszczególnymi polami o konkretnych współrzędnych, czy wysyłamy jakieś dane bin jak w VFD)


    Nie przeczytałeś uważnie opisu do źródeł, które sam zamieściłeś. Masz tam procedury, które odpowiadają za wysłanie słowa sterującego do wyświetlacza, znaku jak i stringu. Aby napisać coś takiego w C musisz wiedzieć jak działa wyświetlacz i jak się go steruje, a z treści listu wynika, że tego nie wiesz.


    Quote:
    Bardzo proszę, że by wpisy były naprawdę jasne dla początkujących bez elokwencji wszystkowiedzących. Ja postaram się bardziej precyzyjnie opisać problem jeżeli będzie taka potrzeba.


    Nie ma sprawy.

    Te źródła, które zamieściłeś są dobre, ale składnia jest już przestarzała (2003 rok). Makr sbi(), cbi() już się nie używa w nowych programach.
  • #3
    ciastek4
    Level 14  
    Jeżeli szukasz jakiejś pomocy to odsyłam do kursu który był w Elektronice dla Wszystkich. Pierwszy nr zaczął się w maju 2005r. Wystarczy iść do pierwszej lepszej biblioteki i dostaniesz te egzemplarze. Później ładne oczko do Pani która sprawuje piecze nad swym księgozbiorem by pozwoliła zrobić ksero:) i kurs jest w twoich rękach..

    Programując w BASCOM nie masz dobrej kontroli nad uC. Polecam C.
  • #4
    wojtekr
    Level 15  
    Sknerstwo nie jest jedynym powodem zmiany na C. Wariactwa Bascoma dały mi się ostatnio we znaki i stąd ta decyzja.

    Reasumując temat jest sbyt obszerny żeby go wyjaśnić nowicjuszom na łamach forum. Trzeba zapozanć się z kursem EP. Jest to jedna z bardziej konkretnych odpowiedzi jakie znalazłem. Mam nadzieje, że nowicjusz za pomocą kursu da radę.

    Dzięki.
  • #5
    trol.six
    Level 31  
    Nie ma coś takiego jak podstawy C dla avr. C jest C.

    I najpierw warto zapoznać sie z tym jezykiem. Tu jest jakis link jak kumasz cos po angielsku:
    http://lib.daemon.am/Books/C/

    Jak nie kumasz to musisz szukać jakis innych kursów, albo ksążek

    Jak juz bedziesz wiedział o co chodzi w C, choć przyznam że ja zaczynałem od asemblera, bo warto wiedzieć co sie tam w procku dzieje, to już można przeczytac np opis avr-gcc.

    Porty traktuje sie jak inne zmienne w C. I dlatego ustawia sie je tak jak inne zmienne. Definicje w C określonych pinów i portów, można definiowac dyrektywa
    #define

    I w zasadzie tyle.

    Tego nie da sie w 5 minut wyjaśnić, Musisz po prostu to przeczytać i zrozumieć. To jest inny styl pisania ze zwględu na to że jest bardziej niskopoziomowy od bascoma. No wszystko jest inne. Asm jest jeszcze inny ze względu że korzystasz bezpośrednio z rozkazów procesora. Dobrze znać tutaj na jakich liczbach operacje są wykonywane, jaka jest ich reprezentacja w zapisie.

    Bascoma nie znam, wiec w tej materii róznic, raczej nic nie pomoge.

    dodane:
    No ważna rzecz, typy. W zależnosci od procesora typy, czyli zakresy wielkości liczb mogą być rózne. Stąd inny zakres ma int na avr a inny na i686 (czyli procesory na PC).
  • #6
    JacekCz
    Level 39  
    nie wyobrażam sobie pierwszego kontaktu z C na uK.
    Tylko desktop. Są darmowe Express od MS, jest dev-cpp. Język jest trudny i niebezpieczny.

    I ostrzeżenie (z uporem maniaka), że wiele jest podłych kursów C, kiepskich antydydaktycznych wzorów
  • #7
    gufiak
    Level 21  
    Quote:
    Przyzwyczajony do bascomowej składni zetknąłem się z jakaś koszmarną składnia C nie mówiąc o asm.
    Wcale składnia C nie jest koszmarna. Wbrew pozorom, to właśnie składnia bascoma jest koszmarna. C jest stosunkowo łatwym językiem do czytania programów. A jedyny plus bascoma to prostota. Wpisujesz instrukcję a on już wszystko robi za Ciebie. C to już niestety wyższy poziom, ale ma niepodważalne zalety wobec bascoma: większa kontrola nad uC, duuużo optymalniejszy kod, no i kompilatory C raczej są mniej zabugowane niż bascom.

    A na początek przede wszystkim naucz się podstawowej składni C. No i skup się na wskaźnikach. W uC często się przydają, a ich zrozumienie pomoże Ci w pisaniu dobrych i optymalnych programów. Wiele ludzi zabiera się za pisanie w C nie mając zielonego pojęcia o wskaźnikach i w rezultacie napisanie prostego programu jest dla nich dużym problemem.
  • #8
    Romantello
    Level 14  
    Tu masz jedną z lepszych stron opisujących składnię języka C i to w naszym języku :) - bardzo przejrzyste opisy:
    http://adambyw.fm.interia.pl/

    Jest tam również do pobrania wersja off-line!
  • #9
    JacekCz
    Level 39  
    gufiak wrote:
    Quote:
    Przyzwyczajony do bascomowej składni zetknąłem się z jakaś koszmarną składnia C nie mówiąc o asm.
    Wcale składnia C nie jest koszmarna. Wbrew pozorom, to właśnie składnia bascoma jest koszmarna.

    Racja.
    Gdzieś czytałem o regule 7. Nie więcej niż 7 wariantów w rozgałęzieniu, nie więcej niż 7 pól w strukturze. Nie więcej niż 7 kontrukcji języka.
    (Zdradzam sekret: jak wychodzi więcej niż 7, powołać nowy 'poziom'). Oczywiście piszę do ludzi inteligentnych i wiemy, że liczba 7 to trochę w przybliżeniu.

    C spełnia ten wymóg. Tu odrózniamy język (konstrukcji jest ok.7) i wymienne bilioteki (co Bascom zlewa w jedno czyniąc niedydaktyczny chaos). Język jest klarowny (ale patrz niżej)

    gufiak wrote:

    A na początek przede wszystkim naucz się podstawowej składni C. No i skup się na wskaźnikach. W uC często się przydają, a ich zrozumienie pomoże Ci w pisaniu dobrych i optymalnych programów. Wiele ludzi zabiera się za pisanie w C nie mając zielonego pojęcia o wskaźnikach i w rezultacie napisanie prostego programu jest dla nich dużym problemem.


    Jest też (bardzo) wielu takich, którzy dobrze sobie pokaleczyli paluchy wskaźnikami. Wskaźnik, unia, inicjowanie, zarządzanie pamięcią, define. Są pewne elementy C (masz rację - mocne) ale bardzo ryzykowne. Ślicznie (i słusznie) punktują to np twórcy javy.
  • #10
    wojtekr
    Level 15  
    Znajdując jakieś przykłady kodu C często mam problem z plikami .h. Domyślam się, że skoro ich nie mam to powinny być dołączone z kodem, że są autorstwa twórcy kodu?
    Np: progmem.h, uart.h

    A wracając do przykładu może mi ktoś pokazać gdzie jest zawarta informacją na temat podłączenia poszczególnych wyprowadzeń portów do DB4-7 LCD?

    Oraz czy nie ma prostej odpowiedzi na pytanie jak sterowany jest LCD?
    Czy może ktoś opisać te linie:
    Code:

    cbi(PORTB,lcd_rs);
     sbi(PORTB,lcd_e);
     PORTB=(PORTB&0x0f)|(instr&0xf0);

    dzięki
  • #12
    User removed account
    User removed account  
  • #13
    farmazon3000
    Level 15  
    no ja nie polecam tej ksiazki jesli nigdy nie miales stycznosci z C, niestety...

    ta ksiazka nie jest nawet dla kogos kto umie C no poziomie srednim

    wiem bo mam te ksiazke, a jestem po 2 semestrach kursu jezyka C

    no i musze powiedziec ze jezyk C dla mikroprocesorow rozni sie jednak od tego ktorego uzywa sie na PC, nie w tym sensie ze uzywa sie jakiejs innej skladni, tylko dlatego, ze nigdy nie uzywa sie operacji bitowych na PC bo nie ma takiej potrzeby, a nie wiem czy i mozliwoasci

    natomiast na uP uzywa sie oprocz zwyklych instrukcji jak na PC, takze operacji na bitach i jest to dosc specyficznie uzycie

    musze powiedziec ze nie ma jakiejs dobrej ksiazki ktora nauczy cie programowac uP w C

    natomiast jest duzo ksiazek ktore naucza cie programowac w C tak w ogole
  • #14
    zumek
    Level 39  
    farmazon3000 wrote:
    ...no i musze powiedziec ze jezyk C dla mikroprocesorow rozni sie jednak od tego ktorego uzywa sie na PC, nie w tym sensie ze uzywa sie jakiejs innej skladni, tylko dlatego, ze nigdy nie uzywa sie operacji bitowych na PC bo nie ma takiej potrzeby, a nie wiem czy i mozliwoasci ...

    Co Ty tu za herezje wypisujesz :?: ;) To w C na PC nie nie ma(nie używa się) takich operatorów & , | , ^ ,.. :?:

    Piotrek
  • #15
    farmazon3000
    Level 15  
    nie chcialbym byc zle zrozumiany: nie napisalem przeciez ze czyms sie ten jezyk rozni jak tylko uzyciem, no bo nie zgodzisz sie ze mna ze programowanie PC rozni sie od prograowania uP?

    i dodam jeszcze ze nie spotkalem sie w programowaniu Pc operacji logicznych na bitach, tylko na typie int, co w C jest wielkim ulatwieniem

    nie ma o co sie czepiac o pierdoly
  • #16
    adamusx
    Level 27  
    W microsofcie pewnie tez wszystko robią na INTach i potem windows zajmuje tyle ile zajmuje :D
  • #17
    Bigfoot
    Level 25  
    Kolega Farmazon opowiada farmazony...

    :)
  • #18
    zwora
    Level 18  
    Witam

    Dolacze sie do tego tematu, bo wspomniane bylo o ksiazce "Mikrokontrolery AVR programowanie w jezyku C". Czy ktos z Was robil przyklady z tej ksiazki. Chodzi mi konkretnie o ten z obsluga lcd. Autor stworzyl dosc sensowna i jak twierdzi optymalna pod wzgledem zajetosci pamieci przez kod wynikowy (w co akurat wierze) biblioteke do obslugi wyswietlacza LCD. Problem w tym, ze jest tam pare bledow. Np w pliku lcd_write.c we wstawce assemblerowej funkcji short_delay(cnt) uzywa operandu wejsciowego ograniczajacego zakres zmiennej od 0 do 255, a nastepnie w tym samym pliku wywoluje te funkcje z wartoscia spoza tego zakresu. Ale to jakos szybko wykrylem. Natomiast mam problem z tworem two_byte_union (uzyty jako typ zmiennej w deklaracji). Nigdzie nic takiego nie moge znalezc. Wpisanie tego w google nie zwraca mi zadnych wynikow? Pozdrawiam
  • #19
    cyjan
    Level 12  
    zwora wrote:
    (...) Natomiast mam problem z tworem two_byte_union (uzyty jako typ zmiennej w deklaracji). Nigdzie nic takiego nie moge znalezc. Wpisanie tego w google nie zwraca mi zadnych wynikow? Pozdrawiam

    Witam!
    Na googlach nie znajdziesz bo to wytwór autora :)))
    two_byte_union to unia zdefiniowana wcześniej (w książce znalazłem ją w rozdziale obsługi klawiatury matrycowej (str 120):
    Code:
    typedef union
    
    {
    uint16_t word;
    uint8_t byte[2];
    }two_byte_union;

    A po co to robi opisane jest ciutkę dalej - zwięzłość kodu maszynowego (kosztem czytelności programu).
    Pozdrawiam, Zenek
  • #20
    tzok
    Moderator of Cars
    Trochę zaofftopikuję: kod w C a zwłaszcza w C++, którego zazwyczaj używa się na PC, jest zupełnie inny niż niż kod dla uC, zwłaszcza, jeśli autor kodu na PC nigdy nie posługiwał się Assemblerem. Na PC są gotowe wygodne polecenia do operowania na plikach, obsługi konsoli (ekran, klawiatura), nie trzeba się też martwić o każdy bajt pamięci. Ponadto w uC a zwłaszcza o architekturze RISC (jak np. AVR) często "polega się" na szybkości procesora - czyli np. do pomiaru czasu można inkrementować w pętli jakąś zmienną, do wstawienia opóźnienia wykonać kilkaset przebiegów pustej pętli.
  • #21
    zwora
    Level 18  
    Dzieki Cyjan. Ze tez tego nie sprawdzilem :-)
  • #22
    User removed account
    User removed account  
  • #23
    shadow0013
    Level 34  
    Kiedyś znalezione w internecie artykuły z EDW "Programowanie procesorów w języku C" (przesiadka na C) pierwszy z maja 2005r. + materiały do kursu dostępne na stronie EdW:
  • #24
    Heniug
    Level 2  
    Witam!
    Czy ma ktoś dostęp do kursu asm w avr studio.
  • #25
    AsKeR
    Level 10  
    A czy mógłby ktoś mi pokazać jakiś program który po prostu wyświetli jakiś prosty napis na wyświetlaczu LCD? Coś jak ten powyżej ale bez klawisza.