Sadece while döngüsünde düzgünce çalışıyor ama if deyimi olduğunda çalışmıyor.

Başlatan myprayer14, 27 Kasım 2016, 13:49:50

myprayer14

Herkese merhabalar,
Küçük bir proje için uğraşıyorum. Anlayamadığım bir sorunum var. Motor kontrol devresi yapıp hızını ölçmek için kesme işlemlerini deniyordum. Bunun için sadece while döngüsü içinde
while(1)
      {
         /*    delay_ms(25);
            set_pwm1_duty(0); 
            output_low(pin_c3);
         
           
            output_high(pin_c4) ;
            set_pwm2_duty(i); 
            
            delay_ms(25);
            printf(lcd_putc,"\f\nRPM DEGERI=%f ",rpm);
}
tam olmasada istediğim sonucu elde ettim. rpm değerini 1500 de gösteriyorum. Ama aynı işlemi if döngüsünü kullanarak yaptığımda program kitleniyor sanki . Bazen 3300 bazen 900 ,600, 1800 gibi değerler gösteriyor. Sağa veya sola dönerken farketmiyor. motor durukende 0 değil yine en son değeri gösteriyor. Kesmeler aktif olmuyor istediğim gibi sanki.

İf döngüsüyle beraber kodun tamamı şöyle;
#include <18F2520.h>
#FUSES INTRC
#FUSES NOWDT                    //No Watch Dog Timer
//#FUSES XT
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
//#FUSES NOMCLR

//#use delay (clock=4000000)
#use delay(internal=4Mhz)

#use fast_io(b) //Port yönlendirme komutları B portu için geçerli
//#define use_portb_lcd TRUE   // LCD B portuna bağlı

#define LCD_ENABLE_PIN PIN_B3
#define LCD_RS_PIN PIN_B1
#define LCD_RW_PIN PIN_B2

#define LCD_DATA4 PIN_B4
#define LCD_DATA5 PIN_B5
#define LCD_DATA6 PIN_B6
#define LCD_DATA7 PIN_B7 
#include <lcd.c>   // lcd.c dosyası tanıtılıyor
//int16 x=1;      // Tamsayı tipinde değişken tanımlanıyor

int16 y=0;    // Ondalıklı tipte değişken tanımlanıyor
//char z;     //  Karakter tipinde değişken tanımlanıyor
float kesme=0;
float RPM;
int i=40;

//***********************************timer1 kesmesi**************************
#use fast_io(c) //Port yönlendirme komutları C portu için geçerli

#int_timer0  //timer0 kesmesi zamanlayıcı modunda
void timer0_kesme()
{
set_timer0(60);
y++;
if(y==15) 
{
//output_high(pin_b0);
RPM=kesme*300;
//delay_ms(1000);
kesme=0;

//delay_ms(5000);
//output_low(pin_b0);
y=0;
}//printf(lcd_putc,"\f \n RPM DEGERI=%f ", RPM );

//printf(lcd_putc,"\f \n RPM DEGERI=%f ", RPM );

}

#int_timer1 // timer1 kesmesi sayıcı modunda
void timer1_kesme()
{ //delay_ms(25);
set_timer1(65511); //tmr1 kesme değeri 
kesme=kesme+1;
//delay_ms(50);
//RPM=kesme*30;
//delay_ms(25);
//printf(lcd_putc,"\f\nRPM DEGERI=%f ",RPM );
//printf(lcd_putc,"\f \n RPM DEGERI=%f ",RPM );

}

void main()
{

   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_2|ADC_TAD_MUL_0);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   //setup_timer_0(RTCC_INTERNAL);
   //setup_timer_1(T1_DISABLED);
   //setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   setup_oscillator(OSC_4MHZ);
   
   
   
   
   
   
   set_tris_a(0x1F);   // RA0 ve RA1 pinleri giriş
   set_tris_b(0x00);
   set_tris_c(0x01);   // RC0 pini giriş
   output_b(0x00);
   output_c(0x00);
   
   set_pwm1_duty(0); 
   set_pwm2_duty(0); 
   
   setup_ccp1(CCP_PWM);  // CCP1 birimi PWM çıkışı için ayarlandı
   setup_ccp2(CCP_PWM);  // CCP2 birimi PWM çıkışı için ayarlandı
   
   setup_timer_2(T2_DIV_BY_1,100,1);
   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256 | RTCC_8_BIT);
   set_timer0(60);
   
   setup_timer_1(T1_EXTERNAL | T1_DIV_BY_2);
   set_timer1(65511);
   
   enable_interrupts(INT_timer0);
   enable_interrupts(INT_timer1);
   
   enable_interrupts(GLOBAL);
   
   
  lcd_init(); 
   delay_ms(10);
   //printf(lcd_putc,"\f MUSTAFA SAHIN ");
   //printf(lcd_putc,"\f\nRPM DEGERI=%f ",RPM );
   //delay_ms(100);
   

   // TODO: USER CODE!!
   
      while(1)
      {
         /*    delay_ms(25);
            set_pwm1_duty(0); 
            output_low(pin_c3);
         
           
            output_high(pin_c4) ;
            set_pwm2_duty(i); 
            
            delay_ms(25);
            printf(lcd_putc,"\f\nRPM DEGERI=%f ",rpm);
      
       if(kesme==0)
       {
            delay_ms(25);
            output_high(pin_c3);
            output_high(pin_c4) ;
           
          
            set_pwm2_duty(0);
            set_pwm1_duty(0);
            //delay_ms(25);}
            
            */
       
         if(!input(pin_a3)){
         
            delay_ms(25);
            set_pwm1_duty(0); 
            output_low(pin_c3);
         
           
            output_high(pin_c4) ;
            set_pwm2_duty(i); 
            delay_ms(25);
            printf(lcd_putc,"\f\nRPM DEGERI=%f ",rpm);
            
            //while(!input(pin_a3));
         }
         
          if(!input(pin_a4)){
         
            delay_ms(25);
            set_pwm2_duty(0); 
            output_low(pin_c4);
            
            output_high(pin_c3) ;
            set_pwm1_duty(i);
               
           printf(lcd_putc,"\f\nRPM DEGERI=%f ",rpm);
            
            //while(!input(pin_a4));
         }    
          if(!input(pin_a2)){
         
            delay_ms(25);
            
            output_low(pin_c3);
            output_low(pin_c4) ;
            
            set_pwm1_duty(0);
            set_pwm2_duty(0); 
            
            printf(lcd_putc,"\f\nRPM DEGERI=%f ",rpm);
            //while(!input(pin_a2));
         }
        
         
         }  
         
        

         
         
       
}
         
         
   

      
     



