Sida 1 av 1

LCD Problem

Postat: 16 mars 2010, 19:15:18
av Stene
Hej!
Jag sitter o försöker få till en bra kod för en lcd. Jag kör med en 16f887 som jag kör på 20Mhz och en 4x20 lcd.
Problemet jag har att texten på lcd blinkar och då är den så svår att läsa. Den översta raden är ok men den nedre är himla svår. Jag är ganska säker på att det finns en bättre kod än den jag använt men jag lyckas inte hitta den. Är det någon som kan ge mig tips om hur jag får bort blinkandet?

Kod: Markera allt

while(1) 


  {     
       
    ADCON0 = 0b0.0.0010.0.1;                           /* vilken som ska omvandlas  AN2 */
    delay(20);
    GO=1;                                              /* start AD       */                                      
    while(GO);                                         /* wait for done  */                                   
    Pid = ADRESH;                                      /* plaserar värdet i char Pid */           

    ADCON0 = 0b0.0.0111.0.1;                           /* vilken som ska omvandlas  AN7 */
    delay(20);
    GO=1;                                              /* start AD        */                               
    while(GO);                                         /* wait for done   */                               
    pId = ADRESH;                                      /* plaserar värdet i char pId */
   
    

   /* analog 3 */
    ADCON0 = 0b0.0.0101.0.1;                           /* vilken som ska omvandlas  AN5 */
    delay(20);
    GO=1;                                              /* start AD        */                               
    while(GO);                                         /* wait for done   */                               
    piD = ADRESH;                                      /* plaserar värdet i char piD */

    

    ADCON0 = 0b0.0.0110.0.1;                           /* vilken som ska omvandlas  AN6 */
    delay(20);
    GO=1;                                              /* start AD        */                               
    while(GO);                                         /* wait for done   */                               
    bor = ADRESH;                                      /*plaserar värdet i char bor */
   
    

    /* beräkning varvtal  */

    varvtal_1 = 7000000/tid_1;                        /* beräkning av varvtal ej rätt!!!*/
    

    ar = varvtal_1 - varvtal_2;                       /* beräkning av är varvtalet */
    varvtal_2 = varvtal_1;                            /* flyttar senaste varvtalet till varvtal 2 */

    if (TMR1IF == 1 )
    {
     varvtal_1 = 0;
         }  
                 
      
       delay(100);
       

       chartoa1(Pid);                                 /* skickar char för omvandling till ascci */
       chartoa2(pId);                                 /* skickar char för omvandling till ascci */
       chartoa3(piD);                                 /* skickar char för omvandling till ascci */
       chartoa4(bor);                                 /* skickar char för omvandling till ascci */
       chartoa5(fel);                                 /* skickar char för omvandling till ascci */
       unslongtoa( varvtal_1 );                       /* skickar char för omvandling till ascci */                     
       string_out();                                  /* skickar till lcd */
       
    
   
    }
   
}




char text1( char x)                                   /* text 1 */
{
   skip(x);                                           /* internal function CC5x.  */
   #pragma return[] = " P = "    
}

char text2( char x)                                   /* text 2 */
{
   skip(x);                                           /* internal function CC5x.  */
   #pragma return[] = " I = "     
}  

char text3( char x)                                   /* text 3 */
{
   skip(x);                                           /* internal function CC5x.  */
   #pragma return[] = " D = "     
}  

char text4( char x)                                   /* text 4 */
{
   skip(x);                                           /* internal function CC5x.  */
   #pragma return[] = "bor= "    
}  

char text5( char x)                                   /* text 5 */
{
   skip(x);                                           /* internal function CC5x.  */
   #pragma return[] = " fel= "      
}  

char text6( char x)                                   /* text 6 */
{
   skip(x);                                           /* internal function CC5x.  */
   #pragma return[] = " RPM= "     
}  

             void string_out(void)                    /* utskrift till lcd */
   {

    char i;
    lcd_init();

    RS = 1;
    for(i=0; i<5; i++) lcd_putchar(text1(i)); 
    
    RS = 1;
    for(i=5; i<8; i++) lcd_putchar(s[i]); 

 
    RS = 1;
    for(i=0; i<5; i++) lcd_putchar(text2(i));
 
    RS = 1;
    for(i=5; i<8; i++) lcd_putchar(I[i]); 

    RS = 0;                                          /* skiftar till rad 2 */
    lcd_putchar( 0b11000000 );   
 
    RS = 1;
    for(i=0; i<5; i++) lcd_putchar(text3(i));
 
    RS = 1;
    for(i=5; i<8; i++) lcd_putchar(D[i]); 

    RS = 0;                                         /* skiftar till rad 3 */
    lcd_putchar( 0b10010100 );   
 
    RS = 1;
    for(i=0; i<5; i++) lcd_putchar(text4(i));
 
    RS = 1;
    for(i=5; i<8; i++) lcd_putchar(L[i]); 

    RS = 1;
    for(i=0; i<5; i++) lcd_putchar(text5(i));
 
    RS = 1;
    for(i=5; i<8; i++) lcd_putchar(F[i]); 

    RS = 0;                                         /* skiftar till rad 4 */
    lcd_putchar( 0b11010100 );   
 
    RS = 1;
    for(i=0; i<6; i++) lcd_putchar(text6(i));
 
    RS = 1;
    for(i=1; i<5; i++) lcd_putchar(V[i]);

 }
   
   




