|
|
View previous topic :: View next topic |
Author |
Message |
Andask
Joined: 24 Apr 2009 Posts: 10
|
Problem with 877A and CCS. |
Posted: Mon Oct 12, 2009 2:00 pm |
|
|
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
|
|
Posted: Mon Oct 12, 2009 2:12 pm |
|
|
Quote: | when you step into the proto-board, the trouble starts. |
Describe the trouble. |
|
|
Andask
Joined: 24 Apr 2009 Posts: 10
|
|
Posted: Mon Oct 12, 2009 2:16 pm |
|
|
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
|
|
Posted: Mon Oct 12, 2009 6:20 pm |
|
|
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
|
|
Posted: Mon Oct 12, 2009 6:36 pm |
|
|
Hmmm.. Right..
The ICD are not connected when I run the program. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Oct 12, 2009 6:39 pm |
|
|
Do you have pull-up resistors on the Row pins ? (You can use 10K ohms) |
|
|
Andask
Joined: 24 Apr 2009 Posts: 10
|
|
Posted: Mon Oct 12, 2009 6:40 pm |
|
|
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
|
|
Posted: Mon Oct 12, 2009 6:43 pm |
|
|
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
|
|
Posted: Mon Oct 12, 2009 6:50 pm |
|
|
Hmm..
I will try it tomorrow.
Do you think can have something wrong in "my' libs? hm. |
|
|
Andask
Joined: 24 Apr 2009 Posts: 10
|
|
Posted: Tue Oct 13, 2009 10:32 am |
|
|
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
|
|
Posted: Tue Oct 13, 2009 10:39 am |
|
|
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
|
|
Posted: Tue Oct 13, 2009 1:00 pm |
|
|
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
|
|
Posted: Tue Oct 13, 2009 1:16 pm |
|
|
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
|
|
Posted: Tue Oct 13, 2009 3:11 pm |
|
|
I check the voltage directly in the pin.. x) |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Oct 13, 2009 3:28 pm |
|
|
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. |
|
|
|
|
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
|