pwm modülü ile 50 hz lik pwm üretilemiyormu?

Başlatan gambit1244, 11 Şubat 2012, 19:45:42

gambit1244

merhaba arkadaşlar bildiginiz gibi pic pwm donanımı timer 2 kullanıyor fakat bu timer a baktıgım zaman en az 1khz gibi değerlere inilebildiğini farkettim
ne yani ben şimdi 50 hz ile pwm yapamayacakmıyım

pwm modülünün timer 0 ı kullanması gibi birşey yaptıramazmıyım

rc servo sürmek isteyen mutlaka olmuştur pic ile :( yazılımsal olarak yaparım fakat pic'i kanser eder gibi geldi ve duty oranım cook hızlı değişicek
ne önerirsiniz bana saygılar teşekkürler..
[email]tufan_ozbek@hotmail.com[/email] Yesterday is history. Tomorrow is a mystery. Today is a gift aslında bütün mesele bu.

SpeedyX

CCP Kullan?

Al örnek:
//*************************
// includes
#include "main.h"



//*************************
// Sabitler
//
#define T_SIG_PERIOD             20000
#define T_MIN_SERVO              800
#define T_MAX_SERVO              2500
#define SERIALDATA_BUFFER_SIZE   32
#define BUFFER_SIZE              32
#define FRAME_START              'B'
#define FRAME_SEPARATOR          'X'
#define FRAME_END                'Z'
#define MAX_INT_LENGTH           4



//*****************************
// Enum (enumeration)
// 

// ENU_PPM_STATE
// PPM  çikis durumu
typedef enum
   {
   PPM_STATE_HIGH,
   PPM_STATE_LOW,
   }ENU_PPM_STATE;

// ENU_SERVO
// Servolar
typedef enum
   {
   SERVO1,
   SERVO2,
   MX_SERVO,
   }ENU_SERVO;
   
//
// ENU_RX_STATE
// Gelen veriyi çözme durum makinesi. 
typedef enum
   {
   RX_STATE_START,   // Start karakteri beklenir
   RX_STATE_FIRST,   // Birinci deger aliniyor
   RX_STATE_SECOND,  // ikinci deger aliniyor
   RX_STATE_END,     // Son deger alindi, komut servolara gönderilmeli
   }ENU_RX_STATE;
   
   

   
//*************************************
/////Veri tipleri
//
// 
// STR_SERIALDATA
// Interrupt -> Ana program  Seri data Alimi
typedef struct
{
BYTE buffer[BUFFER_SIZE];   // Buffer
BYTE next_in;               // Yazma Pointeri
BYTE next_out;             // Okuma pointeri
}STR_SERIALDATA;


// STR_INTERPRETED_SERDATA
typedef struct
{
ENU_RX_STATE  Durum;       // Durum makinesinin durumu
long Val[MX_SERVO];          // PPM Komut degerleri
char Buff[BUFFER_SIZE];    // Geçici tampon bellek
int IdxBuff;               // Tampon bellek durumu
}STR_INTERPRETED_SERDATA;




// *******************************************************
// Global degiskenler
volatile int  PPMState[MX_SERVO];              // Durum
volatile long OffSetWidth[MX_SERVO];           //  PPM Komut
volatile long CPPNextChange[MX_SERVO];         // Sonraki 
volatile long CumulCcp[MX_SERVO];              // CCP'ye yazilacak Toplam, Timer1 sifirlanmiyor
volatile int  CPPFlag[MX_SERVO];               // Ana program döngüsünü Haberdar et
volatile STR_INTERPRETED_SERDATA  SeriYorum; // Seri bilgilerin yorumu


// *******************************************************************
// MACRO LAr 
#define bkbhit (SeriYorum.IdxBuff!=0)



// ****************************************************************
// Prototipler
void CompareFSM(ENU_SERVO IdxCCP);

void SeriDekod(char RxChar);
   int RakamYorumla(char RxChar,ENU_SERVO ServoIdx,ENU_RX_STATE SonrakiDurum,char BeklenenChar );
   void ResetSeriYorum();
   int TestInt(char carac);
   long StringToLong(char *Buff, int length);
// *******************************************************************
// interrupt rutinleri

//
// compare1_isr
// CCP 1 compare ISR
#int_ccp1
void compare1_isr()
{
CompareFSM(SERVO1);
}

//
// compare2_isr
// CCP 2 compare ISR
#int_ccp2
void compare2_isr()
{
CompareFSM(SERVO2);
}

//
// serial_isr
// Seri ISR
#int_rda
void serial_isr() {
 
   SeriDekod(getc());

}

// *********************************************************************
// Fonksyonlar

// 
// CompareFSM
// PPM üretmeyi saglayan durum makinesi
//  Parametre : 
//   giris : IdxCCP  PPM çikis (servo) numarasi
void CompareFSM(ENU_SERVO IdxCCP)
{
switch (PPMState[IdxCCP])
   {
   case  PPM_STATE_HIGH:
      // bir sonraki seviye degisimini ayarla
      if (IdxCCP==SERVO1)
         setup_ccp1(CCP_COMPARE_SET_ON_MATCH);
     else
      setup_ccp2(CCP_COMPARE_SET_ON_MATCH);

     // Zamani hesapla ve durum degiskenini güncelle
      CPPNextChange[IdxCCP]  = T_SIG_PERIOD - CPPNextChange[IdxCCP];
       CumulCcp[IdxCCP] = CumulCcp[IdxCCP] + CPPNextChange[IdxCCP];
     PPMState[IdxCCP] = PPM_STATE_LOW;
     // SFR'e yaz
       if (IdxCCP==SERVO1)
          CCP_1 = CumulCcp[IdxCCP];
      else
      CCP_2 = CumulCcp[IdxCCP];
      break;
   case  PPM_STATE_LOW:
      // bir sonraki seviye degisimini ayarla
      if (IdxCCP==SERVO1)
         setup_ccp1(CCP_COMPARE_CLR_ON_MATCH);
     else
      setup_ccp2(CCP_COMPARE_CLR_ON_MATCH);

     // Zamani hesapla ve durum degiskenini güncelle
     CPPNextChange[IdxCCP] = T_MIN_SERVO + OffSetWidth[IdxCCP];
      if (CPPNextChange[IdxCCP] > T_MAX_SERVO)
          {
          CPPNextChange[IdxCCP] = T_MAX_SERVO;
          }
      CumulCcp[IdxCCP] = CumulCcp[IdxCCP] + CPPNextChange[IdxCCP];
       PPMState[IdxCCP] = PPM_STATE_HIGH;
       // SFR'e yaz
       if (IdxCCP==SERVO1)
          CCP_1 = CumulCcp[IdxCCP];
      else
      CCP_2 = CumulCcp[IdxCCP];
      break;
   default :
      break;
   }
CPPFlag[IdxCCP] = 1;
}


//
// SeriDekod
// Seri baglantidan gelen karakterleri çöz
void SeriDekod(char RxChar)
{
// Duruma göre islem
switch (SeriYorum.Durum)
   {
   case RX_STATE_START :    // Start karakteri beklenir
      if  (RxChar == FRAME_START)
         {
         // Durumu ilerlet
         SeriYorum.Durum = RX_STATE_FIRST;
         }
      break;
   case RX_STATE_FIRST :   // Birinci deger aliniyor
         RakamYorumla(RxChar, SERVO1,RX_STATE_SECOND, FRAME_SEPARATOR );   
         
         break;
   case RX_STATE_SECOND :  // ikinci deger aliniyor
       if (RakamYorumla(RxChar, SERVO2,RX_STATE_END, FRAME_END ))
          {
          // Komutlari ana döngüden al gönder
          }
      break;
   case RX_STATE_END :     // Son deger alindi,
      // komut servolara gönderilmeli, ama gönderilmemis ? bisey yapma, 
      // ana döngünün yapmasini bekle
      break;
   }
   

}


//
// ResetSeriYorum
//  Seri Yorum Struct'unu sifirliyor
void ResetSeriYorum()
{
SeriYorum.Durum = RX_STATE_START;
SeriYorum.IdxBuff = 0;
}


//
// RakamYorumla
// Rakam beklenen durumlarda rakami yorumlar
// giris :
//   RxChar : alinan karakter
//   ServoIdx : Hangi çikisin degeri
//   SonrakiDurum: testler basarili olursa geçilecek sonraki durum
//   BeklenenChar: Bir sonraki duruma geçmek için beklenen karakter (testler basarili olursa o da)
// dönüs : 
//   Eger bir sonraki duruma geçildiyse 0'dan baska, yoksa 0
int RakamYorumla(char RxChar,ENU_SERVO ServoIdx,ENU_RX_STATE SonrakiDurum,char BeklenenChar )
{
int Retour;
Retour = 0;

if (TestInt(RxChar))  // Rakam alindi
   {
   if (SeriYorum.IdxBuff > MAX_INT_LENGTH)  // 10 000 ms veya daha  büyük sayi kabul etmiyoruz
      {
      //  hata Baslangica geri dön
      ResetSeriYorum();
      }
   else
      {
      // Rakami (harf) hafizaya al
      SeriYorum.Buff[SeriYorum.IdxBuff] = RxChar;
      // Index ilerlet
      SeriYorum.IdxBuff++;
      }  
   }
else if ( RxChar == BeklenenChar )
   {
   if (SeriYorum.IdxBuff == 0) // En az bir rakam olmasi gerek
      {
      // Hata : sil bastan
      ResetSeriYorum();   
      }
   else
      {
      // Servo degerini kaydet
      SeriYorum.Val[ServoIdx] = StringToLong(SeriYorum.Buff, SeriYorum.IdxBuff);
      // Degeri test et
      if (SeriYorum.Val[ServoIdx] > (T_MAX_SERVO - T_MIN_SERVO))
         {
         //  hata Baslangica geri dön
         ResetSeriYorum();
         }
      else
         {
         // OK OK
         Retour = 1;
         // Tamponu sifirla (yeni degeri hafizaya almak için)
         SeriYorum.IdxBuff = 0;
         // Durumu ilerlet
         SeriYorum.Durum = SonrakiDurum;
         }
      }
   }
else
   {//  hata Baslangica geri dön
   ResetSeriYorum();
   }
return Retour;
}



   
//
// StringToLong
// Karakter katarindan sayiya çeviren fonksyon
long StringToLong(char *Buff, int length)
{
long Retour;
long Basamak;
signed int ii;

Retour = 0;
Basamak = 1;
for (ii = length- 1 ;ii >= 0; ii--)
   {
   Retour = Basamak * (Buff[ii]- '0') + Retour;
   Basamak = Basamak * 10;
   }
   

return Retour;
}


//
// TestInt
// Bir karakterin Rakam olup olmadigini test ediyor
int TestInt(char carac)
{
int Retour;

if (carac >= '0' && carac <= '9')
   {
   Retour = 1;
   }
else
   Retour = 0;

return Retour;
}

// **********************************************
// Ana döngü 
//
void main()
{
int ii;     // döngü Sayaci

long Komut[MX_SERVO]; // Servolara göndrilecek komut
int KomutGonder[MX_SERVO];   // Komut gönder

   // Hardware setup
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_CLOCK_DIV_2);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_INTERNAL);
   setup_timer_2(T2_DIV_BY_16,255,1);
   setup_ccp1(CCP_COMPARE_CLR_ON_MATCH);
   setup_ccp2(CCP_COMPARE_CLR_ON_MATCH);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);


    // CCP setup
    setup_ccp1(CCP_COMPARE_SET_ON_MATCH);    // Configure CCP1 to set
    CCP_1=0;                                 // C2 high now
    setup_ccp2(CCP_COMPARE_SET_ON_MATCH);    // Configure CCP1 to set
    CCP_2=0;                                 // C2 high now
    set_timer1(0);
    CCP_1 = T_MIN_SERVO;
    CCP_2 = T_MIN_SERVO;
    setup_ccp1(CCP_COMPARE_CLR_ON_MATCH);
    setup_ccp2(CCP_COMPARE_CLR_ON_MATCH);
    
    //
    //********************************
    // DEgiskenleri sifirla
    
    // CCP State Machine
   for (ii = 0; ii < MX_SERVO; ii++)
      {
       PPMState[ii] = PPM_STATE_HIGH;
       CPPFlag[ii] = 0;
       CPPNextChange[ii] = T_SIG_PERIOD - T_MIN_SERVO;
       OffSetWidth[ii] = 0;
      CumulCcp[ii] = 0;
      }
   
   // SeriYorum durum makinesi sifirlansin
   ResetSeriYorum();
   
   // Ana döngü degiskenlerini sifirla
   for (ii= 0; ii < MX_SERVO; ii++)
      {
      KomutGonder[ii] = 0;
      }
    
    // Enable interrupt
   enable_interrupts(INT_CCP1);
   enable_interrupts(INT_CCP2);
    enable_interrupts(int_rda);
   enable_interrupts(GLOBAL);
   
   
   // Ana döngü
    while(true)
      {
      
      
      // Seriden veri geldi mi ? 
      if (SeriYorum.Durum == RX_STATE_END)
         {
         // Komutlari seri modülden ana programa aktar
         for (ii = 0 ; ii< MX_SERVO; ii++) 
            {
            Komut[ii]  = SeriYorum.Val[ii];
            KomutGonder[ii] = 1;
            }
         ResetSeriYorum();
         }
         
      
      
      // Servolari tara
      for (ii = 0; ii<MX_SERVO; ii++)
        {
        // Servolar komut almaya hazir
         if (CPPFlag[ii])
            {
            // Yeni komut 
            if (KomutGonder[ii])
               {
               OffSetWidth[ii] = Komut[ii];
               KomutGonder[ii] = 0;
               }
            CPPFlag[ii] = 0;
            }
         }
     
      } // Ana döngü son
}  // Main Son