void chartoa1(char p)                               /* gör om till ascci */
{
   char i,temp;
   s[8]='\0';
   for (i = 7; ;i--)
      {
       temp = p % 10;
       temp += '0';
       s[i]=temp;
       if (i==0) break;
       p /= 10; 
      }
}

void chartoa2(char p)                              /* gör om till ascci */
{
   char i,temp;
   I[8]='\0';
   for (i = 7; ;i--)
      {
       temp = p % 10;
       temp += '0';
       I[i]=temp;
       if (i==0) break;
       p /= 10; 
      }
}

void chartoa3(char p)                              /* gör om till ascci */
{
   char i,temp;
   D[8]='\0';
   for (i = 7; ;i--)
      {
       temp = p % 10;
       temp += '0';
       D[i]=temp;
       if (i==0) break;
       p /= 10; 
      }
}

void chartoa4(char p)                              /* gör om till ascci */
{
   char i,temp;
   L[8]='\0';
   for (i = 7; ;i--)
      {
       temp = p % 10;
       temp += '0';
       L[i]=temp;
       if (i==0) break;
       p /= 10; 
      }
} 

void chartoa5(char p)                              /* gör om till ascci */
{
   char i,temp;
   F[8]='\0';
   for (i = 7; ;i--)
      {
       temp = p % 10;
       temp += '0';
       F[i]=temp;
       if (i==0) break;
       p /= 10; 
      }
}   

void unslongtoa(unsigned long u16)                 /* gör om till ascci */
{
   char i,temp;
   V[5] = '\0';
   for (i = 4; ;i--)
      {
       temp = u16 % 10;
       temp += '0';
       V[i]=temp;
       if (i==0) break;
       u16 /= 10;
      }
}



void delay( char millisec)                         /* fördröjningen 1 millisekunder vid 4 Mhz */

{
    OPTION = 2;                                    /* prescaler divide by 8        */
    do  {
        TMR0 = 0;
        while ( TMR0 < 125)                        /* 125 * 8 = 1000  */
            ;
    } while ( -- millisec > 0);
}


void lcd_init( void )                              /* måstes köras innan lcd används */ 
{
  delay(20);                                       /* lcd får tid att ställa in sig  40 */ 
  RS = 0;                                          /* lcd i kommando läge */  
  lcd_putchar(0b0011.0011);                        /* LCD starts in 8 bit mode          */
  lcd_putchar(0b0011.0010);                        /* change to 4 bit mode              */
  lcd_putchar(0b00101000);                         /* two line (8+8 chars in the row)   */ 
  lcd_putchar(0b00001100);                         /* display on, cursor off, blink off */
  lcd_putchar(0b00000001);                         /* display clear                     */  
  lcd_putchar(0b00000110);                         /* increment mode, shift off         */ 
  RS = 1;                                          /* lcd i skrivar läge */   
             
}


void lcd_putchar( char data )
{
  // must set LCD-mode before calling this function!
  // RS = 1 LCD in character-mode
  // RS = 0 LCD in command-mode
  // upper Nybble
  D7 = data.7;
  D6 = data.6;
  D5 = data.5;
  D4 = data.4;
  EN = 0;
  nop();
  EN = 1;
  delay(9);                                        /* 5 */
  // lower Nybble
  D7 = data.3;
  D6 = data.2;
  D5 = data.1;
  D4 = data.0;
  EN = 0;
  nop();
  EN = 1;
  delay(9);                                        /* 5 */
  
}

Re: LCD Problem

Postat: 16 mars 2010, 20:47:35
av sodjan
> Jag kör med en 16f887 som jag kör på 20khz

Det är ju väldigt långsamt.

> Är det någon som kan ge mig tips om hur jag får bort blinkandet?

Om blinkandet beror på att du skriver konstant till LCD'n, så är nog bara
lösningen att inte skriva så ofta till den.

Re: LCD Problem

Postat: 16 mars 2010, 20:56:33
av Pajn
Som Sodjan säger så skriver du troligtvis allt för ofta till displayen. Dessutom initierar du displayen varje gång du skriver till den.

