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

[Atmega16]LCD - w Bascomie działa, a w C już nie.

Darektbg 17 Paź 2009 15:08 1848 5
REKLAMA
  • #1 7139679
    Darektbg
    Poziom 21  
    
    
    $regfile = "M16def.dat"
    $crystal = 16000000
    Config Portb = &B11111111 : Portb = &B11111111
    Config Portd = &B11111111 : Portd = &B11111111
    
    
    Config Lcdpin = Pin , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7 , E = Portb.1 , Rs = Portb.2
    Config Lcd = 16 * 2
    Cls
    Cursor Off Noblink
    
    
    Lcd " HELLO WORLD!!!"
    Lowerline
    Lcd " by GIVER 2008"
    
    Do
    
    Loop
    End
    


    Kod się kompiluje, programowanie przeprowadzone bez błędów. Efekt: napis na wyświetlaczu.

    
    #include <avr/io.h>
    //
    #define LCD  PORTB
    #define E  1
    #define RS  2
    //
    #define SET_E   LCD |= _BV(E)
    #define CLR_E   LCD &= ~_BV(E)
    //
    #define SET_RS  LCD |= _BV(RS)
    #define CLR_RS  LCD &= ~_BV(RS)
    
    #define OSC 16
    // definicja funkcji opóźniającej
    void waitms(unsigned char x)
    {
    unsigned char a, b; // zmnienne licznikowe
    for( ; x > 0; --x) // ta pętla zostanie wykonana x-razy
    for(b = 10; b > 0; --b) // a ta 10 razy
    for(a = 25 * OSC; a > 0; --a) // natomiast ta 100 razy
    __asm("nop"); // dodatkowa instrukcja opóźniająca o 1 cykl
    // razem to da opóźnienie ok. x * 1ms
    // x od 0 do 255
    // gdy x = 0 to opóźnienie = 256ms
    }
    
    // pcodedura zapisu bajtu do wyświetlacza LCD
    // bez rozróżnienia instrukcja/dana
    void write_to_lcd(char x)
    {
    SET_E; // ustaw na E stan wysoki
    LCD = ((LCD & 0x0F) | (x & 0xF0)); // zapis pierwszej połówki bajtu
    CLR_E; // opadające zbocze na E -> zapis do wyświetlacza
    SET_E; // ustaw na E stan wysoki
    LCD = ((LCD & 0x0F) | ((x & 0x0F) << 4)); // zapis drugiej połowki bajtu
    CLR_E; // opadające zbocze na E -> zapis do wyświetlacza
    waitms(1); // czekaj 1ms
    }
    
    // procedura zapisu instrukcji do wyświetlacza LCD
    void write_command(char x)
    {
    CLR_RS; // niski stan na RS -> zapis instrukcji
    write_to_lcd(x); // zapis do LCD
    }
    
    // procedura zapisu danej do wyświetlacza LCD
    void write_char(char x)
    {
    SET_RS; // wysoki stan na RS -> zapis danej
    write_to_lcd(x); // zapis do LCD
    }
    
    // procedura zapisu tekstu do wyświetlacza LCD
    void write_text(char * s)
    {
    while(*s) // do napotkania 0
      {
      write_char(*s); // zapisz znak wskazywany przez s na LCD
      s++; // zwiększ s (przygotuj nastepny znak)
      }
    }
    
    // procedura inicjalizacji wyświetlacza LCD
    void lcd_init(void)
    {
    waitms(15); // czekaj 15ms na ustabilizowanie się napięcia zasilającego
    CLR_E; // E = 0
    CLR_RS; // RS = 0
    char i; // zmianna licznikowa
    for(i = 0; i < 3; i++) // trzykrotne powtórzenie bloku instrukcji
      {
      SET_E; // E = 1
      LCD &= 0x3F; //
      CLR_E; // E = 0
      waitms(5); // czekaj 5ms
      }
    SET_E; // E = 1
    LCD &= 0x2E; //
    CLR_E; // E = 0
    waitms(1); // czekaj 1ms
    write_command(0x28); // interfejs 4-bity, 2-linie, znak 5x7
    write_command(0x08); // wyłącz LCD, kursor i miganie
    write_command(0x01); // czyść LCD
    write_command(0x06); // bez przesuwania w prawo
    write_command(0x0C); // włącz LCD, bez kursora i mrugania
    }
    
    // program główny
    int main(void)
    {
    // konfiguracja portów we/wy
    DDRB = 0xFF;
    DDRD = 0xFC;
    PORTB = 0xFF;
    PORTD = 0xF7;
    // inicjalizacja LCD
    lcd_init();
    // zapisz na LCD przykładowy tekst
    write_text("Ala ma kota :D");
    // petla nieskończona
    while(1);
    return 0;
    }
    


    Efekt: brak napisu na wyświetlaczu.
    Dołączony zew. kwarc 16MHz
    [Atmega16]LCD - w Bascomie działa, a w C już nie.
    Nie może być mowy o błędnym połączeniu, ponieważ między kompilacją i programowanie pierwszego a drugiego programu nie było nic zmienianie w połączeniach.

    Poprawiłem tytuł.
    [zumek]
  • REKLAMA
  • #2 7139791
    FlashCode
    Poziom 13  
    Mogę się mylić, ale nie powinieneś przy definicji E i RS jeszcze podać którego portu bity 1 i 2 dotyczą? A jak masz ustawione wyprowadzenie R/W, na stałe L ?
  • REKLAMA
  • #3 7139801
    Darektbg
    Poziom 21  
    No nie ;) RS i E to tylko stała z zapisanym numerem bitu. Tak ma być. A co do R/W jest spięte do masy.
  • REKLAMA
  • #4 7139823
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • #5 7140302
    Darektbg
    Poziom 21  
    Dodam, że ten sam kod chodził dobrze na atiny2313. Tam był problem z kwarcem, ale tutaj wydaje mi się, że fusy i kwarc są w porządku.
  • #6 7140489
    zumek
    Poziom 39  
    Skojarz poniższe:
    
    #define OSC 16
    


    
    unsigned char a, b; // zmnienne licznikowe
    


    
    for(a = 25 * OSC; a > 0; --a) // natomiast ta 100 razy
    


    
    warning: large integer implicitly truncated to unsigned type
    

    Dlaczego ignorujesz ostrzeżenia :?:
    ...
    Poza tym, nie widzę w Twoim kodzie opóźnień, pomiędzy zapisami do LCD :|
REKLAMA