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 support@ccsinfo.com

sorry another kbd.c question

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
homfray



Joined: 19 Nov 2003
Posts: 45
Location: Oxford

View user's profile Send private message Visit poster's website

sorry another kbd.c question
PostPosted: Mon Aug 22, 2005 9:23 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Aug 22, 2005 11:45 am     Reply with quote

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

View user's profile Send private message Visit poster's website

PostPosted: Tue Aug 23, 2005 4:11 am     Reply with quote

Thanks for the reply PCM programmer. Sorry should of kept this a bit more simple instead of baffling everyone Embarassed

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

View user's profile Send private message

PostPosted: Tue Aug 23, 2005 11:59 am     Reply with quote

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








PostPosted: Tue Aug 23, 2005 2:02 pm     Reply with quote

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;
      }

   }
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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