Encoder motor control çalışmıyor yardım

  • Konbuyu başlatan Konbuyu başlatan wildarms
  • Başlangıç tarihi Başlangıç tarihi

wildarms

Üye
Katılım
28 May 2021
Mesajlar
3
Puanları
1
Yaş
27
Merhabalar herkese. pic 16f877a kullanarak encoder dc motor kontrol etmeye çalışıyordum bir türlü #INT_RB kesmesini kullanamadım. kodumda bana yardımcı olabilir misiniz. INT_RB kesmesine bağlı olan angle değeri sürekli sıfır geliyor onu arttırmam lazım bir şekilde lütfen yardımcı olun.
Kod:
#include <16F877A.h>
#device adc=10    //set the bit value of adc
#FUSES XT, NOWDT, NOPROTECT, NOBROWNOUT, NOLVP, NOPUT, NODEBUG, NOCPD
#use delay(crystal=4000000)
#include <lcd.c>

unsigned int16 last_read,quad;

#INT_RB // RB port interrupt on change
void RB_IOC_ISR(void)
{
   int8 encoderRead;
   encoderRead = input_b() & 0x30;
   if(encoderRead == last_read)
   return;
  
   if(bit_test(encoderRead, 4) == bit_test(last_read, 5))
   quad -= 1;
   else
   quad += 1;
   last_read = encoderRead;
}

signed long EncoderGet(void)
{
   signed long value = 1;
  
   while(quad >= 4)
   {
      value += 1;
      quad -= 4;
   }
   while(quad <= -4)
   {
      value -= 1;
   quad += 4;
   } 
return value;
}

signed long PWM,error = 0,change = 0,realPosition = 0,angle = 0.0f;

void main()
{
   unsigned int8 temp;
   unsigned int16 rev,kp;
   unsigned long int16 referance;   //variable for ADC reading value from AN0
  
   lcd_init();
   delay_ms(10);
  
   set_tris_c(0x00); //set all portb pins as output
   set_tris_b(0x00);
   port_b_pullups(TRUE);
   delay_ms(10);
   temp = input_b(); // Add these 4 lines
   enable_interrupts(INT_RB);
   clear_interrupt(INT_RB);
   enable_interrupts(GLOBAL);
   setup_ccp1(CCP_PWM); //4kHz PWM signal output at CCP1 pin 17
   setup_timer_2(T2_DIV_BY_16, 255, 1);
   setup_adc_ports(ALL_ANALOG); //A0A1 A2 A3 A5 E0 E1 E2 analog pins
   setup_adc(ADC_CLOCK_DIV_32); //enable ADC and set clock FOR ADC
  
   WHILE(1)
   {
      set_adc_channel(0); // next analog reading will be from channel 0
      delay_us(10); //allow time after channel selection and reading
      referance =read_adc(); //start and read A/D
      referance=referance*250;
      referance=referance/1023;
      referance=referance+20;
      set_adc_channel(1); // next analog reading will be from channel 1
      delay_us(10); //allow time after channel selection and reading
      kp = 50+(read_adc()*10/1023); //start and read A/D
      delay_ms(200);
     
     
      change = EncoderGet();
         if(change)
         {
            realPosition += change;
         }
         rev = realPosition/360.0f; // Here 360 represents the encoder pulses per revolution
         angle = ((int16)(rev*360))%360; // Real time angle is determined in this line
        

         error=referance-angle;
         PWM=error*kp;
         if (PWM>=1023)
         PWM=1023;
         else if (PWM<=0)
         PWM=0;
         set_pwm1_duty(PWM);


         printf(LCD_PUTC,"\fref=%lu",referance);
         printf(LCD_PUTC,"  kp=%lu",kp);
         printf(LCD_PUTC,"\npos=%lu",rev);
         lcd_gotoxy(8,2);
         printf(LCD_PUTC,"PWM=%lu",PWM);
         delay_ms(700);
   }
}
 
Moderatör tarafında düzenlendi:

Forum istatistikleri

Konular
133,380
Mesajlar
971,000
Kullanıcılar
459,228
Son üye
saidkaradogu

Yeni konular

Çevrimiçi üyeler

Geri
Üst