8 Nisan 2019 Pazartesi

14 - STM32F4 ile Enkoder Okuma

Merhaba,

Enkoder çoğu dc motor uygulamalarında konum belirleme, hız ölçme vb sebeplerden ötürü kullanılmaktadır. Ayrıca radyo ses artırma/azaltma gibi çeşitleri de bulunmaktadır. Ya da encoderli bir çevirmeli buton ile çeşitli projeler yapabilirsiniz. Örneğin aşağıda "rotary encoder" ve üzerinde "Ok" tuşu bulunan bir ürünle projelerinizi farklı bir boyuta taşıyabilirsiniz.


Bildiğiniz üzere "rotary encoder" 'lerde A, B ve bazen de Z çıkışı bulunmaktadır. Biz bu uygulamada A ve B uçlarını kullanarak enkoder okuyacağız. Eğer bu yazıyı okuyorsanız enkoderin genel yapısını bildiğinizi düşünüyorum. Bu yüzden enkoderin A ve B çıkış sinyallerine kısaca değinip koda geçeceğiz. 


Yukarıda bir enkodere ait A ve B çıkış sinyalleri bulunmaktadır. Bu uçlar bir kare dalga üretirler. Başlangıçta A çıkışı lojik 1 olduğunda B ucu lojik 0'dadır. A ucunun lojik 1 olduğu bölgenin yarısında B ucu lojik 1 olur. A ucu lojik 0'a geçtiğinde B ucu halen lojik 1'dedir ta ki A ucunun lojik 0 olduğu bölgenin yarısına kadar, ve bu böylece devam eder. 

Eğer bir enkoder bir turda 250 darbe üretiyor diye yazıyorsa teknik dokümanında, bu sadece bir tetik için geçerlidir. Yani sadece bir kanalın ürettiği kare dalganın yükselen kenarında ölçüm yapıyor isek bir turda 250 darbe okuruz. Hem A hem de B kanalından okuma yapıyor isek bu değer iki kanal olduğu için 500'e çıkar. Hem yükselen hem de düşen kenar tetiklemesinde ölçüm yapıyor isek bir kanalda 250*2=500 darbe okuruz, iki kanal okuyorsak 250*4=1000 darbe okuruz. 

Artık koda geçebiliriz. "Stm32f4 discovery board" stm32f407vgt6 işemcisine sahiptir ve bu işlemcinin kendi enkoder modulu bulunmaktadır. Yani adamlar demişler ki eğer enkoder okuyacaksanız biz sizin için bu işi basit hale getirdik, rahatça işleminizi yapabilirsiniz, ister yükselen kenarda, ister düşen kenarda, isterseniz hem düşen hem yükselen kenardan okuyabilirsiniz diyor. Ancak bunu yaparken bir "timer" birimini enkoder için kullancaksın diyor, çünkü bu "timer" birimi sayesinde rahatça okuyorsun diyor. Şimdiye kadar yazdıklarımız tamamsa, başlayalım.

Enkoder için bir fonskiyon yazalım, bu fonksiyonda enkoderin ayarlarını yapalım.
Enkoder için "timer4" birimini kulanacağız. Siz de herhangi bi CH1 ve Ch2 çıkışı olan bir "timer" birimi kullanabilirsiniz. burada "timer4" kullanacağız. CH1 ve Ch2 için de teknik dokümanından baktığımızda GPIO_Pin_6 ve GPIO_Pin_7 kullanabiliyoruz. 

void Encoder_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; 
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; 
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_Init (GPIOB, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_TIM4);
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_TIM4);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
TIM_EncoderInterfaceConfig(TIM4,TIM_EncoderMode_TI1,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);  

TIM_SetAutoreload (TIM4, 0xffff);
TIM_Cmd (TIM4, ENABLE);
}

// burada enkodere herhangi bir değer verilebilir. örneğin 50, yada 100 artık ne verirseniz
//bu fonksiyondan sonra encoderiniz bu değerden saymaya başlar
void Encoder_Set(int deger)
{
TIM_SetCounter (TIM4, deger);
}

// buradan da enkoderin hangi değerde olduğu okunabilir

int  Read_Encoder_Value(void)
{
return TIM_GetCounter (TIM4);
}


yazdığınız programda ne zaman nerde enkoderden değer okumak istiyorsanız aşağıdaki gibi yapabilirsiniz.

int encoder_value=0;

encoder_value = Read_Encoder_Value();

bu kod parçasını istediğiniz gibi kendi projenize dahil edebilirsiniz.

enkoder ileri giderken artı yönde geri giderken eksi yönde saymaktadır.

İyi Çalışmalar

Hiç yorum yok:

Yorum Gönder