CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Problem with 877A and CCS.
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Andask



Joined: 24 Apr 2009
Posts: 10

View user's profile Send private message

Problem with 877A and CCS.
PostPosted: Mon Oct 12, 2009 2:00 pm     Reply with quote

First of all, sorry for my reaaally poor english... =/

I'm having some problems with software that I'm doing ...

I entered this little code for tests, when I simulate the Proteus and MPLAB, everything is ok, but when you step into the proto-board, the trouble starts.

This is my first program in C and I am using the CCS. The newest version, I picked up on the site. (Demo)

I'll post the code I'm using for the development.
The main, the "library" reading array of keys, and controlling the LCD.

I did not add any extra comment in the source, because it is extremely simple and I believe that comments are not necessary.

But any doubt about the purpose of code you might ask.

Monday when I get back to work, I will make a video of the protoboard when it is running.

Code:

#include <16f877a.h>
#use delay(clock=4000000)
#fuses XT,NOWDT,PUT,NOLVP,NOBROWNOUT,NOPROTECT
#include <mod_lcd.c>
#include <funcs.h>

int x;

void main ()
{
   lcd_ini();
   lcd_escreve('\f');
   printf(lcd_escreve,"Teste");
   
   while(true)
      {   
         lcd_escreve('\f');
         x = leitura(0);
         printf(lcd_escreve,"%u",x);
         delay_ms(500);
      }
}


Code:

/************************************************************************/
/*  MOD_LCD.C - Biblioteca de manipulação de módulo LCD                 */
/*                                                                      */
/*  Autor: Fábio Pereira                                                */
/*                                                                      */
/************************************************************************/

// As definições a seguir são utilizadas para acesso aos pinos do display
// caso o pino RW não seja utilizado, comente a definição lcd_rw
#ifndef lcd_enable
   #define lcd_enable     pin_e1      // pino enable do LCD
   #define lcd_rs         pin_e0      // pino rs do LCD
   //#define lcd_rw      pin_e2      // pino rw do LCD
   #define lcd_d4         pin_d4      // pino de dados d4 do LCD
   #define lcd_d5         pin_d5      // pino de dados d5 do LCD
   #define lcd_d6         pin_d6      // pino de dados d6 do LCD
   #define lcd_d7         pin_d7      // pino de dados d7 do LCD
#endif

#define lcd_type 2           // 0=5x7, 1=5x10, 2=2 linhas
#define lcd_seg_lin 0x40    // Endereço da segunda linha na RAM do LCD

// a constante abaixo define a seqüência de inicialização do módulo LCD
byte CONST INI_LCD[4] = {0x20 | (lcd_type << 2), 0xf, 1, 6};

byte lcd_le_byte()
// lê um byte do LCD (somente com pino RW)
{
   byte dado;
   // configura os pinos de dados como entradas
   input(lcd_d4);
   input(lcd_d5);
   input(lcd_d6);
   input(lcd_d7);
   // se o pino rw for utilizado, coloca em 1
   #ifdef lcd_rw
      output_high(lcd_rw);
   #endif
   output_high(lcd_enable); // habilita display
   dado = 0;   // zera a variável de leitura
   // lê os quatro bits mais significativos
   if (input(lcd_d7)) bit_set(dado,7);
   if (input(lcd_d6)) bit_set(dado,6);
   if (input(lcd_d5)) bit_set(dado,5);
   if (input(lcd_d4)) bit_set(dado,4);
   // dá um pulso na linha enable
   output_low(lcd_enable);
   output_high(lcd_enable);
   // lê os quatro bits menos significativos
   if (input(lcd_d7)) bit_set(dado,3);
   if (input(lcd_d6)) bit_set(dado,2);
   if (input(lcd_d5)) bit_set(dado,1);
   if (input(lcd_d4)) bit_set(dado,0);
   output_low(lcd_enable);   // desabilita o display
   return dado;   // retorna o byte lido
}

