File "KEYLCD-D.C"

Full Path: /home/analogde/www/private/Projet/Example/HC11/KEYLCD-D.C
File size: 4.38 KB
MIME-type: text/x-c
Charset: utf-8

/* Simple program to test CMD11 LCD and AUX keypad.
   Key's pressed are displayed on the LCD */

/*  NOTE:  This version does not debounce keys, you can do that with a flag check */

/* Define where things should reside... */
#define REG_BASE 0xB000
#data    0x2000
#code    0x2100

#include <68hc11.h>
#include <stdio.h>

/* I/O Port definitions */
#define AUX_CON	0xB5F7		/* Aux Control Register */
#define AUX_C	0xB5F6		/* Aux Port A Register */
#define AUX_B	0xB5F5		/* Aux Port A Register */
#define AUX_A	0xB5F4		/* Aux Port A Register */

#define LCD_DATA 0xB5F1      /* LCD Data Register */
#define LCD_CMD  0xB5F0      /* LCD Command Register */

/* Variables */
char keybuf;	/* index variable for key scan */
char keychar;
char testval;
char rcnt;


/* main loop */
void main(){

	pokeb(REG_BASE+DDRD,0x3F);	/* set D data direction register */
/*	pokeb(REG_BASE+DDRA,0xF0); */

	/* Initialize the LCD */
    LCD_Command(0x3C);                 /* initialize command */
    LCD_Command(0x0C);                 /* display on, cursor off */
    LCD_Command(0x06);
    LCD_Command(0x01);

    LCDprint("Press any key: ");
	for( ; ;){
		keychar = getkey();
		cprint(keychar);
	}
}


/*  Busy wait loop to generate a delay multiple of 1ms                */
#define DELAY1MS	73		/* number of loops = 1ms*/

void delay1ms(msecs)
unsigned int msecs;
{
  unsigned int i,j;

  if (msecs > 0) {
     for (j=0; j<=msecs; j++)
        for (i=0; i<DELAY1MS; i++);
  }
  return;
}

/* initialize keyports, prepare for keyscan */
void InitKey(){
	pokeb(AUX_CON,0x8B);	/* cycle port*/
	pokeb(AUX_A,0xFF);		/* force A high*/
	pokeb(AUX_CON,0x93);	/* AUX PortC 4-7 = Out, AUX PortA = IN*/
	pokeb(AUX_C,0xFF);		/* Key columns High on Port C*/
}

void scancol(colval)
char colval;
{
	pokeb(AUX_C,colval);
	testval = (peekb(AUX_A) ^ 0xFF);
}

/* return 1 if a key is pressed*/
kbhit(){

	keybuf = 0;			/* clear key*/
	InitKey();			/* INITIALIZE KEYSCAN*/
	/* start keyscan loop*/
	delay1ms(10);		/* wait 10ms*/

	/* do quick keyscan of all rows */
	pokeb(AUX_C,0x0F);
	testval = (peekb(AUX_A) ^ 0xFF);
	if(testval == 0)	return 0;

	/* do a keyscan*/
	scancol(0x7F);		/* start key scan w/ column 1 on*/
	if(testval == 0){
		keybuf += 4;		/* adjust base key number*/
		scancol(0xBF);		/* column 2 on*/
		if(testval == 0){
			keybuf += 4;		/* adjust base key number*/
			scancol(0xDF);		/* column 3 on*/
			if(testval == 0){
				keybuf += 4;		/* adjust base key number*/
				scancol(0xEF);		/* column 4 on*/
				if(testval == 0){
					keybuf = 0;			/* clear key*/
					InitKey();			/* INITIALIZE KEYSCAN*/
					return 0;		    /* return no key pressed*/
				}
			}
		}
	}

	/* here if a column is high*/
	testval = peekb(AUX_A);

	rcnt=0x80;
	for( ; ;){
		++keybuf;
		if((testval & rcnt) == 0){		/* if this row pressed*/
			InitKey();			/* INITIALIZE KEYSCAN*/
			return(1);
		}

		/* rotate to check next row */

		/* rcnt >>= 1; */	/* this rotates the carry flag, which we don't want */
#asm
		LSR	_rcnt
#endasm
		if(rcnt == 0x08)	break;
	}

	InitKey();			/* INITIALIZE KEYSCAN*/
	return 0;		    /* return no key pressed*/
}


/* return key pressed value.  this table returns ASCII representations*/
keyval(){
	char KeyDATA[18];
	KeyDATA[0] = 	0;
	KeyDATA[1] = 	68;
	KeyDATA[2] = 	70;
	KeyDATA[3] = 	48;
	KeyDATA[4] = 	69;
	KeyDATA[5] = 	67;
	KeyDATA[6] = 	57;
	KeyDATA[7] = 	56;
	KeyDATA[8] = 	55;
	KeyDATA[9] = 	66;
	KeyDATA[10] = 	54;
	KeyDATA[11] = 	53;
	KeyDATA[12] = 	52;
	KeyDATA[13] = 	65;
	KeyDATA[14] = 	51;
	KeyDATA[15] = 	50;
	KeyDATA[16] = 	49;
	KeyDATA[17] = 	48;

	return(KeyDATA[keybuf]);
}

/* wait for a key press and return it's table value*/
getkey(){
	while( !kbhit()) ;	/* wait for key press*/
	return(keyval());   /* return it*/
}

/* Wait for the LCD busy pin to clear                                 */
void LCD_busy(){
    while ((peekb(LCD_CMD) & 0x80)) ;
}

void LCD_Command(cval)
unsigned char cval;
{
    LCD_busy();                         /* wait for busy to clear     */
    pokeb(LCD_CMD,cval);                /* ouptut command             */
}

/* LCD Display Character                                              */
void cprint(dval)
char dval;
{
    LCD_busy();                         /* wait for busy to clear     */
    pokeb(LCD_DATA,dval);               /* ouptut data                */
}

/* LCD Display String                                                 */

void LCDprint(sptr)
unsigned char *sptr;
{
	while( *sptr ){
		cprint(*sptr);
		++sptr;
	}
}