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

[C]Wyświetlacz LCD-nie mogę wświetlić stringa.

desmo999 13 Wrz 2008 20:40 1398 9
REKLAMA
  • #1 5532518
    desmo999
    Poziom 12  
    Witam wszystkich.

    Oto mój programik do obsługi LCD który miał wyświetlać całe wyrazy na nim.Jednak coś nie chce działać do końca.Może ktoś mógłby go sprawdzić u siebie bo sam już nie wiem czy to wina sprzętu czy wina programu - pojedyncze litery wyświetla:
    
    #include <avr/io.h>
    #include<inttypes.h>
    #include<avr/pgmspace.h>
    
    #define cbi(sfr, bit)   (_SFR_BYTE(sfr) &= ~_BV(bit))
    #define sbi(sfr, bit)   (_SFR_BYTE(sfr) |= _BV(bit))
    
    #define LCD_PORT   PORTB
    #define lcd_rs 2
    #define lcd_e 3
    #define CR 0x0a
    
    
    
    
    void czekaj(unsigned long pt)  ///petla opozniajaca
    
    
     {
       #define tau 10.38
             
    		 unsigned char tp1;
             for(;pt>0;pt--)
    		 
    	    {
    	       for(tp1=255;tp1!=0;tp1--)
    		      {
    	           asm ("nop");
    	           }        
    	  }
    	   
      }
    
    void instrukcja( char instr)
    
      {
       cbi (PORTB,lcd_rs);
       cbi (PORTB,lcd_e);
       PORTB=(PORTB&0x0f)|(instr&0xf0);
       sbi (PORTB,lcd_e);
       asm("nop");
       asm("nop");
       asm("nop");
       
      
       
       czekaj(10L);
       cbi (PORTB,lcd_rs);
       cbi (PORTB,lcd_e);
       PORTB=(PORTB&0x0f)|((instr&0x0f)<<4);
       sbi (PORTB,PB3);
       asm("nop");
       asm("nop");
       asm("nop");
    
       cbi(PORTB,lcd_e);
       czekaj(10L);
    }
    
    
    void LCDdata(char data)
    
      {
       sbi (PORTB,lcd_rs);
       cbi (PORTB,lcd_e);
       PORTB=(PORTB&0x0f)|(data&0xf0);
       sbi (PORTB,lcd_e);
       asm("nop");
       asm("nop");
       asm("nop");
       
      
       
       czekaj(15L);
       sbi (PORTB,lcd_rs);
       cbi (PORTB,lcd_e);
       PORTB=(PORTB&0x0f)|((data&0x0f)<<4);
       sbi (PORTB,lcd_e);
       czekaj(50*tau);
       asm("nop");
       asm("nop");
       asm("nop");
    
      czekaj(15);
    }
    
     void LCDstr(char *str)
       {
       
       
        int n=0;
    
         while(0!=str[n])
    	 {
    	   LCDdata(str[n]);
    	   n++;
    	  } 
    	   
    }
    
    
    
    
    int main(void)
    {
    
    
    PORTB=0x03;   //pb0-pb3 - podciągniecia
    DDRB=0xff;    //portb-wyjscie
    
    czekaj(45*tau);   //stabilizowanie napiecia
    
    
    
    
    
      
    cbi(PORTB,lcd_rs);
    cbi(PORTB,lcd_e);
    PORTB=(PORTB&0x00)|0x20;
    sbi(PORTB,PB3);
    asm("nop");
    asm("nop");
    asm("nop");
    cbi(PORTB,lcd_e);
    czekaj(50);
    instrukcja(0x28);  //interfejs 4 bitowy , 2 linie,znak 5x7
    instrukcja(0x08);  //wylacz LCD,wylacz kursor,wylacz mruganie
    instrukcja(0x01);  //czysc lcd
    instrukcja(0x01);
    instrukcja(0x0f);
    czekaj(2*tau);
    while(1)
    {
    instrukcja(0x0f);
    LCDstr("ja");
    
    
    return(0);
    }
    }
    


    pozdrawiam wszystkich:]

    Problem , to "zakazane" słowo w tytule tematu - regulamin
    Tytuł poprawiłem.
    [zumek]
  • REKLAMA
  • #2 5533024
    markosik20
    Poziom 33  
    void LCDstr(char *str) 
       { 
        
        while(*str) 
        { 
          LCDdata(*str); 
          str++; 
         } 
           
    }
  • REKLAMA
  • #3 5533216
    desmo999
    Poziom 12  
    Niestety zmiana nic nie daje:(po kompilacji i wgraniu do AVR-ka wszystko wygląda jak w poprzedniej wersji.

    Pozdrawiam
  • REKLAMA
  • #5 5533847
    zumek
    Poziom 39  
    Myślę , że błąd jest w części konfiguracyjnej LCD , bo nie widzę polecenia entry mode set , ale widzę 2 razy CLS - po co :?:
    Jest:
    
    instrukcja(0x28);  //interfejs 4 bitowy , 2 linie,znak 5x7
    instrukcja(0x08);  //wylacz LCD,wylacz kursor,wylacz mruganie
    instrukcja(0x01);  //czysc lcd
    instrukcja(0x01);
    instrukcja(0x0f); 

    Zmienić na:
    
    instrukcja(0x28);  //interfejs 4 bitowy , 2 linie,znak 5x7
    instrukcja(0x08);  //wylacz LCD,wylacz kursor,wylacz mruganie
    instrukcja(0x01);  //czysc lcd
    instrukcja(0x06);  //entry mode set  I/D=1 , S=0
    instrukcja(0x0f); 


    Sprawdź.

    Piotrek
  • #6 5534287
    desmo999
    Poziom 12  
    No niestety nic zmienay nie wniosły i nadal działa wyświetlanie tylko pojedynczych literek
    czyli;

    
    
    LCDdata('j');
    
    



    Pozdrawiam

    Dodano po 5 [godziny] 45 [minuty]:

    Może jeśli ktoś miałby ochote to niech wgra ten programik do sowjego AVR i sprawdzi czy u niego to działa, bo może błąd nie do końca tkwi w programie.
  • #7 5536116
    madteus
    Poziom 11  
    Nie wiem czy coś to da ale napisać warto. Sprawa może wyglądać tak, że jeśli w str jest jakiś ciąg znaków to po każdym znaku w tablicy str może byc znak '\0' ('\0'==0) np. str={'s',\0','l','\0','o','\0','w','\0','o'}. Po wyświetleniu pierwszego znaku pętla while zakończy w takim układzie działanie.
     
    void LCDstr(char *str)
    {
       
       
        int n=0;
    
         while(0!=str[n])
        {
          LCDdata(str[n]);
          n++;
         }
          
    }
  • #8 5538245
    desmo999
    Poziom 12  
    WITAM

    Programik zaczął działać - poprawny kod znajduje się poniżej.

    Pozdrawiam
  • #9 5539036
    madteus
    Poziom 11  
    Móglbyś napisać co było źle?
  • REKLAMA
  • #10 5540867
    desmo999
    Poziom 12  
    Witam.

    Oczywiście już piszę co zmieniłem w kodzie .Oto kod:
    
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <stdlib.h>
    #include<inttypes.h>
    #include<avr\pgmspace.h>
    
    unsigned char wiersz=0;
    unsigned char kolumna=0;
    #include <string.h>
    
    #define cbi(sfr, bit)   (_SFR_BYTE(sfr) &= ~_BV(bit))
    #define sbi(sfr, bit)   (_SFR_BYTE(sfr) |= _BV(bit))
    
    #define LCD_PORT   PORTB
    #define lcd_rs 2
    #define lcd_e 3
    #define CR 0x0a
    
    
    
    
    void czekaj(unsigned long pt)  ///petla opozniajaca
    
    
     {
       #define tau 10.38
             
    		 unsigned char tp1;
             for(;pt>0;pt--)
    		 
    	    {
    	       for(tp1=255;tp1!=0;tp1--)
    		      {
    	           asm ("nop");
    	           }        
    	  }
    	   
      }
    
    void instrukcja( char instr)
    
      {
       cbi (PORTB,lcd_rs);
       cbi (PORTB,lcd_e);
       PORTB=(PORTB&0x0f)|(instr&0xf0);
       sbi (PORTB,lcd_e);
       asm("nop");
       asm("nop");
       asm("nop");
       
      
       
       czekaj(10L);
       cbi (PORTB,lcd_rs);
       cbi (PORTB,lcd_e);
       PORTB=(PORTB&0x0f)|((instr&0x0f)<<4);
       sbi (PORTB,PB3);
       asm("nop");
       asm("nop");
       asm("nop");
    
       cbi(PORTB,lcd_e);
       czekaj(10L);
    }
    
    
    void LCDdata( char data)
    
      {
       sbi (PORTB,lcd_rs);
       cbi (PORTB,lcd_e);
       PORTB=(PORTB&0x0f)|(data&0xf0);
       sbi (PORTB,lcd_e);
       asm("nop");
       asm("nop");
       asm("nop");
       
      
       
       czekaj(15L);
       sbi (PORTB,lcd_rs);
       cbi (PORTB,lcd_e);
       PORTB=(PORTB&0x0f)|((data&0x0f)<<4);
       sbi (PORTB,lcd_e);
       czekaj(50*tau);
       asm("nop");
       asm("nop");
       asm("nop");
    
      czekaj(15);
    }
    
    void LCDstr(char *str)
       { 
          char znak;
          while(0!=(znak=pgm_read_byte(str++)))
    	 {
          
          
    	   LCDdata(znak);
    	   
    	   
    	  } 
    	  }  
    
    
    
    
    int main(void)
    {
    
    
    PORTB=0x03;   //pb0-pb3 - podciągniecia
    DDRB=0xff;    //portb-wyjscie
    
    czekaj(45*tau);   //stabilizowanie napiecia
    
    
    
    
    
    int i;for (i=0;i<3;i++)
       {
      
         cbi(PORTB,lcd_rs);
         cbi(PORTB,lcd_e);
    	 PORTB=(PORTB&0x00)|0x20;
    	 sbi(PORTB,PB3);
         asm("nop");
    	 asm("nop");
    	 asm("nop");
    	 cbi(PORTB,lcd_e);
    	 czekaj(50);
                     }
    
    instrukcja(0x28);  //interfejs 4 bitowy , 2 linie,znak 5x7
    instrukcja(0x08);  //wylacz LCD,wylacz kursor,wylacz mruganie
    instrukcja(0x01);  //czysc lcd
    instrukcja(0x06);
    instrukcja(0x0f);
    czekaj(2*tau);
    
    instrukcja(0x01); 
    LCDstr(PSTR("Hello "));
      
     
    
      return(0);
    }
    


    Zostało dodane makro PSTR które tworzy napis w pamięci programu i zwraca wskaźnik do niego oraz dodałem makro pgm_read_byte które umożliwia dostęp do danych zapisanych w pamięci programu. Tak prznajmiej jest zapisane w kursie programowania C który był w Edw :)
    pozdrawiam
REKLAMA