Re: LCD Problem

Postat: 16 mars 2010, 21:14:50
av ToPNoTCH
Kan inte C men om jag förstår koden rätt så instämmer jag i tidigare inlägg.

Adressera startposition på rätt rad och skriv endast varvtalet där.
Tänk på att fylla på med blanktecken eller nollor bara så att gamla tecknena skrivs över helt.

Sedan är det ju alltid en avvägning mellan hur ofta man verkligen behöver uppdatera då konstant uppdatering med hög frekvens kan ge visst flimmer.
En snyggare lösning är ju att bara uppdatera när värdet ändrats.

Men den stora boven är den ständiga initialiseringen tror jag.

Re: LCD Problem

Postat: 17 mars 2010, 19:30:07
av Stene
Hej!
Jag skrev fel angående vilken frekvens jag körde med, det ska vara 20 Mhz.
Ni har ide om att det är den ständiga initialiseringen som ställer till det största problemet. Hur tycker ni att jag ska göra för att fixa till det? Läggar jag det före while(1) eller? Om jag ska göra det hur gör jag då med RS funktionen i void lcd_init?

Re: LCD Problem

Postat: 17 mars 2010, 20:08:53
av Pajn
Jag förstår inte vad RS skapar för problem, men du har inte postat koden där du sätter variabeln/deffinerar den så om du postar det blir det lättar att förstå.
Du verkar ha missat hela huvudet på koden då du inte har någon main funktion, kan du posta det?

En annan grej, som visserligen inte har med "blinkadet" att göra är att du sätter RS varje gång du skriver till displayen i funktionen string_out()
om du redan vet att RS är ett behöver du ju inte sätta den till ett igen exempel:

Kod: Markera allt

    RS = 1;
    for(i=0; i<5; i++) lcd_putchar(text1(i));
   
    RS = 1;
    for(i=5; i<8; i++) lcd_putchar(s[i]); 

Re: LCD Problem

Postat: 17 mars 2010, 20:23:13
av Stene
Hej!
Här kommer main koden som jag missade förra gången. Det är mycket möjligt att jag gjort allt fel!

Kod: Markera allt