void lcd_envia_nibble( byte dado )
// envia um dado de quatro bits para o display
{
   // coloca os quatro bits nas saidas
   output_bit(lcd_d4,bit_test(dado,0));
   output_bit(lcd_d5,bit_test(dado,1));
   output_bit(lcd_d6,bit_test(dado,2));
   output_bit(lcd_d7,bit_test(dado,3));
   // dá um pulso na linha enable
   output_high(lcd_enable);
   output_low(lcd_enable);
}


void lcd_envia_byte( boolean endereco, byte dado )
{
   // coloca a linha rs em 0
   output_low(lcd_rs);
   // aguarda o display ficar desocupado
   //while ( bit_test(lcd_le_byte(),7) ) ;
   // configura a linha rs dependendo do modo selecionado
   output_bit(lcd_rs,endereco);
   delay_us(100);   // aguarda 100 us
   // caso a linha rw esteja definida, coloca em 0
   #ifdef lcd_rw
      output_low(lcd_rw);
   #endif
   // desativa linha enable
   output_low(lcd_enable);
   // envia a primeira parte do byte
   lcd_envia_nibble(dado >> 4);
   // envia a segunda parte do byte
   lcd_envia_nibble(dado & 0x0f);
}


void lcd_ini()
// rotina de inicialização do display
{
   byte conta;
   output_low(lcd_d4);
   output_low(lcd_d5);
   output_low(lcd_d6);
   output_low(lcd_d7);
   output_low(lcd_rs);
   //#ifdef lcd_rw
   //   output_high(lcd_rw);
   //#endif
   output_low(lcd_enable);
   delay_ms(15);
   // envia uma seqüência de 3 vezes 0x03
   // e depois 0x02 para configurar o módulo
   // para modo de 4 bits
   for(conta=1;conta<=3;++conta)
   {
      lcd_envia_nibble(3);
      delay_ms(5);
   }
   lcd_envia_nibble(2);
   // envia string de inicialização do display
   for(conta=0;conta<=3;++conta) lcd_envia_byte(0,INI_LCD[conta]);
}

void lcd_pos_xy( byte x, byte y)
{
   byte endereco;
   if(y!=1)
      endereco = lcd_seg_lin;
   else
      endereco = 0;
   endereco += x-1;
   lcd_envia_byte(0,0x80|endereco);
}

void lcd_escreve( char c)
// envia caractere para o display
{
   switch (c)
   {
     case '\f'    :   lcd_envia_byte(0,1);
              delay_ms(2);
            break;
     case '\n'   :
     case '\r'    :   lcd_pos_xy(1,2);
              break;
     case '\b'    :   lcd_envia_byte(0,0x10);
              break;
     default   :   lcd_envia_byte(1,c);
              break;
   }
}

char lcd_le( byte x, byte y)
// le caractere do display
{
   char valor;
   // seleciona a posição do caractere
   lcd_pos_xy(x,y);
   // ativa rs
   output_high(lcd_rs);
   // lê o caractere
   valor = lcd_le_byte();
   // desativa rs
   output_low(lcd_rs);
   // retorna o valor do caractere
   return valor;
}


Code:

#define col1 pin_b3
#define col2 pin_b2
#define col3 pin_b1

#define lin1 pin_b4
#define lin2 pin_b5
#define lin3 pin_b6
#define lin4 pin_b7

int tecla_temp, tecla;

