Kesme İçinde Veri Okumak (Keypad)

Başlatan vitruvius, 04 Aralık 2011, 18:58:31

vitruvius

Merhaba, keypad'ten tuşa basıldığında led yakmak istiyorum. Kesme kısmında bir sorunum var.

Kod şu şekilde:

#include <16f877A.h>
#fuses XT, NOWDT, NOPROTECT, NOBROWNOUT, NOLVP, NOPUT, NOWRT, NODEBUG, NOCPD
#use delay (clock=4000000)

#use fast_io(b)
#use fast_io(c)
#use fast_io(a)

int x;
int data;

#int_ext
void dis_kesme ()

{
 
data=input_c();

if(data==10010000) //Keypad'den 8'e basılma durumu
{x=8;}

else if(data==10000000) //Keypad'den 7'ye basılma durumu
{x=7;}
 
}


void main ( )
{
setup_psp(PSP_DISABLED);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_CCP1(CCP_OFF);
setup_CCP2(CCP_OFF);

set_tris_b(0x01);
set_tris_c(0xFF);
set_tris_a(0x00);

output_a(0x00);

ext_int_edge(L_TO_H);

enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);


if(x==8)
{output_high(pin_a0);
delay_ms(20);}

else if(x==7)
{ output_high(pin_a5);
delay_ms(20);}

while(1);

}


Burada kesme içinde okunan değere göre bir değişken atamak istiyorum ki ilerde o değişkeni kullanıp lcd'ye yazdırmak v.s. gibi işlerde kullanacağım. Kodun o halinde a0 yada a5 pinin'deki ledler yanmıyor.


Kesmeyi şu şekilde yapınca ledler yanıyor:
#int_ext
void dis_kesme ()

{
 
data=input_c();

if(data==10010000) //Keypad'den 8'e basılma durumu
{output_high(pin_a0);}

else if(data==10000000) //Keypad'den 7'ye basılma durumu
{output_high(pin_a5);}
 
}


Ancak dediğim gibi ben kesme içinde değere göre bir değişken atayıp o değişkeni ilerde yorumlamak istiyorum. Bunu nasıl yapabilirim? Teşekkürler.

Devrem şu şekilde:


ctn1905

#1
if pin_a şartlarını while içine koy

vitruvius

Alıntı yapılan: ctn1905 - 04 Aralık 2011, 19:12:43
if pin_a şartlarını while içine koy

Teşekkür ederim. Şu şekilde yapınca oldu, ancak niye sonsuz döngü içinde yazmak gerekiyor?

while(1)
{
if(x==8)
{output_high(pin_a0);
delay_ms(20);}

else if(x==7)
{ output_high(pin_a5);
delay_ms(20);}
}

CaFFeiNe

programın if şartlarına bir kez bakıp while(1); satırında çakılıp kalıyor çünkü

vitruvius

#4
Şu an basılan tuşları doğru bir şekilde alamıyorum. Simulasyonda 6'ya bastığım zaman ekrana 11'i yazıyor. Aradığım gibi bir datasheet bulamadığımdan simulasyon yaparken pinlerin yanındaki mavi ve kırmızı kutucuklara baktım (Resimde çerçeveye aldım). Kırmızı kutucuk lojik-1, mavi kutucuk da lojik-0 durumunu gösteriyor benim bilgiğim kadarıyla.

Kod şu an şu şekilde: (1,7,8,*,0 doğru şekilde ekrana yazılıyor. 3, "9" olarak; 6, "11" olarak yazılıyor. Diğer tuşlar herhangi bir etki yapmıyor.)

#include <16f877A.h>
#fuses XT, NOWDT, NOPROTECT, NOBROWNOUT, NOLVP, NOPUT, NOWRT, NODEBUG, NOCPD
#use delay (clock=4000000)

#use fast_io(b)
#use fast_io(c)
#use fast_io(a)

#include <lcd.c>

int x;
int data;

