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

Is there a significantly faster way to do this ??

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



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

Is there a significantly faster way to do this ??
PostPosted: Fri Jul 13, 2012 10:47 am     Reply with quote

The function is the core of an 8x8 matrix key press detector.
it works and seems fast enough. But can it be done a whole lot better?

Code:

// on entry Port D is all output, pulled high for gross keydown detection
// port B is pulled DOWN by 10K x8 and is the receive side of the key mtx
// at least one matrix closure was detected  by the calling routine.   
// OK[64] is a byte matrix that holds the character we want to output
// holdoff   &&  repeats,   etc handled externally

void decode88(void){  // ** decode and OUTPUT one or more keys pressed
     byte work;
     unsigned int8 i,j,r=1;

    for (i=0; i<8; i++){ // now select one row at a time
     output_d(r);
     delay_us(10);     // for TTelmah - ;-))
     work=input_b();
     if (0!=work){ // found closure on this row
       for (j=0; j<8; j++){ // now which column ?
         if( bit_test(work,j)){ // closure on this column 
              putc(ok[((8*i)+j)];
         }             // if bitsy
       }               // j loop
     }                 // end WORK
     r =r*2;           // shift row bit
   }                  //for i
   output_d(255);  // raise  all lines for next detect
}
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Fri Jul 13, 2012 2:54 pm     Reply with quote

Two things stand out to be relative slow:
1) The 10us delay, why is it there? Do some calculations and most likely you can use a shorter delay, possibly after decreasing the 10k resistors.
2) The putc is dangerous. The UART can only buffer 1 character and will stall for a relative long time when data is already waiting to be sent. Much better to use the well known interrupt driven transmit buffer from the ex_stisr example.
temtronic



Joined: 01 Jul 2010
Posts: 9216
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Fri Jul 13, 2012 2:58 pm     Reply with quote

Without seeing the listing....

r =r*2; // shift row bit

might be better done using the 'shift' function ??

also.... be sure to figure out the 'debounce' requirement...
Ttelmah



Joined: 11 Mar 2010
Posts: 19480

View user's profile Send private message

PostPosted: Sat Jul 14, 2012 4:13 am     Reply with quote

The compiler will optimise a fixed *2, to a shift, so makes no difference.

On the delay, 10uSec is 'long', even with 10K resistors. The value needed is going to depend on the total capacitance of the lines, and the resistances of the switches themselves, but I'd have guess a uSec or two would have been enough.

The putc, is worse than 'dangerous'. As it stands, assuming 9600bps, you could be stuck inside the routine for over 60mSec, if all the switches were made!.... Agree wholeheartedly - buffer.

I have to say 'why' have the block testing outside the routine?. To my mind, tidier, to have this routine start by outputting 255, and immediately test and return if input_b==0.

The routine also makes no attempt to ignore keys that are 'held', so will keep being called, and keep delaying for putc when this happens....

Best Wishes
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Sat Jul 14, 2012 9:23 am     Reply with quote

Thanks for excellent tips:

1- Baud is 115200 using FTDI to USB interface, inter-key dead band is 100msec typical - 'holdoff' timing is external too. I only showed the core decoder - which is called with external timing control so as not to repeat when not valid initially or timed out - I also omitted the assignment of output char to BYTE curkey as not being relevant to the routine's basic efficiency.

2- The routine is never called in the first place unless a read of port b comes up with !=0 using portd= 255 - thats why the routine must end with portd =255

3- I considered bugging out of the loops with a return as soon as any code is detected by row scan of port d but left it as it is to detect multiple keys being pressed - THAT is the main area of uncertainty I was hoping to optimize, but saw no clear way to do it.

4- 10us was safely longer than needed as I could see bounce port b pins
with 18" cable to pic and is 10x longer than I need - shorter than 1 us
delay gave the odd bad code output.

5- Being a printed carbon matrix with 500 ohms or more closed - 10k was judged a safe enough load to allow for deterioration after many many presses of lifetime activity.
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