tuş takımı ve pic ile mesaj yazmak

Başlatan jackal183, 10 Mart 2011, 15:14:10

jackal183

arkadaşlar, elimizde 4x4 lük bir keypad olduğunu düşünelim, bu keypadi cep telefonunda mesaj yazdığımız gibi kullanmmak istiyorum, yani 2 tuşuna bir kere basıldığında 'a'  iki kere basıldığında 'b' üç kere basıldığında 'c' gibi. ama bunları hızlı bir şekilde yaparsa böyle olacak, yavaş yaparsa olmayacak. yani bildiğiniz cep telefonunda mesaj yazma olayı işte. timer kullanarak yapılır diye tahmin ediyorum ama timer konusuna hakim değilim. yardımcı olursanız sevinirim.

Tagli

Düğmeye her basışın sayılması normal yollardan yapılacak. Ancak burada, basılan düğmenin bir önceki ile aynı olup olmadığı da kontrol edilmeli. Diğer özellik için ise bir zaman aşımı süresi belirlenmeli. Diyelim ki 1 saniye olsun. Herhangi bir timer'ı her 1 saniyede bir kesme oluşturacak şekilde kurup kesme kodunda düğme sayacının sıfırlanması yeterli.
Gökçe Tağlıoğlu

jackal183

basit mantıkla düşünürsek, yani en azından benim kurduum mantık bu şekilde. diyelim tuş takımından 2'ye basıldı. tam bu anda timer başlayacak, ve ekranda a harfi görünecek, timer için belirlediğimiz süre dolmadan tekrar 2 ye basılırsa b görünecek, b göründükten sonra timer resetleyeceğiz, yine timerın süresi dolmadan tekrar 2 ye basılırsa da c görünecek. benim sormak istediğim soru timer modulü nasıl çalışır, biraz inceledim ama karşık gibi geldi bana

Mucit23

Çevrede çok örnek var. Kesme kullanmanız gerekiyor.

Tagli

Evet, aslında her tuşa basışta timer'ın sıfırlanması da gerekiyor, bu kısmı ihmal etmişim.

Timer kullanımı zor sayılmaz. Ancak kullandığın timer'a göre ayarlar değişecektir. Genelde TMR0 en az ayarı olan en basit timer'dır. Ancak uzun süreli bir bekleme için yetersiz kalacaktır. Muhtemelen senin uygulamanda TMR1'i kullanman gerekecek. Ancak sorun şu ki örneğin 1 saniyelik bir bekleme için TMR1 de yetersiz kalacak. Muhtemelen ikinci (ve daha yavaş) bir kristal ile TMR1'i besleyerek yavaşlatabilir ve bu şekilde istediğin bekleme değerine ulaşabilirsin.
Gökçe Tağlıoğlu

jackal183

peki timer nasıl kontrol edilir timer interruptı nasıl yapılır, hi-tech derleyecisine göre anlatır mısınız acaba

_MOD_

Hazır konu açılmışken konuyla alakalı birşey sormak istiyorum.

Tuş takımı tarama süresi ne kadar olmalı. İnsan eli hangi sürelerle taranırsa taramadan kaçamaz?

Mucit23

timerde beklemeye gerek yok. Bir sayac oluştur. Her kesmeye gittiğinde Tuşa basılmadığı sürece sayacı 1 arttır. Sayac misal 100 olunca son basılan harfi sabitle.Ben 100 dedim sadece örnek. Sen istedğin değer koyabilirsin. Arka planda bir saatda oluşturabilirsin. TMR0 ın prescaller oranını 1/64 yaparsan 4 MHz de 1 saniyede yaklaşık olarak 61 kesme oluşur. Her kesmeye geldiğinde sayacı 1 arttır. Sayac değeri 60 olunca sn adlı değişkeni 1 arttır sayacı sıfırla. Bu şekilde bir saniye bilgisi elde etmiş olursun. Gerçek saatler için bu yöntem pek tercih edilmez çünkü kodların işlenme süresi ortam koşulları vs. bu değeri arttırıp azaltabilir.  Ama bunun gibi hassasiyet gerekmeyen yerlerde çok kullanılır. Ete hocamızın bu konuda örnekleri mevcut.

