View previous topic :: View next topic |
Author |
Message |
Athar Rasul
Joined: 19 Mar 2010 Posts: 13
|
Problem with compiling lcd.c and kbd.c |
Posted: Fri Mar 19, 2010 5:58 am |
|
|
I am using PIC16F877A to interface 2x16 LCD and 4x3 keypad. Problem might be silly but whenever I try to compile the standard drivers for these, following errors occur:
*** Error 128 "KBD.C" Line 37(5,9): A #DEVICE required before this line
*** Error 128 "LCD.C" Line 41(1,1): A #DEVICE required before this line |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 19, 2010 9:44 am |
|
|
They are driver files. They are not stand-alone programs. They are
required to be included in a larger program. This is done with #include
statements. See this CCS example file, which shows how to do it:
Quote: |
c:\program files\picc\examples\ex_lcdkb.c
|
|
|
|
Athar Rasul
Joined: 19 Mar 2010 Posts: 13
|
|
Posted: Fri Mar 19, 2010 1:23 pm |
|
|
I know that these files are to be included in the main program. Here is the complete code:
Code: |
#include <16F877A.h>
#device ADC = 8 // 8-bit conversion
#use delay(clock = 16000000)
#use rs232(UART1) // Select hardware UART
#include <LCD.C>
#include <KBD.C>
void main(){
setup_uart(9600); // Set baud rate
setup_adc(ADC_CLOCK_INTERNAL); // ADC clock
setup_adc_ports(AN0); // Input combination
set_adc_channel(0); // Select RA0
int key;
delay_ms(100);
while(1){
delay_ms(500);
key=kbd_getc();
lcd_putc(key);
}
} |
here are driver files:
Code: |
///////////////////////////////////////////////////////////////////////////
//// KBDD.C ////
//// Generic keypad scan driver ////
|
Code: |
///////////////////////////////////////////////////////////////////////////
//// LCDD.C ////
//// Driver for common LCD modules ////
|
I've connected keypad to port B (pull up resistors for rows) and lcd with port D(in 4-bit mode). I also tried the example file but it also gave the same error during compilation. Also please tell me how to use AN0 and AN1 as analog inputs while setting rest (AN2-AN7) as digital. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 19, 2010 1:55 pm |
|
|
Are you compiling this in MPLAB ? If so, don't add lcd.c and kbd.c to
the project. The only source file that should be "added to the Project"
is Ex_lcdkb.c, as shown in the MPLAB Project Window below:
Code: |
Ex_lcdkb.mcp
- Source Files
- Ex_lcdkb.c
-Header Files
- 16F877.h
-Other Files
|
If you added lcd.c and kbd.c to the project, they will appear in the
source files list above. Right-click on each file and Remove it.
Only Ex_lcdkb.c should be in the list.
Quote: |
Also please tell me how to use AN0 and AN1 as analog inputs while
setting rest (AN2-AN7) as digital.
|
You can't do it with the 16F877. You can only use the pre-selected sets
of Analog pins that are listed in the 16F877 data sheet, and in the
16F877.h file. The nearest possible setting to the one that you want
is with AN0, AN1, and AN3 as analog. Example:
Code: |
setup_adc_ports(AN0_AN1_AN3);
|
If you want more flexibility, then choose a more modern PIC, such as
the 16F887. It can select individual Analog pins in any combination. |
|
|
Athar Rasul
Joined: 19 Mar 2010 Posts: 13
|
|
Posted: Fri Mar 19, 2010 2:45 pm |
|
|
That solved my problem. Thanks a lot. About the analog pins; I think I'll go for the three pins but I was wondering is it possible to setup the adc ports and adc channel alternatively for the two inputs? like:
while(1){
setup_adc_ports(AN0);
set_adc_channel(0); // Select RA0
............
...........
...........
...........
setup_adc_ports(AN1);
set_adc_channel(1); // Select RA1
...........
...........
} |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 19, 2010 3:07 pm |
|
|
Read my previous post:
Quote: |
You can't do it with the 16F877. You can only use the pre-selected sets
of Analog pins that are listed in the 16F877 data sheet, and in the
16F877.h file.
|
My advice is, buy a 16F887. Then you can do anything you want with
the analog pins. You will be much happier. |
|
|
Athar Rasul
Joined: 19 Mar 2010 Posts: 13
|
|
Posted: Fri Mar 19, 2010 4:07 pm |
|
|
That doesn't bother me. I'm happier still... Thank you for your cooperation. |
|
|
Athar Rasul
Joined: 19 Mar 2010 Posts: 13
|
|
Posted: Fri Mar 19, 2010 4:10 pm |
|
|
Sorry to bother you again but how can I make the keypad wait for the input once called? instead of having to call it a million times. Also can I send commands to lcd like hiding the cursor (0x0C) etc? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Mar 19, 2010 4:20 pm |
|
|
Create a routine that waits for a keypress and then call it.
Example:
Code: |
#include <16F877.H>
#fuses XT, NOWDT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#include "flex_lcd.c"
#include "flex_kbd.c"
// Wait for a key on the keypad to be pressed. Then return it.
char wait_kbd_getc(void)
{
char retval;
while(1)
{
retval = kbd_getc();
if(retval)
return(retval);
delay_ms(10);
}
}
//======================
void main()
{
char k;
lcd_init();
kbd_init();
while(1)
{
k = wait_kbd_getc(); // Wait for a key press
printf(lcd_putc, "\fKey = %c", k); // Display it on LCD
}
} |
|
|
|
Athar Rasul
Joined: 19 Mar 2010 Posts: 13
|
|
Posted: Sat Mar 20, 2010 4:12 am |
|
|
I know this shouldn't be happening but now I have to press the keys for quite some time, otherwise they aren't detected. And what about sending control commands to lcd. How can I do that? |
|
|
Athar Rasul
Joined: 19 Mar 2010 Posts: 13
|
|
Posted: Sat Mar 20, 2010 5:20 am |
|
|
Also please tell me can I call "wait_kbd_getc(void)" routine from some other routine? (other than main())? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Mar 20, 2010 11:05 am |
|
|
Quote: |
Now I have to press the keys for quite some time, otherwise they aren't detected.
|
Get creative. Try reducing the debounce period. Reduce it from 10ms to 5ms. Experiment.
Quote: |
Can I call "wait_kbd_getc(void)" routine from some other routine?
|
Don't ask my permission. Just try it. |
|
|
Athar Rasul
Joined: 19 Mar 2010 Posts: 13
|
|
Posted: Sat Mar 20, 2010 1:31 pm |
|
|
Code: | #include <16F877A.h>
#device ADC = 8 // 8-bit conversion
#use delay(clock = 16000000)
#use rs232(UART1) // Select hardware UART
#include <lcd.c>
#include <kbd.c>
char wait_kbd_getc(void);
int input();
int selection;
void main(){
int tin,degc[3],degf[3],key,temp_t,level_t,in; // Input variable
long tf;
set_tris_d(0); //Made Port D Output port (to use with in main function)
set_tris_e(0); //Made Port C output port (to use with outer function)
setup_uart(9600); // Set baud rate
setup_adc(ADC_CLOCK_INTERNAL); // ADC clock
setup_adc_ports(AN0_AN1_AN3); // Input combination
set_adc_channel(0); // Select RA0
delay_ms(100);
lcd_init();
kbd_init();
while(1){
delay_ms(500);
if(!input(PIN_B0)){
in=input();
if(in!=0 & selection==1){
temp_t=in; printf("New Temp Thresh is %c",temp_t);delay_ms(1000);
}
if(in!=0 & selection==2){
level_t=in; printf("New Level Thresh is %c",level_t);delay_ms(1000);
}
}
tin=read_adc();
tin=tin/1.7; //digital to temperature value
tf=(tin*1.8)+32;
degc[2]= tin%10+'0';
degc[1]= (tin/10)%10+'0';
degc[0]= (tin/100)%10+'0';
degf[2]= tf%10+'0';
degf[1]= (tf/10)%10+'0';
degf[0]= (tf/100)%10+'0';
lcd_putc("\fTEMP:");
printf("Temperature is ");
if(degc[0]!='0'){
putc(degc[0]);
lcd_putc(degc[0]); goto skip;
}
if(degc[1]!='0'){
skip: putc(degc[1]);
lcd_putc(degc[1]);
}
putc(degc[2]);putc(0xDF);
printf(lcd_putc, "%c%cC/",degc[2],0xDF); // Display it on LCD
printf("C or ");
if(degf[0]!='0'){
putc(degf[0]);
lcd_putc(degf[0]);
}
putc(degf[1]);
lcd_putc(degf[1]);
putc(degf[2]);putc(0xDF);
printf(lcd_putc, "%c%cF",degf[2],0xDF); // Display it on LCD
printf("F.");
putc(13);
}
}
// Wait for a key on the keypad to be pressed. Then return it.
char wait_kbd_getc(void){
char retval;
while(1){
retval = kbd_getc();
if(retval)
return(retval);
delay_ms(1);
}
}
input(){
int key,input;
start_input: lcd_putc("\f1:Temp Thresh.\n2:Level Thresh.");
key=wait_kbd_getc();
switch(key){
case 1: selection=1; lcd_putc("\fSet Temp(0-150)\n"); goto start_temp;
case 2: selection=2; lcd_putc("\rSet Level(0-100)\n"); goto start_level;
case '#': input=0; goto end_input;
default: goto start_input;
}
start_temp: key=wait_kbd_getc();
switch(key){
case '*': if(input>150){lcd_putc("\fOut of range...");
delay_ms(1000);input=0; lcd_putc("\fSet Temp(0-150)\n");
goto start_temp;}
else return(input);goto end_input;
case '#': input=0; goto start_input;
default: input=(input*10)+key; lcd_putc(key); goto start_temp;
}
start_level: key=wait_kbd_getc();
switch(key){
case '*': if(input>100){lcd_putc("\fOut of range...");
delay_ms(1000);input=0; lcd_putc("\fSet Level(0-100)\n");
goto start_level;}
else return(input);goto end_input;
case '#': input=0; goto start_input;
default: input=(input*10)+key; lcd_putc(key); goto start_level;
}
input=0;
return(input);
end_input:
} | [/code]
Last edited by Athar Rasul on Sat Mar 20, 2010 2:43 pm; edited 2 times in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Mar 20, 2010 2:10 pm |
|
|
I have no idea where lines 32 and 117 are in your code. I am not a
mind reader. I suggest that you read the CCS manual and look at
the correct syntax for whatever lines are causing the problem. Also
look at the code for a few lines above the error line. Sometimes the
compiler generates an error in later lines, if you are missing a brace
or some other syntax error.
In other words, don't depend on me to solve your problems.
Learn how to trouble-shoot the problem by using your own mind. |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Sat Mar 20, 2010 2:25 pm |
|
|
You cannot re-declare the function input().
How do expect the compiler to know what you mean here?
_________________ Google and Forum Search are some of your best tools!!!! |
|
|
|