void main( void)
{
    
      
        TRISD = 0b00.00.0000;                              /* inställning av D-porten in ellet ut 1=in 0= ut */
        TRISC = 0b00.00.0100;                              /* inställning av C-porten in ellet ut 1=in 0= ut */                          
        TRISB = 0b00.00.0000;                              /* inställning av B-porten in ellet ut 1=in 0= ut */
        TRISA = 0b00.00.0000;                              /* inställning av A-porten in ellet ut 1=in 0= ut */
        ADCON1 = 0b0.001.0000;                             /* inställning av hastigheten att omvandla AN till dig */
        T1CON = 0b00.11.0.0.0.1 ;                          /* inställning av timer 1 */
        T2CON = 0b0.0000.1.01;                             /* inställning av timer 2 */
        CCP1CON = 0b00.00.0101 ;                           /* inställning av CCP1 ingången, pulser in */
        CCP2CON = 0b00.00.1100 ;                           /* inställning av CCP2 ingången, PWM ut */
       
        PEIE    = 1 ;
        CCP1IE  = 1 ; 
        GIE     = 1;                                       /* global enable */
        PR2 = 255;                                         /* timer räknar till 255 o seda börjar om */
        ANSELH=0;                                          /* dom höga analoga används ej */
        ANSEL.7 = 1;                                       /* analoga kanalen 7 på */
        ANSEL.2 = 1;                                       /* analoga kanalen 2 på */
        ANSEL.5 = 1;                                       /* analoga kanalen 5 på */
        ANSEL.6 = 1;                                       /* analoga kanalen 6 på */ 

        OPTION .7 =0;                                      /* pullup på */

        



Re: LCD Problem

Postat: 17 mars 2010, 20:45:05
av Pajn
Du har fortfarande inte med koden där du definierar RS men men jag antar att den pekar på en pinne.
Om du flyttar upp lcd_init() så att den hamnar innan loopen men efter all "pin initiering" så görs ju initieringen bara när picen startar.

Re: LCD Problem

Postat: 17 mars 2010, 21:35:32
av Stene
Hej!
Ok jag tror att jag förstår men jag lyckas inte få det att fungera. Ska jag lägga in hela voiden? eller?

Kod: Markera allt

  /*  16f887 o lcd */

#include "16F887.h"
#include "int16Cxx.h" 
#pragma config |= 0x00D2                                 /* instälningar pic */

bank1 unsigned long tid_1;                               /* första tidtagningen  */


#pragma origin 4                                         /* interrepten */
interrupt int_server( void )                             /* the place for the interrupt routine */
{
  int_save_registers
  if( CCP1IF == 1 )                                      /* vänta på puls */
  {
    
    tid_1  = CCPR1H*256;
    tid_1 += CCPR1L;





    CCP1IF = 0;                                          /* nollar flaga för interrupt */ 
    TMR1H = 0;                                           /* nollar tiner 1 */
    TMR1L = 0;                                           /* nollar timer 1 */
    TMR1IF = 0;  
    
     } 
  int_restore_registers
}
 
#include "MATH16.H"                                      /* matte bibloteket */


#pragma bit RS  @ PORTD.3                                /* utgång för lcd  RC6 */
#pragma bit EN  @ PORTD.2                                /* utgång för lcd  RC7 */

#pragma bit D7  @ PORTC.4                                /* utgång för lcd  RC4 */
#pragma bit D6  @ PORTD.4                                /* utgång för lcd  RB6 */
#pragma bit D5  @ PORTB.4                                /* utgång för lcd  RB4 */
#pragma bit D4  @ PORTB.2                                /* utgång för lcd  RC0 */

void string_out( void );                                 /* void utskriften */
void delay( char );                                      /* void fördröjning */
void lcd_init( void );                                   /* initsiering av lcd */
void lcd_putchar( char );                                /* utskrift lcd */
char text1( char );                                      /* text till lcd */       
char text2( char );                                      /* text till lcd */
char text3( char );                                      /* text till lcd */
char text4( char );                                      /* text till lcd */
char text5( char );                                      /* text till lcd */
void unslongtoa( unsigned long );                        /* omvandlingen från unsigned long till ascci */
void chartoa1(char  );                                   /* omvandlingen från char till ascci */
void chartoa2(char  );                                   /* omvandlingen från char till ascci */
void chartoa3(char  );                                   /* omvandlingen från char till ascci */
void chartoa4(char  );                                   /* omvandlingen från char till ascci */
void chartoa5(char  );                                   /* omvandlingen från char till ascci */

char s[11];                                              /* char för char till ascci */
char I[11];                                              /* char för char till ascci */                     
char D[11];                                              /* char för char till ascci */
char L[11];                                              /* char för char till ascci */
char F[11];                                              /* char för char till ascci */
bank1 char V[11];                                        /* char för char till ascci */









void main( void)
{
    
        
        TRISD = 0b00.00.0000;                              /* inställning av D-porten in ellet ut 1=in 0= ut */
        TRISC = 0b00.00.0100;                              /* inställning av C-porten in ellet ut 1=in 0= ut */                          
        TRISB = 0b00.00.0000;                              /* inställning av B-porten in ellet ut 1=in 0= ut */
        TRISA = 0b00.00.0000;                              /* inställning av A-porten in ellet ut 1=in 0= ut */
        ADCON1 = 0b0.001.0000;                             /* inställning av hastigheten att omvandla AN till dig */
        T1CON = 0b00.11.0.0.0.1 ;                          /* inställning av timer 1 */
        T2CON = 0b0.0000.1.01;                             /* inställning av timer 2 */
        CCP1CON = 0b00.00.0101 ;                           /* inställning av CCP1 ingången, pulser in */
        CCP2CON = 0b00.00.1100 ;                           /* inställning av CCP2 ingången, PWM ut */
        PEIE    = 1 ;
        CCP1IE  = 1 ; 
        GIE     = 1;                                       /* global enable */
        PR2 = 255;                                         /* timer räknar till 255 o seda börjar om */

        ANSELH=0;                                          /* dom höga analoga används ej */
        ANSEL.7 = 1;                                       /* analoga kanalen 7 på */
        ANSEL.2 = 1;                                       /* analoga kanalen 2 på */
        ANSEL.5 = 1;                                       /* analoga kanalen 5 på */
        ANSEL.6 = 1;                                       /* analoga kanalen 6 på */ 

        
        OPTION .7 =0;                                      /* pullup på */

  

Re: LCD Problem

Postat: 17 mars 2010, 22:03:20
av Pajn
>Ska jag lägga in hela voiden? eller?
Nja, du ska anropa funktionen:

Kod: Markera allt

ANSEL.6 = 1; /* analoga kanalen 6 på */


OPTION .7 =0; /* pullup på */
lcd_init();
Samt ta bort anropet från string_out()

Kod: Markera allt

void string_out(void)                    /* utskrift till lcd */
   {

    char i;

    RS = 1;

Re: LCD Problem

Postat: 18 mars 2010, 19:45:28
av Stene
Hej!
Japp nu fungerar det som jag vill efter att jag flyttat initialiseringen. Det va det som vad problemet.
Tack för hjälpen!!