jackal183

teşekkür ederim yapmaya çalışayım bakalım

jackal183

http://hotfile.com/dl/110673212/6fab4b1/lcdmenuv2.0.rar.html

kardeş ben bunu yapmaya çalıştım kısmen de başarılı oldum ama stabil çalışmıyor, eğer inceleme imkanın olursa
1. sorun; çok yavaş çalışıyor
2. sorun; timer sorunu olsa gerek, timer süresi dolduğunda lcd'ye bir sonraki satıra geç komutunu yolluyorum ama geçmiyor, kendine göre herhangi bir yerde geçiyor gibi geliyor bana, yani tam ayarlayamadım, yardımcı olur musunuz size zahmet. kodları da koyuyorum. linkte isis simülasyonu ve hi-tech projesi de bulunmaktadır. kaynak olarak FxDeV kullandım

ayrıca merak edene de
http://www.engineersgarage.com/microcontroller/8051projects/alphabetic-keypad-AT89C51-circuit?destination=node%2F284
adam yapmış çalıştırmış ama çok karmaşık bir kod gibi geldi bana bir günde çözemedim, çözmeye de çok uğraşmadım açıkçası, timer falan kullanmamış gibi görünüyor.
#include <htc.h>
#include "delay.h"
#include "lcd.h"

#define row1 RC3
#define row2 RC4
#define row3 RC5
#define row4 RC6
#define col1 RD0
#define col2 RD1
#define col3 RD2


char i;
char keyactive=1,lastkey=0;
char maxlength;
char keyflag=0;
char Posflag=0;

char scanKeyboard(void)
{
        char key=0;
        
        row1=1;
        if(col1)
        	key='1';
        else if (col2)
        	key='2';
        else if (col3)
            key='3';
        row1=0;
        
        row2=1;
        if(col1)
            key='4';
        else if (col2)
            key='5';
        else if (col3)
            key='6';
        row2=0;
        
        row3=1;
        if(col1)
            key='7';
        else if (col2)
            key='8';
        else if (col3)
            key='9';
        row3=0;
        
        row4=1;
        if(col1)
            key='*'; 
        else if (col2)
            key='0';
        else if (col3)
            key='#';
         row4=0;
        
        if((keyactive>0)&&(lastkey==key)){
        	key=0;
        }
        else{
        	keyactive=key;
        	lastkey=key;
        }
        
        return key;
        
}

void placeCursor(char row, char col, char maxLength){
	char i;
	lcd_gotoxy(row,col);
	for (i=0;i<maxLength;i++){
		lcd_yaz(" ");
	}
	lcd_gotoxy(row,col);
	lcd_komut(ImlecYanSon);
	
}

