Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
07/05/03 00:36
Read: times


 
#50090 - RE: 16-bit keyscan to 4-bit
Responding to: ???'s previous message
I looked over the code sample that you posted Javier. The code itself is pretty straightforward. There are however certain technigues that can be used in the C coding to make the resulting assembler language as efficient as possible. I happen to use Keil C-51 and know some of the optimizations that the compiler is able to perform. So I re-wrote your algorithm a bit. The main focus was to reduce the number of local variables and number of data manipulations required per loop. (Note that another code structure may be better for other C compilers).

Here is the C code I put together....

#pragma SRC

unsigned int ScanKey(void)   /* test case to provide */
{                            /* compilability */
	return(0x0002);
}

unsigned char ScanKeySingle(void) 
{ 
	unsigned int key16;
	unsigned char key8 = 16;

	/* get the key scan vector */
	key16 = ScanKey();

	/* exit early if no keys active */
	if(key16 == 0x0000)
	{
		return(0x80);			/* show no key */
	}			

	/* scan the 16 bit key vector with 1's for keys pressed */
	do
	{
		if(key16 & 0x8000)		/* if a key vector bit is set */
		{
			if(key16 & 0x7FFF)	/* if another bit is set */
			{
				/* show multiple key pressed */
				return(0x10);	
			}
			else
			{
				/* singular key found */
				return(--key8);
			}
		}

		key16 <<= 1;			/* shift the key bits left */

	} while(--key8);

	/* default exit for no kwy pressed */
	return(0x80);				/* Note that code never will get here */
} 								/* due to the early exit check at beginning */


Here is the assembler language listing of the Keil C compiler output.


; testc.SRC generated from: testc.c
; COMPILER INVOKED BY:
;        C:KeilC51BINC51.EXE testc.c BROWSE DEBUG OBJECTEXTEND


NAME	TESTC

?PR?ScanKey?TESTC    SEGMENT CODE 
?PR?ScanKeySingle?TESTC                  SEGMENT CODE 
	PUBLIC	ScanKeySingle
	PUBLIC	ScanKey
; #pragma SRC
; 
; unsigned int ScanKey(void)   /* test case to provide */

	RSEG  ?PR?ScanKey?TESTC
ScanKey:
	USING	0
			; SOURCE LINE # 3
; {                            /* compilability */
			; SOURCE LINE # 4
; 	return(0x0002);
			; SOURCE LINE # 5
	MOV  	R6,#00H
	MOV  	R7,#02H
; }
			; SOURCE LINE # 6
?C0001:
	RET  	
; END OF ScanKey

; 
; unsigned char ScanKeySingle(void) 

	RSEG  ?PR?ScanKeySingle?TESTC
ScanKeySingle:
	USING	0
			; SOURCE LINE # 8
; { 
			; SOURCE LINE # 9
; 	unsigned int key16;
; 	unsigned char key8 = 16;
			; SOURCE LINE # 11
;---- Variable 'key8?141' assigned to Register 'R5' ----
	MOV  	R5,#010H
; 
; 	/* get the key scan vector */
; 	key16 = ScanKey();
			; SOURCE LINE # 14
	LCALL	ScanKey
;---- Variable 'key16?140' assigned to Register 'R6/R7' ----
; 
; 	/* exit early if no keys active */
; 	if(key16 == 0x0000)
			; SOURCE LINE # 17
	MOV  	A,R7
	ORL  	A,R6
	JNZ  	?C0006
; 	{
			; SOURCE LINE # 18
; 		return(0x80);			/* show no key */
			; SOURCE LINE # 19
	MOV  	R7,#080H
	RET  	
; 	}			
			; SOURCE LINE # 20
?C0006:
; 
; 	/* scan the 16 bit key vector with 1's for keys pressed */
; 	do
; 	{
			; SOURCE LINE # 24
; 		if(key16 & 0x8000)		/* if a key vector bit is set */
			; SOURCE LINE # 25
	MOV  	A,R6
	JNB  	ACC.7,?C0007
; 		{
			; SOURCE LINE # 26
; 			if(key16 & 0x7FFF)	/* if another bit is set */
			; SOURCE LINE # 27
	ANL  	A,#07FH
	ORL  	A,R7
	JZ   	?C0008
; 			{
			; SOURCE LINE # 28
; 				/* show multiple key pressed */
; 				return(0x10);	
			; SOURCE LINE # 30
	MOV  	R7,#010H
	RET  	
; 			}
			; SOURCE LINE # 31
?C0008:
; 			else
; 			{
			; SOURCE LINE # 33
; 				/* singular key found */
; 				return(--key8);
			; SOURCE LINE # 35
	DEC  	R5
	MOV  	R7,AR5
	RET  	
; 			}
			; SOURCE LINE # 36
; 		}
			; SOURCE LINE # 37
?C0007:
; 
; 		key16 <<= 1;			/* shift the key bits left */
			; SOURCE LINE # 39
	MOV  	A,R7
	ADD  	A,ACC
	MOV  	R7,A
	MOV  	A,R6
	RLC  	A
	MOV  	R6,A
; 
; 	} while(--key8);
			; SOURCE LINE # 41
	DJNZ 	R5,?C0006
; 
; 	/* default exit for no kwy pressed */
; 	return(0x80);				/* Note that code never will get here */
			; SOURCE LINE # 44
	MOV  	R7,#080H
; } 								/* due to the early exit check at beginning */
			; SOURCE LINE # 45
?C0003:
	RET  	
; END OF ScanKeySingle

	END



As you can see one would be hard pressed to write hand coded assembler that would be much more efficient.

Have Fun
Michael Karas


List of 6 messages in thread
TopicAuthorDate
16-bit keyscan to 4-bit            01/01/70 00:00      
   RE: 16-bit keyscan to 4-bit            01/01/70 00:00      
   RE: 16-bit keyscan to 4-bit            01/01/70 00:00      
   RE: 16-bit keyscan to 4-bit            01/01/70 00:00      
   RE: 16-bit keyscan to 4-bit            01/01/70 00:00      
      RE: 16-bit keyscan to 4-bit            01/01/70 00:00      

Back to Subject List