Welcome, Ziyaretçi

Gönderen Konu: Atmega 328P encoder  (Okunma sayısı 5181 defa)

0 Üye ve 1 Ziyaretçi konuyu incelemekte.

tahtaco

  • Teğmen
  • ***
  • İleti: 179
  • Teşekkür: 41
Atmega 328P encoder
« : 13 Şubat 2016, 19:46:15 »
Merhaba rotary encoderle değişken değerlerini artır azaltmak istiyorum.
240,45,90 değerleri artırıp azaltmak istiyorum.
Kod: Üye Olmadan Linkleri Göremezsiniz. Üye Olun veya Giriş Yapın
timer_1_set_one_shot_value(CALC_US(240));
state = STATE_IS_1;
timer_1_set_one_shot_value(CALC_US(45));
state = STATE_IS_2;
timer_1_set_one_shot_value(CALC_US(90));
state = STATE_IS_3;

uint8_t val =240,val1=45,val2=90; değişkenlere değerleri  verdik.

timer_1_set_one_shot_value(CALC_US(val));
state = STATE_IS_1;
timer_1_set_one_shot_value(CALC_US(val1));
state = STATE_IS_2;
timer_1_set_one_shot_value(CALC_US(val2));
state = STATE_IS_3;



     

    ISR (INT0_vect)
{

if (((PIND&0x04)==0x00)&&(val<240)&&(val1<45)&&(val2<90))   val = val +1 ;   val1  = val1 +1 ;   val2 = val2 +1;    //inc
if (((PIND&0x02)==0x01)&&(val >200)&&(val<25)&&(val2<70))     val = val -1;     val1 = val1 -1 ;       val2 = val2 -1;      //dec

}

 

   
   int main(void)
{
        DDRD &= ~(1 << PD2); //encoder A   input a
DDRD &= ~(1 << PD3); //encoder B input   b
PORTD |= (1 << PD2);    //Pull-UP R
PORTD |= (1 << PD3);    //Pull-UP R
}

int main kısmında hangi registerleri set etmem gerekiyor INT0,INT1 aktif etmek için çok teşekkürler.


« Son Düzenleme: 13 Şubat 2016, 19:52:52 Gönderen: tahtaco »

__root

  • Teknik Destek
  • Teğmen
  • ******
  • İleti: 209
  • Teşekkür: 30
Ynt: Atmega 328P encoder
« Yanıtla #1 : 14 Şubat 2016, 14:46:52 »
Merhaba
Genellikler bu tür basit mikrodenetleyicilerde iki yöntem var. Birincisi sürekli poll yöntemi diğeri interrupt yöntemi. Ben daha önce poll yöntemini kullanmıştım.

Kod: Üye Olmadan Linkleri Göremezsiniz. Üye Olun veya Giriş Yapın
b0 = pin_get_status(p0);
b1 = pin_get_status(p1);

if (r_flag==0){
if (b0==0 && b1==1){
azaltildi = 1;
r_flag=1;
}else if (b0==1 && b1==0){
arttirildi = 1;
r_flag=1;
}if (b0==0 && b1==0){
r_flag=1;
}
}else{
if (b0==1 && b1==1){
r_flag=0;
}
}

po ve p1 encoderin iki ucu.burada r_flag b0, b1 static değişkenler. bu fonksiyonu loop içinde sürekli poll ederseniz sağa çevrildiğinde sola çevrildiğinde arrtir azalt değişkenleri 1 ya da sıfır olur.
« Son Düzenleme: 14 Şubat 2016, 14:48:40 Gönderen: __root »

tahtaco

  • Teğmen
  • ***
  • İleti: 179
  • Teşekkür: 41
Ynt: Atmega 328P encoder
« Yanıtla #2 : 14 Şubat 2016, 15:19:51 »
Teşekkürler hocam  :)

Uykusuz

  • Administrator
  • Yarbay
  • ******
  • İleti: 2599
  • Teşekkür: 207
  • while(heart_rate>0){work();}
Ynt: Atmega 328P encoder
« Yanıtla #3 : 15 Şubat 2016, 08:20:53 »
Merhaba

Ancak şimdi fırsatım oldu yazmaya, ben de kesme yönteminde yapmanız gerekenleri anlatmaya çalışayım. Kodlarınızı anlamaya çalışmayacağım zira bu kadar zamanım maalesef yok  :)

İlk etapta Rotary encoder'i bağlayacağınız A ve B pinlerini giriş olarak tanımlamalı ve pull-up aktif edilmeli. Bu portlar atmega328 için  PORTD2 ve PORTD3