void inputtext(char row, char col, char maxlength)
{
	char key=0;
	char textflag=0;
	char textkey=0;	
	
	
	key=scanKeyboard();
	if(key=='1'){
		placeCursor(row,col,maxlength);
	}
	
	
	key=scanKeyboard();

	switch(key){
	
		case ('*'):{
			Posflag++;
			textkey='*';
			textflag=1;
		}break;
		
		case ('#'):{
			Posflag++;
			textkey='#';
			textflag=1;
		}break;
	
		case ('0'):{
				Posflag++;
				textkey=' ';
				textflag=1;
		}break;
		
		

		case ('2'):{ 	
			if(i==5){
				//Posflag++;
				keyflag=0;	
			}	
			
			textkey=keyflag+'a';
			keyflag++;
						
			if ((textkey>0)&&(textkey<(3+'a'))){
				textflag=1;
			}	
		}break;
				
		case ('3'):{ 	
			if(i==5){
				Posflag++;
				keyflag=0;	
			}	
					
			textkey=keyflag+'d';
			keyflag++;
								
			if ((textkey>0)&&(textkey<(3+'d'))){
				textflag=1;
			}	
		}break;
		
		case ('4'):{ 	
			if(i==5){
				Posflag++;
				keyflag=0;	
			}	
					
			textkey=keyflag+'g';
			keyflag++;
								
			if ((textkey>0)&&(textkey<(3+'g'))){
				textflag=1;
			}	
		}break;
		
		case ('5'):{ 	
			if(i==5){
				Posflag++;
				keyflag=0;	
			}	
					
			textkey=keyflag+'j';
			keyflag++;
								
			if ((textkey>0)&&(textkey<(3+'j'))){
				textflag=1;
			}	
		}break;
		
		case ('6'):{ 	
			if(i==5){
				Posflag++;
				keyflag=0;	
			}	
					
			textkey=keyflag+'m';
			keyflag++;
								
			if ((textkey>0)&&(textkey<(3+'m'))){
				textflag=1;
			}	
		}break;
		
		case ('7'):{ 	
			if(i==5){
				Posflag++;
				keyflag=0;	
			}	
					
			textkey=keyflag+'p';
			keyflag++;
								
			if ((textkey>0)&&(textkey<(3+'p'))){
				textflag=1;
			}	
		}break;
		
		case ('8'):{ 	
			if(i==5){
				Posflag++;
				keyflag=0;	
			}	
					
			textkey=keyflag+'t';
			keyflag++;
								
			if ((textkey>0)&&(textkey<(3+'t'))){
				textflag=1;
			}	
		}break;
		
		case ('9'):{ 	
			if(i==5){
				Posflag++;
				keyflag=0;	
			}	
					
			textkey=keyflag+'w';
			keyflag++;
								
			if ((textkey>0)&&(textkey<(3+'w'))){
				textflag=1;
			}	
		}break;
	}
	
	
	if(Posflag<maxlength){
		if(textflag&&textkey){
			lcd_gotoxy(row,col+Posflag);
			veri_yolla(textkey);		
		}
	}
	if(((key=='7')||(key=='9'))&&(keyflag>4)){
		keyflag=0;
	}
	else if (keyflag>3){
		keyflag=0;
	}
}

void main(void)
{  
   char key=0;
   
   ADCON1=0x07;
   TRISA=0x00;
   TRISB=0x00;
   TRISC=0x00;
   TRISD=0xFF;
   PORTB=0;PORTC=0;PORTD=0;
    
   TMR1H=-50000/256;
   TMR1L=-50000%256;
   TMR1CS=0;
   T1CKPS1=1;
   T1CKPS0=0;
   T1SYNC=1;
   TMR1IF=0;
   TMR1IE=1;
   TMR1ON=1;
   PEIE=1;
   GIE=1;
           
   lcd_init();
   lcd_komut(ImlecGizle);
    
   while(1){
	   
	   inputtext(1,1,5);
   } 
}

static void interrupt
textinterrupt(void)
{
	if(TMR1IF){
		GIE=0;
		i++;

		
		if(i>5)
			i=0;
		
		TMR1H=-50000/256;
		TMR1L=-50000%256;
		TMR1IF=0;
		GIE=1;
	}
}

omereliusuk

#10
zaten lcd yi kullanırken normalde yazarken mesela 'a' yazdın o direkt olarak yan tarafa geçer o yüzden komutla geri almalısın ki aynı yere gelsin. tuşa basılmadığı sürece de bir daha geri alınmasın ki daha da sola kaymasın kursor. süren dolduğu zaman ise kursor sağ tarafa kaysın ki yeni harf rakam neyse gelirse oraya aktarılsın...
ayrıca en altta timer aktif görünüyor kesme var.
textinterrupt(void)
{
	if(TMR1IF){
		GIE=0;
		i++;

		
		if(i>5)
			i=0;
		
		TMR1H=-50000/256;
		TMR1L=-50000%256;
		TMR1IF=0;
		GIE=1;
	}
}

jackal183

ben de zaten bu söylediklerini aynen yapmaya çalıştım kardeş, her bir case'in başında;
if(i==5)
                  Posflag++;


kodu ile imleci bir yana kaydırıyorum onun dışında kaydırmıyorum.

timer kesmesi ile 1 saniyelik süre ayarlıyorum, yani 1 saniye için kesmenini içindeki i değişkeni 5 kez artıyor,

jackal183