#SEPARATE
int leitura(int y)
{

   output_low(col1);
   output_low(col2);
   output_low(col3);
   
   tecla_temp = 0;
   tecla = 0;

   ler:
   
   while(true)
   {
      //Testar coluna 1, valores 1, 4, 7, 254;
      output_high(col1);
      if (input(lin1))
      {
       
        while (input(lin1)) {}
       
        tecla_temp = 1;
        break;
      } else
      if (input(lin2))
      {
             
        while (input(lin2)) {}
       
        tecla_temp = 4;
        break;
      } else
      if (input(lin3))
      {
             
        while (input(lin3)) {}
       
        tecla_temp = 7;
        break;
      } else
      if (input(lin4))
      {
             
        while (input(lin4)) {}
       
        tecla_temp = 254;
        break;
      }
     
      output_low(col1);
     
      //Testar coluna 2, valores 2, 5, 8, 0;
      output_high(col2);
      if (input(lin1))
      {
             
        while (input(lin1)) {}
       
        tecla_temp = 2;
        break;
      } else
      if (input(lin2))
      {
             
        while (input(lin2)) {}
       
        tecla_temp = 5;
        break;
      } else
      if (input(lin3))
      {
             
        while (input(lin3)) {}
       
        tecla_temp = 8;
        break;
      } else
      if (input(lin4))
      {
             
        while (input(lin4)) {}
       
        tecla_temp = 0;
        break;
      }
     
      output_low(col2);
     
      //Testar coluna 3, valores 3, 6, 9, 255;
      output_high(col3);
      if (input(lin1))
      {
             
        while (input(lin1)) {}
       
        tecla_temp = 3;
        break;
      } else
      if (input(lin2))
      {
             
        while (input(lin2)) {}
       
        tecla_temp = 6;
        break;
      } else
      if (input(lin3))
      {
             
        while (input(lin3)) {}
       
        tecla_temp = 9;
        break;
      } else
      if (input(lin4)) // enter
      {
             
        while (input(lin4)) {}
       
        tecla_temp = 255;
        break;
      }
     
      output_low(col3);

   }   
     
   if (tecla_temp < 254)
   {
     tecla = tecla * 10;
     tecla = tecla + tecla_temp;
   }
   
   if (tecla_temp == 255)
   {
     while (input(lin4)){};
     if (tecla == 0) tecla = 255; else tecla = tecla;
     return tecla;
   }
   
   if (tecla_temp == 254)
   {
     tecla = 254;
     return tecla;
   }
   if (y == 1) printf(lcd_escreve,"%u",tecla_temp);   
   goto ler;
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 12, 2009 2:12 pm     Reply with quote

Quote:
when you step into the proto-board, the trouble starts.

Describe the trouble.
Andask



Joined: 24 Apr 2009
Posts: 10

View user's profile Send private message

PostPosted: Mon Oct 12, 2009 2:16 pm     Reply with quote

The display flashes the figures "254" and "255", it would be normal even if I had pressed any key, but this occurs even with the keyboard off.

And when the keyboard was on, and I came in with some key value, typing for example "7" + "enter", the display shows something like "7777474547 "....
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 12, 2009 6:20 pm     Reply with quote

Quote:

#define lin3 pin_b6
#define lin4 pin_b7

Pins B6 and B7 are used by the ICD debugger/programmer and you
have your keypad connected to these pins.
You must remove the ICD connector from the board before running
the program.
Andask



Joined: 24 Apr 2009
Posts: 10

View user's profile Send private message

PostPosted: Mon Oct 12, 2009 6:36 pm     Reply with quote

Hmmm.. Right..

The ICD are not connected when I run the program.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 12, 2009 6:39 pm     Reply with quote

Do you have pull-up resistors on the Row pins ? (You can use 10K ohms)
Andask



Joined: 24 Apr 2009
Posts: 10

View user's profile Send private message

PostPosted: Mon Oct 12, 2009 6:40 pm     Reply with quote

I've tried this, the problems still alive.. xD

But I don't remember the value of the resistors, I think it was 4.7K..

I can try with 10K ohms tomorrow...
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 12, 2009 6:43 pm     Reply with quote

My advice is to use the Flex lcd driver and the Flex keypad driver
from the CCS code library.
Andask



Joined: 24 Apr 2009
Posts: 10

View user's profile Send private message

PostPosted: Mon Oct 12, 2009 6:50 pm     Reply with quote

Hmm..

I will try it tomorrow.
Do you think can have something wrong in "my' libs? hm. Rolling Eyes
Andask



Joined: 24 Apr 2009
Posts: 10

View user's profile Send private message

PostPosted: Tue Oct 13, 2009 10:32 am     Reply with quote

Hmm. ok.
I've tried with this, flex_lcd.c and kbd.c.
I din't found the flex_kbd.c só I used the kcd.c provided by the CCS installer.

I have any success too.
Take a look in the simulation:



Code:

#fuses XT,NOWDT,PUT,NOBROWNOUT,NOLVP
#use delay(clock=4000000)

#include "flex_lcd.c"
#include <kbd.c>

void main()
{
   unsigned int c;
   lcd_init();
   kbd_init();
   
   while(TRUE)
   {
      c = kbd_getc();
      lcd_putc(c);
      lcd_putc("??");
   }
}


Code:

// flex_lcd.c

#define LCD_DB4   PIN_D4
#define LCD_DB5   PIN_D5
#define LCD_DB6   PIN_D6
#define LCD_DB7   PIN_D7

#define LCD_E     PIN_D0
#define LCD_RS    PIN_D1
#define LCD_RW    PIN_D2

// If you only want a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line.

#define USE_LCD_RW   1     


Flex driver:
http://www.ccsinfo.com/forum/viewtopic.php?t=24661


Code:

////                  Generic keypad scan driver                       ////
////                                                                   ////
////  kbd_init()   Must be called before any other function.           ////
////                                                                   ////
////  c = kbd_getc(c)  Will return a key value if pressed or /0 if not ////
////                   This function should be called frequently so as ////
////                   not to miss a key press.                        ////
////                                                                   ////
///////////////////////////////////////////////////////////////////////////
////        (C) Copyright 1996,2003 Custom Computer Services           ////


keypad driver:
Quote:
c:\program files\picc\drivers\kbd.c
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Oct 13, 2009 10:39 am     Reply with quote

Quote:
void main()
{
unsigned int c;
lcd_init();
kbd_init();

while(TRUE)
{
c = kbd_getc();
lcd_putc(c);
lcd_putc("??");
}
}

You are not using the CCS keypad driver correctly. It has to be polled
continuosly. Look in this example file to see how to do it:
Quote:
c:\program files\picc\examples\ex_lcdkb.c
Andask



Joined: 24 Apr 2009
Posts: 10

View user's profile Send private message

PostPosted: Tue Oct 13, 2009 1:00 pm     Reply with quote

I checked that error, now my code is looking like this:

Code:
#include <16f877a.h>
#fuses XT,NOWDT,PUT,NOBROWNOUT,NOLVP
#use delay(clock=4000000)

#include "flex_lcd.c"
#include <kbd.c>

void main()
{
   char c;
   lcd_init();
   kbd_init();
   
   while(TRUE)
   {
      c=kbd_getc();
        if(c!=0)
          if(c=='*')
            lcd_putc('\f');
          else
            lcd_putc(c);
   }
}


What occur now is... (In the breadboard)
1) The first column do not work, any button....
2) Sometimes when I press a button, like '5' the LCD show me '55' or '555'....

With a voltmeter I check the voltage of the 3 column's pins and I got this:
Col 1 = 0,13 V
Col 2 = 0,50 V
Col 3 = 0,50 V

The schematic I'm using in the breadboard is this.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Oct 13, 2009 1:16 pm     Reply with quote

Quote:
What occur now is... (In the breadboard)
1) The first column do not work, any button....

Look for a wiring error. Maybe you connected it to the wrong pin,
or maybe there is a solder short.
Andask



Joined: 24 Apr 2009
Posts: 10

View user's profile Send private message

PostPosted: Tue Oct 13, 2009 3:11 pm     Reply with quote

I check the voltage directly in the pin.. x)
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Oct 13, 2009 3:28 pm     Reply with quote

Most of these problems are caused by a bad connection.
Sometimes the threads go on for several pages and in the end,
the person finds a bad connection.

I can't help any more on this. You must work to find the problem.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group