Kod: Üye Olmadan Linkleri Göremezsiniz. Üye Olun veya Giriş Yapın
DDRD |= 0b00001100
PORTD |= 0b00001100

PD2 ve 3 giriş olarak tanımlandı ve pullup aktif edildi.

Sonra kesmeleri açmalısınız.

Kod: Üye Olmadan Linkleri Göremezsiniz. Üye Olun veya Giriş Yapın
EICRA = 0b00001010;
Düşen kenarda kesme oluşturuldu.

Kod: Üye Olmadan Linkleri Göremezsiniz. Üye Olun veya Giriş Yapın
EIFR = 0b0000011;
Kesme bayrakları temizlendi.

Kod: Üye Olmadan Linkleri Göremezsiniz. Üye Olun veya Giriş Yapın
EIMSK = = 0b0000011;
Hem Int0 hem INT1 için de kesmeler aktifleştildi. Bundan sonra her bir düşen kenar durumu algılandığında ISR (INT0_vect) veya ISR (INT1_vect) fonksiyonlarınız çalışacaktır. Sadece birini kullanmak istiyorsanız EIMSK kontrol kaydedicisinden istediğinizi kapatabilirsiniz.

Kolay gelsin.

« Son Düzenleme: 15 Şubat 2016, 08:22:46 Gönderen: Uykusuz »
Projelerimiz için tıklayın Üye Olmadan Linkleri Göremezsiniz. Üye Olun veya Giriş Yapın
Sipariş ve Bilgi için satis@lugatek.com ile irtibata geçiniz.
Lütfen teknik sorularınızı forumda sorunuz özel mesaj göndermeyiniz

tahtaco

  • Teğmen
  • ***
  • İleti: 179
  • Teşekkür: 41
Ynt: Atmega 328P encoder
« Yanıtla #4 : 15 Şubat 2016, 08:56:49 »
Vakit ayırıp verdiğiniz  cevap için teşekkür ederim  :)

tahtaco

  • Teğmen
  • ***
  • İleti: 179
  • Teşekkür: 41
Ynt: Atmega 328P encoder
« Yanıtla #5 : 17 Şubat 2016, 14:27:25 »
__root  hocam  merhaba
pin_get_status(p0);
pin_get_status(p1);
azaltildi = 1;
arttirildi = 1;
nasıl tanımlıyoruz  :)
            
               
         

__root

  • Teknik Destek
  • Teğmen
  • ******
  • İleti: 209
  • Teşekkür: 30
Ynt: Atmega 328P encoder
« Yanıtla #6 : 17 Şubat 2016, 14:37:25 »
p0 ve p1 encoderi bağladığınız iki pin. Hangi pinlere bağladıysanız o pini okuyorsunuz. Encoderin portd ye bağlı olduğunu düşünürsek;


b0 =  ((PIND)>>p0)&1)
b1 =  ((PIND)>>p1)&1)

attirildi ya da azaltildi adlı global değişkenleriniz çevrilen yöne göre 1 ya da sıfır oluyor. Program içerisinde de bu değişkenlere bakarak istediğiniz değişkenin değerini arttrıp azaltabilirsiniz. İşiniz bittikten sonra bu iki değişkeni sıfırlamayı unutmayın.

tahtaco

  • Teğmen
  • ***
  • İleti: 179
  • Teşekkür: 41
Ynt: Atmega 328P encoder
« Yanıtla #7 : 20 Şubat 2016, 12:56:45 »
Bu şekilde güzel çalışıyor simulasyonda denedim.Yardımlarınız için Uykusuz, __root   hocam çok tşkler tekrar.

Kod: Üye Olmadan Linkleri Göremezsiniz. Üye Olun veya Giriş Yapın
volatile int v =240 , v1 = 60 ,v2 =90;

void initInterrupts(void);

ISR(INT1_vect){

if (PIND & (1<<PIND3)){

v++;
v1++;
v2++;
}

else{

v--;
v1--;
v2--;
}

}

void initInterrupts(void){

EICRA = 0b00001000;// ISC11 enable
EIFR = 0b0000010;// INTF1 enable
EIMSK =  0b0000010;//INT1 enable

sei();
}

tahtaco

  • Teğmen
  • ***
  • İleti: 179
  • Teşekkür: 41
Ynt: Atmega 328P encoder
« Yanıtla #8 : 20 Şubat 2016, 15:58:21 »
edit : if (PINB & (1<<PINB0)) olacak :)