arkadaşlar bu bahsettiğim şeyi yaptım çok da güzel çalışıyor, proteustaki basit keypad için yaptım, isteyen olursa daha gelişmiş keypadlere de nasıl entegre edilebileceğini yani sola sağa doğru ilerlemek aşağı yukarı gitmek silmek falan gibi, ve kodun mantığını anlatabilirim.

http://hotfile.com/dl/111475343/995cc67/lcdmenuv2.0.rar.html

#include <htc.h>
#include "delay.h"
#include "lcd.h"

#define row1 RC3
#define row2 RC4
#define row3 RC5
#define row4 RC6
#define col1 RD0
#define col2 RD1
#define col3 RD2


char timer;
char keyactive=1,lastkey=0;
char maxlength;
char keyflag=0;
char Posflag=0;
float counter=0;
char key=0;
char symbolflag=0;
char tmpkey=0;
char UpperCase=0;
char textkey=0;
char currentrow;
char initPos;
char maxLength;
char PreviousKey=0;

char scanKeyboard(void)
{
         key=0;
        
        row1=1;
        if(col1)
        	key='1';
        else if (col2)
        	key='2';
        else if (col3)
            key='3';
        row1=0;
        
        row2=1;
        if(col1)
            key='4';
        else if (col2)
            key='5';
        else if (col3)
            key='6';
        row2=0;
        
        row3=1;
        if(col1)
            key='7';
        else if (col2)
            key='8';
        else if (col3)
            key='9';
        row3=0;
        
        row4=1;
        if(col1)
            key='*'; 
        else if (col2)
            key='0';
        else if (col3)
            key='#';
         row4=0;
        
        if((keyactive>0)&&(lastkey==key)){
        	key=0;
        }
        else{
        	keyactive=key;
        	lastkey=key;
        }
        
        return key;
        
}

void placeCursor(char currentrow, char currentcol, char maxLength){
	char i;
	lcd_gotoxy(currentrow,currentcol);
	for (i=0;i<maxLength;i++){
		lcd_yaz(" ");
	}
	lcd_gotoxy(currentrow,currentcol);
	lcd_komut(ImlecYanSon);
	
}


char charKeyboard(char currentrow, char initPos, char maxLength, char textkey)
{
	char textflag=0;
	char tmpkey=0;
	
	tmpkey=textkey;
	

	switch(textkey){
	
		case ('0'):{
				textkey=keyflag + ' ';
				keyflag++;

		}break;
		
		case ('1'):{
				textkey='.' - keyflag;
				keyflag++;
				symbolflag++;
		}break;
		
		case ('*'):{
				textkey='*';
		}break;
		
		case ('#'):{
				textkey='#';
				UpperCase++;
				if(UpperCase>1){
					UpperCase=0;
				}					
		}break;
		
		case ('2'):{ 				
					textkey=keyflag+'a';
					keyflag++;			
		}break;
		
		case ('3'):{ 					
					textkey=keyflag+'d';
					keyflag++;
		}break;
		
		case ('4'):{ 					
					textkey=keyflag+'g';
					keyflag++;
		}break;
		
		case ('5'):{ 					
					textkey=keyflag+'j';
					keyflag++;
		}break;
		
		case ('6'):{ 					
					textkey=keyflag+'m';
					keyflag++;
		}break;
		
		case ('7'):{ 					
					textkey=keyflag+'p';
					keyflag++;
		}break;
		
		case ('8'):{ 					
					textkey=keyflag+'t';
					keyflag++;
		}break;
		
		case ('9'):{ 					
					textkey=keyflag+'w';
					keyflag++;
		}break;
		
		default : textkey=0;break;
	}
	
	if((tmpkey==55)||(tmpkey==57)){ // the key 7 and 9 have 4 letter character, the others have 3 letter character
		if (keyflag>4){
			keyflag=0;
			return tmpkey;	// if keyflag is greater than 4, this function returns the number for 7 or 9 key 
		}
	}
	else if(tmpkey==48){
		if (keyflag>1){
			keyflag=0;
			return tmpkey; // if keyflag is greater than 1, this function returns the number 0
		}
	}
	else if(tmpkey==49){
		if(keyflag==8){
			textkey=':';
		}
		else if(keyflag==9){
			textkey=';';
		}
		else if(keyflag==10){
			textkey='?';
		}
		else if(keyflag==11){
			textkey='/';
		}
		else if(keyflag==12){
			textkey='#';
		}
		else if(keyflag>12){
			keyflag=0;
			return tmpkey;
		}
	}
	else{
		if(keyflag>3){
			keyflag=0;
			return tmpkey; 
		}
	}
	
	
	if(UpperCase){
		textkey=textkey-32;
		if((tmpkey=='0')||(tmpkey=='*')||(tmpkey=='1')){
			textkey=textkey+32;
		}
	}
		
	return textkey;	// if key is 7 or 9 and, keyflag is not greater than 4 for 7 and 9. this function returns the letters for 7 and 9
					// or if key are the others and, keyflag is not greater than 3. this function returns the letters for the others
}
void closeCursor(void)
{
	lcd_komut(ImlecGizle);
}

