|
|
View previous topic :: View next topic |
Author |
Message |
homfray
Joined: 19 Nov 2003 Posts: 45 Location: Oxford
|
sorry another kbd.c question |
Posted: Mon Aug 22, 2005 9:23 am |
|
|
I have built some electronics using an 18F8621 and a 4x3 keyboard
when I use the following test script it works a treat
kbdTest.c
Code: | #include <18F8621.h>
#device *=16 ADC=8
#define Fosc 40000000
#define WireTX PIN_C7
#define WireRX PIN_C6
#define ConsTX PIN_G1
#define ConsRX PIN_G2
#use delay(clock = Fosc,RESTART_WDT)
#fuses EC_IO, BROWNOUT, BORV20, PUT, STVREN, NOLVP
#use rs232(baud=9600, xmit=WireTX, rcv=WireRX, ERRORS, STREAM=Wireless)
#use rs232(baud=9600, xmit=ConsTX, rcv=ConsRX, ERRORS, STREAM=Console) //Setup RS232
BYTE k;
void main()
{
set_tris_f(0b1111000);
output_bit(PIN_F0,1);
output_bit(PIN_F1,0);
output_bit(PIN_F2,1);
while(true)
{
if (input(PIN_F3)==0)
fprintf(Console,"F3=0\n\r");
else
fprintf(Console,"F3=1\n\r");
if (input(PIN_F4)==0)
fprintf(Console,"F4=0\n\r");
else
fprintf(Console,"F4=1\n\r");
if (input(PIN_F5)==0)
fprintf(Console,"F5=0\n\r");
else
fprintf(Console,"F5=1\n\r");
if (input(PIN_F6)==0)
fprintf(Console,"F6=0\n\r\n\r");
else
fprintf(Console,"F6=1\n\r\n\r");
delay_ms(5000);
}
} |
when I use a modified kbd script nothing happens although I know it calls kbd as I can stick stuff in the return and change the output. It will be something I have missed I am sure but another pair opf eyes on it would be appreciated
KBDBuzband.c
Code: | //based on KBD.C
#byte kbd = 0xF85 // Port F on 18F452
#define set_tris_kbd(x) set_tris_f(x)
#define Bitmask(x) (1 << (x & 7))
// These statements define the connections between the keypad
// pins and the PIC pins. For example, the column 0 pin on the
// keypad connector goes to pin B2 on the PIC. If you change
// the wiring on your board, then you must also change the
// definitions below to match your board. I have used the
// Bitmask() macro in the following statements because I think
// it makes the connections easier to understand, compared to
// the way CCS does it in their driver.
#define COL0 Bitmask(PIN_F0)
#define COL1 Bitmask(PIN_F1)
#define COL2 Bitmask(PIN_F2)
#define ROW0 Bitmask(PIN_F6)
#define ROW1 Bitmask(PIN_F5)
#define ROW2 Bitmask(PIN_F4)
#define ROW3 Bitmask(PIN_F3)
#define ALL_ROWS (ROW0|ROW1|ROW2|ROW3)
#define ALL_COLS (COL0|COL1|COL2)
#define ALL_PINS (ALL_ROWS|ALL_COLS)
// Keypad layout:
char const KEYS[4][3] = {{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}};
// Set this number to apx n/333 where
// n is the number of times you expect
// to call kbd_getc each second.
#define KBD_DEBOUNCE_FACTOR 33
void kbd_init()
{
}
char kbd_getc( )
{
static BYTE kbd_call_count;
static short int kbd_down;
static char last_key;
static BYTE col;
BYTE kchar;
BYTE row;
kchar='\0';
if(++kbd_call_count>KBD_DEBOUNCE_FACTOR)
{
switch (col)
{
case 0 : set_tris_kbd(ALL_COLS&~COL0);
kbd=~COL0&ALL_COLS;
break;
case 1 : set_tris_kbd(ALL_COLS&~COL1);
kbd=~COL1&ALL_COLS;
break;
case 2 : set_tris_kbd(ALL_COLS&~COL2);
kbd=~COL2&ALL_COLS;
break;
}
if(kbd_down)
{
if((kbd & (ALL_ROWS))==(ALL_ROWS))
{
kbd_down=FALSE;
kchar=last_key;
last_key='\0';
}
}
else
{
if((kbd & (ALL_ROWS))!=(ALL_ROWS))
{
if((kbd & ROW0)==0)
row=0;
else if((kbd & ROW1)==0)
row=1;
else if((kbd & ROW2)==0)
row=2;
else if((kbd & ROW3)==0)
row=3;
last_key =KEYS[row][col];
kbd_down = TRUE;
}
else
{
++col;
if(col==3)
col=0;
}
}
kbd_call_count=0;
}
set_tris_kbd(ALL_PINS);
return(kchar);
// return('A');
} |
kbdMain.c
Code: | #include <18F8621.h>
#device *=16 ADC=8
#include <KBDBuzband.c>
#define Fosc 40000000
#define WireTX PIN_C7
#define WireRX PIN_C6
#define ConsTX PIN_G1
#define ConsRX PIN_G2
#use delay(clock = Fosc,RESTART_WDT)
#fuses EC_IO, BROWNOUT, BORV20, PUT, STVREN, NOLVP
#use rs232(baud=9600, xmit=WireTX, rcv=WireRX, ERRORS, STREAM=Wireless)
#use rs232(baud=9600, xmit=ConsTX, rcv=ConsRX, ERRORS, STREAM=Console) //Setup RS232
BYTE k;
void main()
{
while(true)
k=kbd_getc();
fprintf(Console,"%c\n\r",k);
delay_ms(500);
}
} |
anything stupid there???? _________________ Nice!!! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Aug 22, 2005 11:45 am |
|
|
There are several things wrong with your code.
If you look in the c:\Program Files\Picc\Examples folder, you will
see this file: EX_LCDKB.C
That file shows how to call the CCS keypad driver.
You must check to see if the return value is non-zero.
Here's the code, with the LCD stuff edited out, and modified
to use the serial port instead of the LCD. This is what you
should be doing:
Code: | void main()
{
char k;
kbd_init();
while(1)
{
k = kbd_getc();
if(k != 0)
if(k == '*')
printf("\n\r");
else
putc(k);
}
} |
In addition to that, you must have pull-up resistors on the Row pins
of the keypad. You can use four 10K resistors on pins F3, F4, F5, and F6.
Also you have a problem here:
Quote: | #define WireTX PIN_C7
#define WireRX PIN_C6 |
You have Tx and Rx reversed. By doing so, you will create a software
UART on those pins. The compiler won't use the hardware UART.
See the 18F6621 data sheet for the pin diagram. |
|
|
homfray
Joined: 19 Nov 2003 Posts: 45 Location: Oxford
|
|
Posted: Tue Aug 23, 2005 4:11 am |
|
|
Thanks for the reply PCM programmer. Sorry should of kept this a bit more simple instead of baffling everyone
The Tx and Rx is not reversed just a typo on my part from now on will move the actual script across and stop just typing it out.
Have the pull ups on row pins which is F6 (Row 1), F5 (Row 2), F4 (Row 1) and, F3 (Row 4). Discovered this problem all by myself earlier when nothing at all was happening with my keypad!!
to keep things simple I have directly used the main program as instructed and copied kbd.c and made a few changes for port F. I get exactly the same problem. the return from kbd.c is always 0 and therefore no output with any button press. I know I am calling kbd.c because when I simply return a character from kbd.c, my main program reads the non 0 value and puts it out to the screen.
What do we think guru's any suggestions???
KBD.c
Code: | #byte kbd = 0xF85 // This puts the entire structure
#define set_tris_kbd(x) set_tris_f(x)
//Keypad connection:
//
#define COL0 (1 << 1)
#define COL1 (1 << 2)
#define COL2 (1 << 3)
#define ROW0 (1 << 7)
#define ROW1 (1 << 6)
#define ROW2 (1 << 5)
#define ROW3 (1 << 4)
#define ALL_ROWS (ROW0|ROW1|ROW2|ROW3)
#define ALL_PINS (ALL_ROWS|COL0|COL1|COL2)
// Keypad layout:
char const KEYS[4][3] = {{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}};
#define KBD_DEBOUNCE_FACTOR 33 // Set this number to apx n/333 where
// n is the number of times you expect
// to call kbd_getc each second
void kbd_init() {
}
char kbd_getc( ) {
static BYTE kbd_call_count;
static short int kbd_down;
static char last_key;
static BYTE col;
BYTE kchar;
BYTE row;
kchar='\0';
if(++kbd_call_count>KBD_DEBOUNCE_FACTOR) {
switch (col) {
case 0 : set_tris_kbd(ALL_PINS&~COL0);
kbd=~COL0&ALL_PINS;
break;
case 1 : set_tris_kbd(ALL_PINS&~COL1);
kbd=~COL1&ALL_PINS;
break;
case 2 : set_tris_kbd(ALL_PINS&~COL2);
kbd=~COL2&ALL_PINS;
break;
}
if(kbd_down) {
if((kbd & (ALL_ROWS))==(ALL_ROWS)) {
kbd_down=FALSE;
kchar=last_key;
last_key='\0';
}
} else {
if((kbd & (ALL_ROWS))!=(ALL_ROWS)) {
if((kbd & ROW0)==0)
row=0;
else if((kbd & ROW1)==0)
row=1;
else if((kbd & ROW2)==0)
row=2;
else if((kbd & ROW3)==0)
row=3;
last_key =KEYS[row][col];
kbd_down = TRUE;
} else {
++col;
if(col==3)
col=0;
}
}
kbd_call_count=0;
}
set_tris_kbd(ALL_PINS);
return(kchar);
//return('A'); //to see if it returns anything
} |
NewTest.c
Code: | #include <18F8621.h>
#device *=16 ADC=8
#include <KBD.c>
#define Fosc 40000000
#define WireTX PIN_C6
#define WireRX PIN_C7
#define ConsTX PIN_G1
#define ConsRX PIN_G2
#use delay(clock = Fosc,RESTART_WDT)
#fuses EC_IO, BROWNOUT, BORV20, PUT, STVREN, NOLVP
#use rs232(baud=9600, xmit=WireTX, rcv=WireRX, ERRORS, STREAM=Wireless)
#use rs232(baud=9600, xmit=ConsTX, rcv=ConsRX, ERRORS, STREAM=Console) //Setup RS232
void main()
{
char k;
kbd_init();
fprintf(Wireless,"Starting\n\r\n\r");
while(1)
{
k=kbd_getc();
if(k !=0)
if(k=='*')
fprintf(Wireless,"its a star\n\r");
else
fputc(k,Wireless);
delay_ms(500);
}
} |
_________________ Nice!!! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Aug 23, 2005 11:59 am |
|
|
The two methods that you're using to make the bitmasks are different.
Code: |
#define Bitmask(x) (1 << (x & 7))
#define COL0 Bitmask(PIN_F0)
#define COL1 Bitmask(PIN_F1)
#define COL2 Bitmask(PIN_F2)
#define ROW0 Bitmask(PIN_F6)
#define ROW1 Bitmask(PIN_F5)
#define ROW2 Bitmask(PIN_F4)
#define ROW3 Bitmask(PIN_F3)
|
Code: |
#define COL0 (1 << 1)
#define COL1 (1 << 2)
#define COL2 (1 << 3)
#define ROW0 (1 << 7)
#define ROW1 (1 << 6)
#define ROW2 (1 << 5)
#define ROW3 (1 << 4)
|
The first method will produce these bitmasks:
0x01
0x02
0x04
0x40
0x20
0x10
0x08
The 2nd method will make these bitmasks:
0x02
0x04
0x08
0x80
0x40
0x20
0x10
The 2nd method produces bitmasks that are shifted one bit to
the left, compared to the first method.
The bitmasks are critical for the proper operation of the keypad driver.
Are you sure that the bitmasks you're using (either set) are correct
for your keypad and for the wiring connections between it and the PIC ?
Who is the manufacturer of your keypad and what is the part number ?
Can you post a link to the data sheet ?
Can you post a list of the connections between your keypad and the
pins on the PIC ? |
|
|
Guest
|
|
Posted: Tue Aug 23, 2005 2:02 pm |
|
|
the pdf for the keypad can be found at www.substation23.net/4200.pdf
the PIC pinout is
COL0 PIN_F0
COL1 PIN_F1
COL2 PIN_F2
ROW0 PIN_F3
ROW1 PIN_F4
ROW2 PIN_F5
ROW3 PIN_F6
Worried that I could not get this code working I have written my own and it is working fine
here it is
Code: |
#include <18F8621.h>
#device *=16 ADC=8
#define Fosc 40000000
#define WireTX PIN_C6
#define WireRX PIN_C7
#define ConsTX PIN_G1
#define ConsRX PIN_G2
#use delay(clock = Fosc,RESTART_WDT)
#fuses EC_IO, BROWNOUT, BORV20, PUT, STVREN, NOLVP
#use rs232(baud=9600, xmit=WireTX, rcv=WireRX, ERRORS, STREAM=Wireless)
#use rs232(baud=9600, xmit=ConsTX, rcv=ConsRX, ERRORS, STREAM=Console) //Setup RS232
int change=0;
int outcome;
static short btnFlag;
// Keypad layout:
char const UnitName[12] =
{
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L'
};
char const DataName[1] =
{
'1'
};
void main()
{
set_tris_f(0b1111000);
btnFlag = FALSE;
while(true)
{
if (btnFlag==FALSE)
{
if (change==0)
{
output_bit(PIN_F0,0);
output_bit(PIN_F1,1);
output_bit(PIN_F2,1);
btnFlag=TRUE;
if (input(PIN_F3)==0)
outcome=1;
else if (input(PIN_F4)==0)
outcome=4;
else if (input(PIN_F5)==0)
outcome=7;
else if (input(PIN_F6)==0)
outcome=10;
else
btnFlag=FALSE;
}
else if (change==1)
{
output_bit(PIN_F0,1);
output_bit(PIN_F1,0);
output_bit(PIN_F2,1);
btnFlag=TRUE;
if (input(PIN_F3)==0)
outcome=2;
else if (input(PIN_F4)==0)
outcome=5;
else if (input(PIN_F5)==0)
outcome=8;
else if (input(PIN_F6)==0)
outcome=11;
else
btnFlag=FALSE;
}
else if (change==2)
{
output_bit(PIN_F0,1);
output_bit(PIN_F1,1);
output_bit(PIN_F2,0);
btnFlag=TRUE;
if (input(PIN_F3)==0)
outcome=3;
else if (input(PIN_F4)==0)
outcome=6;
else if (input(PIN_F5)==0)
outcome=9;
else if (input(PIN_F6)==0)
outcome=12;
else
btnFlag=FALSE;
}
change++;
if (change==3)
change=0;
}
else
{
delay_ms(500);
fprintf(Wireless, "%c", 0xBA); // LAM - something for the RX's USART to "lock onto"
fprintf(Wireless, "%c", 0xBE); // LAM - something for the RX's USART to "lock onto"
fprintf(Wireless, "%c", 0xFA); // LAM - something for the RX's USART to "lock onto"
fprintf(Wireless, "%c", 0xCE); // LAM - something for the RX's USART to "lock onto"
fprintf(Wireless,"%c%c%c%cBUZ%c\r",UnitName[outcome-1],UnitName[outcome-1],UnitName[outcome-1],UnitName[outcome-1],DataName[0]);
btnFlag=FALSE;
}
}
} |
|
|
|
|
|
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
|