Cemre.

Program ne kadar sürede bir kesme alt rutinlerine dallanıyor? Yani Timer0 ve Timer1 kaç ms/us'de bir çağrılıyor? Aşina olmadığım için soruyorum.

Salih

Aşağıda örnek bir takometre programı veriyorum.
Kendine göre uyarlayabilirsin.

// Tmr1 Modülünü Takometre olarak kullanma, Örnek Programı
#Include  <16F877A.h>
#Fuses XT,NOWDT
#Use Delay(clock=4M)
#include <Lcd.c>

int16 devir=0;
int8 i=0;
int1 oldu;

#int_Timer0// 50 ms
void Kesme()
{      
      i++;
      if (i==10)
         {
            devir = get_timer1();// devir dakika olması için. Encoder=120 pals/devir            
            i     = 0;
            oldu  = 1;
            set_timer1(0);
         }  
      set_timer0(60);     
}

void main()
{   
   Setup_timer_0(T0_INTERNAL | T0_DIV_256);
   setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1);//Tmr1 sayıcı olarak ayarlandı
   setup_timer_2(T2_DISABLED,0,1);   
   Setup_adc_ports(NO_ANALOGS);   
   port_b_pullups(true);
   Enable_interrupts(INT_Timer0);
   Enable_interrupts(GLOBAL);
   Lcd_init();
   delay_ms(10);
   set_timer1(0);
   While(True)   
   { 
     if (oldu)
      {
         printf(Lcd_putc,"\fDevir=%Lu",devir);
         oldu=0;
      }      
   }
} 

myprayer14

Alıntı yapılan: Salih - 27 Kasım 2016, 21:21:52
Aşağıda örnek bir takometre programı veriyorum.
Kendine göre uyarlayabilirsin.

// Tmr1 Modülünü Takometre olarak kullanma, Örnek Programı
#Include  <16F877A.h>
#Fuses XT,NOWDT
#Use Delay(clock=4M)
#include <Lcd.c>

int16 devir=0;
int8 i=0;
int1 oldu;

#int_Timer0// 50 ms
void Kesme()
{      
      i++;
      if (i==10)
         {
            devir = get_timer1();// devir dakika olması için. Encoder=120 pals/devir            
            i     = 0;
            oldu  = 1;
            set_timer1(0);
         }  
      set_timer0(60);     
}

void main()
{   
   Setup_timer_0(T0_INTERNAL | T0_DIV_256);
   setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1);//Tmr1 sayıcı olarak ayarlandı
   setup_timer_2(T2_DISABLED,0,1);   
   Setup_adc_ports(NO_ANALOGS);   
   port_b_pullups(true);
   Enable_interrupts(INT_Timer0);
   Enable_interrupts(GLOBAL);
   Lcd_init();
   delay_ms(10);
   set_timer1(0);
   While(True)   
   { 
     if (oldu)
      {
         printf(Lcd_putc,"\fDevir=%Lu",devir);
         oldu=0;
      }      
   }
} 