#int_ext
void dis_kesme ()

{
 
data=input_c();

if(data==00000000) //Keypad'den 1'ye basılma durumu
{x=1;}

else if(data==00010000) //Keypad'den 2'ye basılma durumu
{x=2;}

else if(data==00100000) //Keypad'den 3'ye basılma durumu
{x=3;}

else if(data==01000000) //Keypad'den 4'ye basılma durumu
{x=4;}

else if(data==01010000) //Keypad'den 5'ye basılma durumu
{x=5;}

else if(data==01100000) //Keypad'den 6'ye basılma durumu
{x=6;}

else if(data==10000000) //Keypad'den 7'ye basılma durumu
{x=7;}

else if(data==10010000) //Keypad'den 8'e basılma durumu
{x=8;}

else if(data==10100000) //Keypad'den 9'ye basılma durumu
{x=9;}

else if(data==11010000) //Keypad'den 0'ye basılma durumu
{x=0;}

else if(data==11000000) //Keypad'den *'ye basılma durumu
{x=10;}

else if(data==11100000) //Keypad'den #'ye basılma durumu
{x=11;}
 
}


void main ( )
{
setup_psp(PSP_DISABLED);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_CCP1(CCP_OFF);
setup_CCP2(CCP_OFF);

set_tris_b(0x01);
set_tris_c(0b11111111);
set_tris_a(0x00);
set_tris_d(0x00);

lcd_init();

output_a(0x00);

ext_int_edge(L_TO_H);

enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);

while(1)
{
if(x==8)
{output_high(pin_a0);
delay_ms(20);}

else if(x==7)
{ output_high(pin_a5);
delay_ms(20);}

//lcd_send_byte(0,0x0d); İmlecin yanıp sönmesi
printf(lcd_putc,"\fBasilan Deger=%d",x);
delay_ms(500);
}

}


Devre: (Keypad'den 6'ya basmışken)


vitruvius

Yada Serdar Çiçek'in kitabındaki örnekten yola çıkarak şu şekilde bir kod yazdım. Bu sefer de C portunun tamamını okuyup lcd'ye yazıyor. Bunun sadece son 4 bitini nasıl okurum? Teşekkürler.


CCS C kodu:

#include <16f877A.h>
#fuses XT, NOWDT, NOPROTECT, NOBROWNOUT, NOLVP, NOPUT, NOWRT, NODEBUG, NOCPD
#use delay (clock=4000000)

#use fast_io(b)
#use fast_io(c)
#use fast_io(d)

#include <lcd.c>

#byte portc=0x07

char const keys [] = {1,2,3,0,4,5,6,0,7,8,9,0,0xF,0,0xF,0};
int x;

#int_ext
void dis_kesme ()

{
 portc=keys[portc>>4];
 x=portc;
}

void main ( )
{
setup_psp(PSP_DISABLED);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_CCP1(CCP_OFF);
setup_CCP2(CCP_OFF);

set_tris_b(0x01);
set_tris_c(0xF0);
set_tris_d(0x00);

lcd_init();

ext_int_edge(L_TO_H);

enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);

portc=0;

while(1)
{
printf(lcd_putc,"\fBasilan Deger=%d",x);
delay_ms(500);
}
}



Devre resmi (5'e basılmışken, ok yönünde 01010101=85 yapıyor):


ferdem

#6
Son 4 biti aşağıdaki gibi and işlemiyle alabilirsin.
x=portc&0xF0;

Sonra da 4 defa sağa kaydırman gerekiyor, CCS C help e bakabilirsin.

Düzenleme:
Şöyle olabilir:
var=(var&0xF0)/16;

Pir-O

#int_ext
void dis_kesme ()

{
 portc=keys[portc>>4];
 x=portc;

 x=x&0b11110000;   //maskeleme

}


Şu şekilde maskeleme yaparsan yüksek değerlikli 4 bit kalır diğerleri sıfırlanır.