tahtaco

  • Teğmen
  • ***
  • İleti: 179
  • Teşekkür: 41
Ynt: Atmega 328P encoder
« Yanıtla #9 : 27 Mayıs 2016, 19:05:16 »
Merhaba resimde ki zamanlamaları yapmaya çalışıyorum ,bazen tam istediğim gibi  gayet güzel  bazende üsteki sinyale göre  farklı noktalarda on off oluyor neden acaba  saygılar :)
Kod: Üye Olmadan Linkleri Göremezsiniz. Üye Olun veya Giriş Yapın
#include <avr/io.h>
#include <avr/interrupt.h>


static  uint8_t state = 0;
static uint16_t OCR_advance[] = {240,240,60,60,60,60,60,60,60,540};
#define STATE_COUNT (sizeof(OCR_advance)/sizeof(uint16_t ))

static uint8_t state_1 = 0;
static uint16_t OCR_advance_1[] = {16,104,16,104,16,104,16,1068};
#define STATE_COUNT_1 (sizeof(OCR_advance_1)/sizeof(uint16_t ))

ISR(TIMER1_COMPA_vect)
{
  OCR1A += OCR_advance[state];
  if (++state >= STATE_COUNT)
  state = 0;
}

ISR(TIMER1_COMPB_vect)
{
OCR1B += OCR_advance_1[state_1];
if (++state_1 >= STATE_COUNT_1)
state_1 = 0;
}

int main(void)
{
// OC1A output
DDRB = (1<<1)|(1<<2);
// Toggle OC1A on compare match
TCCR1A = (1<<COM1A0)|(1<<COM1B0);
OCR1A = 540;
OCR1B =1068;
TIMSK1 = (1<<OCIE1A)|(1<<OCIE1B);
// Presc. 1:8 for 1MHz timer tick
TCCR1B = 1<<CS11;
sei();

    while (1)
    {
    }
}
« Son Düzenleme: 27 Mayıs 2016, 19:07:21 Gönderen: tahtaco »

__root

  • Teknik Destek
  • Teğmen
  • ******
  • İleti: 209
  • Teşekkür: 30
Ynt: Atmega 328P encoder
« Yanıtla #10 : 31 Mayıs 2016, 13:54:06 »
Merhaba
Portları nerede değiştirdiğinizi göremedim o kısmı da ekleyebilir misiniz?

tahtaco

  • Teğmen
  • ***
  • İleti: 179
  • Teşekkür: 41
Ynt: Atmega 328P encoder
« Yanıtla #11 : 31 Mayıs 2016, 14:00:11 »
Kod: Üye Olmadan Linkleri Göremezsiniz. Üye Olun veya Giriş Yapın
  OC1A,OC1B çıkış
 DDRB = (1<<1)|(1<<2);

__root

  • Teknik Destek
  • Teğmen
  • ******
  • İleti: 209
  • Teşekkür: 30
Ynt: Atmega 328P encoder
« Yanıtla #12 : 31 Mayıs 2016, 14:10:01 »

burada sadece giriş-çıkış ayarları yapılıyor. interrupt rutinlerinde portlarda bir değişim yazmamışsınız.

tahtaco

  • Teğmen
  • ***
  • İleti: 179
  • Teşekkür: 41
Ynt: Atmega 328P encoder
« Yanıtla #13 : 31 Mayıs 2016, 14:24:41 »
static uint16_t OCR_advance[] = {240,240,60,60,60,60,60,60,60,540};
dizide ki değerleri  sırasıyla OCR1A  yüklüyor.state 0 ise 240 us 1, state1 240  0 şeklinde devam ediyor.OCR1A,B pwm çıkış pinleri kullanılıyor.

__root

  • Teknik Destek
  • Teğmen
  • ******
  • İleti: 209
  • Teşekkür: 30
Ynt: Atmega 328P encoder
« Yanıtla #14 : 31 Mayıs 2016, 14:43:56 »
Karşılaştırma sonucu bu pinler sıfır ya da 1 oluyor fakat donanımsal olarak sadece karşılaşma anında bu pinler değiştirilir. Yani timer<ocr ise pin0 kal değilse 1 kal gibi çalışmıyor. Bu yaklaşımınız bu sebeple doğru değil. Her interrupt'a girildiğinde kendiniz bu pini o state durumunda ne olması gerekiyorsa o seviyeye çekmelisiniz. pinler normal io olarak ayarlanmalı, timer ya da pwm modülüne kesinlikle bağlı kalmamalıdır.