Teşekkürl ederim. Ben alınan değeri direk  lcd de göstermeye çalışıyordum. If (oldu) kısmıyla lcd de gösterince while döngüsü içinde güzel bir biçimde görebiliyorum artık. Ancak şöyle bir sorun daha var ki:motoru if deyimi ile  calistirdigimda motor ilk anda daha hızlı dönüyor 5-6sn sonra ise aynı  while döngüsünde düzgün çalıştığı hale yani normal hale  geliyor. Bu ilk kalkışma neden hızlı dönüyor ve bunun önüne nasıl geçerim acaba?

Salih


myprayer14


myprayer14

Alıntı yapılan: Salih - 28 Kasım 2016, 11:04:31
Programının son halini gönder bakalım.

if deyimiyle komut vermeyip while döngüsü içinde motoru enerji verir vermez döndürmek istediğimde istediğim sonucu aldım. kodu şöyle ;
#include <18F2520.h>
#FUSES INTRC
#FUSES NOWDT                    //No Watch Dog Timer
//#FUSES XT
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
//#FUSES NOMCLR
//#use delay (clock=4000000)
#use delay(internal=4Mhz)
#use fast_io(b) //Port yönlendirme komutları B portu için geçerli
//#define use_portb_lcd TRUE   // LCD B portuna bağlı
#define LCD_ENABLE_PIN PIN_B3
#define LCD_RS_PIN PIN_B1
#define LCD_RW_PIN PIN_B2
#define LCD_DATA4 PIN_B4
#define LCD_DATA5 PIN_B5
#define LCD_DATA6 PIN_B6
#define LCD_DATA7 PIN_B7 
#include <lcd.c>   // lcd.c dosyası tanıtılıyor
int16 y=0;    // Ondalıklı tipte değişken tanımlanıyor
float kesme=0.0;
float RPM;
int i=50;
int oldu=0;
//***********************************timer1 kesmesi**************************
#use fast_io(c) //Port yönlendirme komutları C portu için geçerli
#int_timer0  //timer0 kesmesi zamanlayıcı modunda
void timer0_kesme()
{
y++;
if(y==9) //450ms de bir timer0 kesmesi oluşuyor.
 {

 RPM=kesme;
 y=0;
 kesme=0.0;
 oldu=1;

 }
set_timer0(60);
}

#int_timer1 // timer1 kesmesi sayıcı modunda
void timer1_kesme()
{ 
set_timer1(65531); //tmr1 kesme değeri //10 darbe de +0.04 1sn de 25tur yani +1
kesme=kesme+0.04;

}
void main()
{

   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_2|ADC_TAD_MUL_0);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   //setup_timer_0(RTCC_INTERNAL);
   //setup_timer_1(T1_DISABLED);
   //setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   setup_oscillator(OSC_4MHZ);
   
   
   set_tris_a(0x1F);   // RA0 ve RA1 pinleri giriş
   set_tris_b(0x00);
   set_tris_c(0x01);   // RC0 pini giriş
   output_b(0x00);
   output_c(0x00);
   
   set_pwm1_duty(0); 
   set_pwm2_duty(0); 
   
   setup_ccp1(CCP_PWM);  // CCP1 birimi PWM çıkışı için ayarlandı
   setup_ccp2(CCP_PWM);  // CCP2 birimi PWM çıkışı için ayarlandı
   
   setup_timer_2(T2_DIV_BY_1,100,1);
   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256 | RTCC_8_BIT);
   set_timer0(60);
   
   setup_timer_1(T1_EXTERNAL | T1_DIV_BY_2);
   set_timer1(65531);
   
   enable_interrupts(INT_timer0);
   enable_interrupts(INT_timer1);
   
   enable_interrupts(GLOBAL);
   
   
  lcd_init(); 
  delay_ms(10);
 
   // TODO: USER CODE!!
   
      while(1)
      {    
            delay_ms(25);
            set_pwm2_duty(0); 
            output_low(pin_c4);
            
            output_high(pin_c3) ;
            set_pwm1_duty(i);
            delay_ms(25);
            
            printf(lcd_putc,"\f\nRPM=%f ",rpm*3000);
            
           
     if(oldu)
               {
               delay_ms(25);
               printf(lcd_putc,"\f\nRPM DEGERI=%ld ",rpm);
               }
             
 
     
         }  
         
        

         
         
       
}
         
         
   

      
     