void cursorUpdate(void)
{
	lcd_komut(ImlecYanSon);
}


void PrintNextPos(char currentrow, char initPos, char maxLength, char letter) //if the previous key and currentkey are not same, print next position
{
	if(textkey != '#'){
		if(Posflag<maxLength){
			lcd_gotoxy(currentrow,initPos+Posflag);
			veri_yolla(letter);	
			Posflag++;
		}
	}
}

void PrintSamePos(char currentrow, char initPos, char maxLength, char letter) // if the previous key and currentkey are same, print same position
{	
	if(textkey != '#'){
		if(Posflag<=maxLength){
			lcd_gotoxy(currentrow,initPos+Posflag-1);
			veri_yolla(letter);
		}
	}
	
	if(Posflag==maxLength){
		closeCursor();
	}
}

char isSameKey(char textkey)	// are the previous key and current key  same?
{	
	if(PreviousKey != 0 || textkey != 0){
		if (PreviousKey==textkey){
			return 1;
		}
		else{
			PreviousKey=textkey;
			return 0;
		}
	}
	return 0;
}


void TextMode(char currentrow, char initPos, char maxLength ) 
{	
	char letter;

	
	
	
	if(Posflag<=maxLength){
		textkey=scanKeyboard();
	}
	else{
		Posflag++;
		textkey=0;
	}
	
		if(textkey != 0){	
			if(timer==2){
				cursorUpdate();
				keyflag=0;
				letter=charKeyboard(currentrow, initPos, maxLength, textkey);
				PrintNextPos(currentrow, initPos, maxLength, letter);
				timer=0;
				PreviousKey=textkey;
			}
			else{
				if(isSameKey(textkey)){ 
						closeCursor();	// close cursor, until it is timeout or the key is different
						letter=charKeyboard(currentrow, initPos, maxLength, textkey);
						PrintSamePos(currentrow, initPos, maxLength, letter);
						timer=0;			
				}
				else{
					cursorUpdate();	// updatecursor, if it is different key
					keyflag=0;
					letter=charKeyboard(currentrow, initPos, maxLength, textkey);				
					PrintNextPos(currentrow, initPos, maxLength, letter);
					timer=0;
				}
			}
		}
		else if(timer==2){	// updatecursor, only if it is timeout 
			cursorUpdate();
			keyflag=0;
		}
}
void main(void)
{  
   char key=0;
   
   ADCON1=0x07;
   TRISA=0x00;
   TRISB=0x00;
   TRISC=0x00;
   TRISD=0xFF;
   PORTB=0;PORTC=0;PORTD=0;
    
   TMR1H=-50000/256;
   TMR1L=-50000%256;
   TMR1CS=0;
   T1CKPS1=1;
   T1CKPS0=0;
   T1SYNC=1;
   TMR1IF=0;
   TMR1IE=1;
   TMR1ON=1;
   PEIE=1;
   GIE=1;
           
   lcd_init();
   lcd_komut(ImlecGizle);
    
   while(1){
	   
	   TextMode(1,1,5);
   } 
}

static void interrupt
textinterrupt(void)
{
	if(TMR1IF){
		GIE=0;
		
		timer++;		
		if(timer>2)
			timer=0;
		
		TMR1H=-50000/256;
		TMR1L=-50000%256;
		TMR1IF=0;
		GIE=1;
	}
}