gambit1244

#2
hocam bu kod heralde normal servolar için yazılmış
ben eksik anlatmışım özür dilerim.
ben rc servo kullanıyorum
ccp modülünü kullanarak yani çıkış frekansım tim2 ayarları ile 1.2khz oluyor minimum
bunu 50 hz yapıp duty cycle oranını 5 ila 10 arasında değiştirerek motoru kontrol edeceğim

tek yapmam gereken

set_pwm1_duty(i);
komutu kullanmak olucak


aslında bi hilesini buldum işin ama sadece denemek için işimi görüyor şuan için
clock ayarlarındaki hs yerine xt yazdığım zaman işlemci nasıl oluyorsa 20 kat yavaşlıyor ve 1.2 khz olan sinyalim 60 hz e düşüyor
60 hz ile denemeler yaptım ve motor düzgün çalışıyor ama 20 kat yavaş :((


buda örnek kodum
#include <18f4580.h>     // Kullanılacak denetleyicinin başlık dosyası tanıtılıyor.
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay (clock=20000000) // Gecikme fonksiyonu için kullanılacak osilatör frekansı belirtiliyor.
#use fast_io(a) //Port yönlendirme komutları A portu için geçerli
#use fast_io(c) //Port yönlendirme komutları C portu için geçerli

void main ( )
{
   setup_psp(PSP_DISABLED);        // PSP birimi devre dışı
   setup_timer_1(T1_DISABLED);     // T1 zamanlayıcısı devre dışı
   setup_adc_ports(NO_ANALOGS);    // ANALOG giriş yok
   setup_adc(ADC_OFF);             // ADC birimi devre dışı

   set_tris_a(0x03);   // RA0 ve RA1 pinleri giriş
   set_tris_c(0x00);   // RC0, RC1 ve RC2 pini giriş

   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_16,255,16); // Timer2 ayarları yapılıyor
 
   set_pwm1_duty(13); // PWM1 çıkışı görev saykılı belirleniyor
   set_pwm2_duty(30); // PWM2 çıkışı görev saykılı belirleniyor
delay_ms(300);
   while(1) // Sonsuz döngü
   {
[email]tufan_ozbek@hotmail.com[/email] Yesterday is history. Tomorrow is a mystery. Today is a gift aslında bütün mesele bu.

justice_for_all

zamanlayici ile yazilimsal pwm yap sende cozunurlugu pek iyi olmaz ama idare eder yinede
Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay

gambit1244

Alıntı yapılan: justice_for_all - 11 Şubat 2012, 21:35:36
zamanlayici ile yazilimsal pwm yap sende cozunurlugu pek iyi olmaz ama idare eder yinede

6 kanalın duty sini sürekli değiştiricem hocam kastırmazmı aynı anda accelerometer dan bilgi de okuyup işleyeceğim :((

eğer olmazsa i2c den pwm süren bir entegre kullanıcam
[email]tufan_ozbek@hotmail.com[/email] Yesterday is history. Tomorrow is a mystery. Today is a gift aslında bütün mesele bu.

justice_for_all

pwm frekansin dusuk oldugu icin sorun olacagini zannetmiyorum ben rgb led icin 3 kanal yapmistim pek sorun yasamadim eger suan deneme sansin varsa bi dene derim bence
Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay

gambit1244

Alıntı yapılan: justice_for_all - 11 Şubat 2012, 21:47:17
pwm frekansin dusuk oldugu icin sorun olacagini zannetmiyorum ben rgb led icin 3 kanal yapmistim pek sorun yasamadim eger suan deneme sansin varsa bi dene derim bence

denedim hocam çalışıyor ama çözünürlüğü düşük dediğiniz gibi 6 tane bağlayınca nolcak bakalım :)
şuan için denemelerimde kullanırım fakat ileride bitane tlc5940 alıp kullanmayı düşünüyorum
teşekkürler
[email]tufan_ozbek@hotmail.com[/email] Yesterday is history. Tomorrow is a mystery. Today is a gift aslında bütün mesele bu.

SpeedyX

Kod RC servolar için 20ms periyotlu PPM sinyali üretiyor.

gambit1244

#8
Alıntı yapılan: SpeedyX - 11 Şubat 2012, 23:09:05
Kod RC servolar için 20ms periyotlu PPM sinyali üretiyor.
speedyx hocam ilginiz için çok teşekkür ederim

compare özelliğini hiç kullanmadığım için
bende yazılımsal pwm e gittim bu sırada
ileride sizin kodunuzuda deneyeceğim
yazılımsal pwm beklentimin üzerinde çalıştı
normal rc kumandadan yüzde 50 daha az çözünürlükte
yani kumandada 24 adım var benim programda 12 adım var
brushless i esc ile sürdüm
değişken 14 ise  en düşük   değişken 26 ise en yüksek devirde dönüyor

sanırım şuan için işimi görücek bu hatta bununla bile yapabilirim programı..
serdar çiçeğin uygulamasından tırtıkladığım kodu modifiye ettim 16 serisinde timer 8 bit benimkinde(pic18) 16 bit olduğu için. 50 hz i deneme yanılma yoluyla buldum(logic analyzerim sağolsun)

işte kod.

200ms aralıklarla en yüksek ve en düşük güçte çalışıyor

/******************************************************
      PIC16F877 İle R/C Servo Motor Uygulaması
******************************************/
#include <18f4580.h>     // Kullanılacak denetleyicinin başlık dosyası tanıtılıyor.

#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD // Denetleyici konfigürasyon ayarları

#use delay (clock=20000000) // Gecikme fonksiyonu için kullanılacak osilatör frekansı belirtiliyor.

// R/C Servo motor dönme açı değerleri
const int8 servo_derece_1[]={8,9,10,11,12,13,14,15,16,17,18};
const int8 servo_derece_2[]={18,17,16,15,14,13,12,11,10,9,8};
const int8 servo_derece_3[]={8,12,18,8,12,18,8,12,18,8,12};
int a=0;
int x=13;
int i=0,pwm=0,duty_0=0,duty_1=0,duty_2=0;
int16 zaman=0; // 16 bitlik değişken tanımlanıyor

#int_timer0  // Timer0 taşma kesmesi
void kesme ()
{
   set_timer0(65451);  // TMR0 kaydedicisine 113 değeri yükleniyor
   if (pwm==0)       // Eğer PWM değişkeni 0 ise
   {
      output_high(pin_b0); // RB0 çıkışı lojik-1
      output_high(pin_b1); // RB1 çıkışı lojik-1
      output_high(pin_b2); // RB2 çıkışı lojik-1
   }

   if (pwm>=duty_0) output_low(pin_b0);
   if (pwm>=duty_1) output_low(pin_b1);
   if (pwm>=duty_2) output_low(pin_b2);

   zaman++; // zaman değişkenini 1 arttır

   // Servo motor dönüş adımları arası bekleme süresi için
   if (zaman>17350) // 17350x114,4µsn=1.984.840µsn, yaklaşık 2msn
   {
      zaman=0;  // zaman değişkenini sıfırla
      i++;      // i değişkeni değerini 1 arttır
      if(i==11) // Eğer i değeri 11 ise-Tüm adımlar bitti ise
         i=0;   // i değişkenini sıfırla
   }

   pwm++;       // pwm değişkenini 1 arttır
   if (pwm>=65344) // pwm değeri 173'den büyük ise
      pwm=0;    // pwm değişkenini sıfırla
}

/********* ANA PROGRAM FONKSİYONU********/

void main ()
{
   setup_psp(PSP_DISABLED);        // PSP birimi devre dışı
   setup_timer_1(T1_DISABLED);     // T1 zamanlayıcısı devre dışı
   setup_timer_2(T2_DISABLED,0,1); // T2 zamanlayıcısı devre dışı
   setup_adc_ports(NO_ANALOGS);    // ANALOG giriş yok
   setup_adc(ADC_OFF);             // ADC birimi devre dışı
   setup_CCP1(CCP_OFF);            // CCP1 birimi devre dışı
   setup_CCP2(CCP_OFF);            // CCP2 birimi devre dışı


   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_4); // Timer0 ayarları belirtiliyor
   set_timer0(65333);  // TMR0 kaydedicisine 113 değeri yükleniyor

   enable_interrupts(int_timer0); // Timer0 taşma kesmesi aktif
   enable_interrupts(global);     // Aktif edilen tüm kesmelere izin ver

   output_b(0x00);  // İlk anda B portu çıkışı sıfırlanıyor

duty_0=x;
delay_ms(3000);//13 boşta   14 start 26 son 12 kademeli
   while(1)  // Sonsuz döngü
   {
   for (a=1;a<=10;++a)
{

      duty_0=14;
     
      delay_ms(200);
  
    duty_0=26;
       delay_ms(200);
}
     }
   }
[email]tufan_ozbek@hotmail.com[/email] Yesterday is history. Tomorrow is a mystery. Today is a gift aslında bütün mesele bu.

justice_for_all

kodda pwmin 50 hz oldugundan eminmisiniz?

kodda bi noktaya daha degineyim timer0 degerinin icerigini biraz yuksek tutarsaniz kodlarinizda aksama olma olasiligi daha az olur bence pwm karsilastirmada degeri dusurun timer degerini yukseltin orantili olarak simdi mainda kodlar az oldugu icin sorun olmayabilir ama main kisminda kodlar fazlalastikca isler aksayabilir.
Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay

gambit1244

hocam nasıl oldugunu hiç sormayın ama tam 49.9 hz :D
yarın dediklerinizle ilgilenicem teşekkürler
[email]tufan_ozbek@hotmail.com[/email] Yesterday is history. Tomorrow is a mystery. Today is a gift aslında bütün mesele bu.

rree

#11
Timer kesmelerinden birini kullanmıştım bir ara . Yazılım kısmı kesme programı 16 bit sayaç değişkeni ile if komutu ile karşılaştırma işlemi yapmıştım. Frekans 50 hz gibi düşük değerlerde idi. Çözünürlük 16 bit olunca frekan oldukça düşüyordu.Dspic lerin bazıları 16 bit pwm e sahip onları doğrudan kullanılabilr.

gambit1244

#12
sonunda 2 programı birleştirdim
ve karşılaştırma değerinide düşürdüm
program kumandadan gelen pwm i okuyup 0-12 arası bir değer verip pwm çıkış olarak veriyor
gayet güzel çalışıyor birde accelerometer ilave ettimmi tamamdır en zor kısmı o olucak sanırım

16 bit pwm olunca 50 hz e düşüyor yani?
tamam hocam bunu bi araştırıcam teşekkürler


edit:PIC24EP256GU814 diye bir entegre buldum ccs c de support desteği var fakat benim complier eski olduğu için header dosyası bende yok
16 bit pwm + 10 kanal desteği var ve 60 mips gücünde ne dersiniz boyle birşey alıp işi büyütsemmi üstadlarım?
[email]tufan_ozbek@hotmail.com[/email] Yesterday is history. Tomorrow is a mystery. Today is a gift aslında bütün mesele bu.