1440-1500-1560 arasında değişiyor. Ama if deyimi ekleyip motoru sağ sol stop ile kontrol etmek isteyince program düzgün cevap vermiyor. if deyimiyle kod şöyle;
#include <18F2520.h>
#FUSES INTRC
#FUSES NOWDT                    //No Watch Dog Timer
//#FUSES XT
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
//#FUSES NOMCLR
//#use delay (clock=4000000)
#use delay(internal=4Mhz)
#use fast_io(b) //Port yönlendirme komutları B portu için geçerli
//#define use_portb_lcd TRUE   // LCD B portuna bağlı
#define LCD_ENABLE_PIN PIN_B3
#define LCD_RS_PIN PIN_B1
#define LCD_RW_PIN PIN_B2
#define LCD_DATA4 PIN_B4
#define LCD_DATA5 PIN_B5
#define LCD_DATA6 PIN_B6
#define LCD_DATA7 PIN_B7 
#include <lcd.c>   // lcd.c dosyası tanıtılıyor
int16 y=0;    // Ondalıklı tipte değişken tanımlanıyor
float kesme=0.0;
float RPM;
int i=50;
int oldu=0;
//***********************************timer1 kesmesi**************************
#use fast_io(c) //Port yönlendirme komutları C portu için geçerli
#int_timer0  //timer0 kesmesi zamanlayıcı modunda
void timer0_kesme()
{
y++;
if(y==9) //450ms de bir timer0 kesmesi oluşuyor.
 {

 RPM=kesme;
 y=0;
 kesme=0.0;
 oldu=1;

 }
set_timer0(60);
}

#int_timer1 // timer1 kesmesi sayıcı modunda
void timer1_kesme()
{ 
set_timer1(65531); //tmr1 kesme değeri //10 darbe de +0.04 1sn de 25tur yani +1
kesme=kesme+0.04;

}
void main()
{

   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_2|ADC_TAD_MUL_0);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   //setup_timer_0(RTCC_INTERNAL);
   //setup_timer_1(T1_DISABLED);
   //setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   setup_oscillator(OSC_4MHZ);
   
   
   set_tris_a(0x1F);   // RA0 ve RA1 pinleri giriş
   set_tris_b(0x00);
   set_tris_c(0x01);   // RC0 pini giriş
   output_b(0x00);
   output_c(0x00);
   
   set_pwm1_duty(0); 
   set_pwm2_duty(0); 
   
   setup_ccp1(CCP_PWM);  // CCP1 birimi PWM çıkışı için ayarlandı
   setup_ccp2(CCP_PWM);  // CCP2 birimi PWM çıkışı için ayarlandı
   
   setup_timer_2(T2_DIV_BY_1,100,1);
   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256 | RTCC_8_BIT);
   set_timer0(60);
   
   setup_timer_1(T1_EXTERNAL | T1_DIV_BY_2);
   set_timer1(65531);
   
   enable_interrupts(INT_timer0);
   enable_interrupts(INT_timer1);
   
   enable_interrupts(GLOBAL);
   
   
  lcd_init(); 
  delay_ms(10);
 
   // TODO: USER CODE!!
   
      while(1)
      {    /*
           
            delay_ms(25);
            set_pwm2_duty(0); 
            output_low(pin_c4);
            
            output_high(pin_c3) ;
            set_pwm1_duty(i);
            delay_ms(25);
            
            printf(lcd_putc,"\f\nRPM=%f ",rpm*3000);
            */
           
     if(oldu)
               {
               delay_ms(25);
               printf(lcd_putc,"\f\nRPM DEGERI=%f ",rpm*3000);
               }
             
  
             if(!input(pin_a3))
               {
         
               delay_ms(25);
               set_pwm1_duty(0); 
               output_low(pin_c3);
               output_high(pin_c4) ;
               set_pwm2_duty(i); 
           
            
               //while(!input(pin_a3));
               }
         
             if(!input(pin_a4))
               {
         
               delay_ms(25);
               set_pwm2_duty(0); 
               output_low(pin_c4);
               output_high(pin_c3) ;
               set_pwm1_duty(i);
                
          
               //while(!input(pin_a4));
               }    
              if(!input(pin_a2))
                {

                delay_ms(25);
                output_low(pin_c3);
                output_low(pin_c4) ;
                set_pwm1_duty(0);
                set_pwm2_duty(0); 
                //while(!input(pin_a2));
                }
     
         }  
         
        

         
         
       
}
         
         
   

      
     


Dün motoru 1. verdiğim kodu deneyip bırakmıştım. Böyle çalışınca butonlarla da çalışır diye ancak öyle olmadı. ikinci verdiğim kodda program hızlı döndüğünden dolayı 1800-1900 gibi değerler gösteriyor. Bir tarafa normal dönüyor bir tarafa ise hızlı

Buna ilaveten motorların ikinci kodda ki gibi olduğunda ilk kalkışta biraz hızlı döndüğünden ama sonrasında normale dönmesinden bahsetmiştim. Yardımcı olursanız çok sevinirim.

myprayer14

Tekrar baktım ki sola dönerken if deyimi olmadan dönse bile sanırım daha hızlı dönüyor. Sağa dönerken 1500 d/dk sola dönerken 1800-2000 d/dk dönüyor.