16f628a ile Rotary Encoder Uygulaması

Başlatan FxDev, 07 Eylül 2009, 06:39:21

FxDev

Bugün uyku tutmayınca bir gece uygulaması daha yaptım...
Aşağıda fotoğrafı görülen rotary encoder ile deneme yaptım. LCD ekranına kaç derece ve nereye doğru döndüğü ve kaç tur attığı görülebiliyor. Rotary encoder'in çok çok hızlı döndürülmemesi şeklinde RB0/INT kesmesini kullanan devre gayet iyi çalışmakta.
Görüntüler ve Kod:

Rotary encoder görüntüsü:



Çalışma Görüntüleri:





Kodlar:

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

#define B	RB1
#define C	RB2

int counter,counter_old;
unsigned char flag,tur;

void main(void)
{
	CMCON=0x07;
	PORTA=0x00;
	PORTB=0x00;
	TRISA=0x00;
	TRISB=0x07;
	
	INTEDG=1;		// Yükselen kenar kesme
	INTF=0;			// Bayrak temizleniyor
	INTE=1;			// Dış kesme aktif
	GIE=1;			// Genel kesmeler aktif
	
	DelayMs(250);
	lcd_init();
	
	for(;;)
	{	
		lcd_gotoxy(1,1);
		lcd_yaz("Aci:");
		veri_yolla(counter/1000+48);
		veri_yolla((counter%1000)/100+48);
		veri_yolla((counter%100)/10+48);
		veri_yolla('.');
		veri_yolla(counter%10+48);
		veri_yolla(0xDF);
		if(counter>3600)
			counter=0;
		if(counter<0)
			counter=3564;
		if(flag==0)
		{	
			lcd_yaz(" Sag");
			veri_yolla(0x7E);
		}
		else
		{	
			lcd_yaz(" Sol");
			veri_yolla(0x7F);
		}
		lcd_gotoxy(2,1);
		veri_yolla(tur/100+48);
		veri_yolla((tur%100)/10+48);
		veri_yolla(tur%10+48);
		lcd_yaz(" Tur Dondu");
	}
}

static void interrupt
rotary_encoder(void)
{
	GIE=0;
	counter_old=counter;
	if(B==1)
		counter=counter-36;
	else
		counter=counter+36;
	
	if((counter_old-counter)>0)
	{
		flag=1;
		if(C)
			tur--;
	}
	else
	{
		flag=0;
		if(C)
			tur++;
	}
	INTF=0;
	GIE=1;
}

aykut54

uygulama için teşekkürler aklımda böyle bir uygulama vardı ama fazla zaman bulupta yapamadım boş bir vakitte denicem benim yapacağım sin ve cos enkoderli bir sistem olucak

selamlar

Erol YILMAZ

"çok çok hızlı" nın frekans karşılığını tam olarak tespit edebilirmisin ?

Erol YILMAZ

Başka bir Mcu ile,

10.000 adet 5 khz lik ileri ve ardından,
10.000 adet 5 khz lik geri sinyali ürettiğinde

Encoder-metre'nin 0 da olması lazım.

Bu testi geçerse 5.5 kHz lik bi hızla deneyebilirsin.

picusta

lcd_gotoxy
lcd_yaz
veri_yolla

Fonksyonlarinin içerigi nedir ?
GIE=0;
komutu satiri geçiyor mu ?

GamzeDemir

Hocam bu rotary encoder ler tam olarak calısma prensibi nedir; anladıgım kadarıyla bunu rpm ölçer olarak kullanabiliyoruz peki bunu motora nasıl baglıyoruz neresine acıkcası pek hayal edemedim bilgilendirirseniz cok sevinirim

asagıda bir tane buldum

http://www.ctl.com.tr/Optoelektronik_acisan.pdf

mihri

static void interrupt
rotary_encoder(void)
{
   GIE=0;
   counter_old=counter;
   .
   .
   .


Kesme oluştuktan sonra programın GIE=0 satırına gelmesi ne kadar sürüyor?
"Eppur si muove!"

picusta

Benim demek istedigim, ana programda çagirdigin fonksyonlarda kesmeleri disable ediyormusun etmiyormusun ?
Ediyorsan programinda kesme "latency"'si olusur. ve o ölçtügün 10us 'lik süre arada bir uzaybilir, ve pals kaçirabilirsin. Bu latency kesmeleri ne kadar süre boyunca disable ettigine bagli.
Bu yüzden "Built-in" denilen fonksyonlara dikkat edilmeli.
Ana programda kesmeleri disable etmiyorsan sorun yok tabii.

"Data integrity"'ye de dikkat etmelisin:
counter, flag,tur degiskenlerini lcd'ye yazarken bunlardan biri degisirse (interrupt gelirse mesela), yanlis göstereceksin.
Ama bu uygulamada bu sorun değil çünkü "habire" lcd'yi tazeliyorsun. LCD bir kere yanlis gösterse sorun değil, çïnkü hemen sonra dogru gösterecek.
Farzet ki bu degerleri belli araliklarla kayit ediyorsun: bir SD karta attiyorsun. Ana programa kayit fonksyonunu yazarsan, ve önlem almazsan sorun olur.
Umarim bu yazdiklarimi negatif elestiri değil de, "latency" ve "Data integrity" kavramlarina bir giris olarak algilarsin.
Kolay gelsin basarilar, bol C'li günler.