M

16 adet servo sürmek

Başlatan mustafa_60, 03 Ağustos 2013, 02:08:20

mustafa_60

merhaba herkeze iyi forumlar;
16 servo motor ile hexapod robot yappmak istiyorum. bir çok yol denedim ancak bi türlü sonuca ulaşamıyorum aslında nasıl bir yol izleyecegimide bilmiyorum. bir tane kesin yol bulsam yönelip işe koyulacagım...sizden istegim bana bi mantık haritası oluşturabilecek bi yol göstermek.algoritma lazım. çok kasvetli iş. ve bu yüzden lütfen bilgisine güvenen yazarsa memnun olurum yanlış anlaşılmasın lütfen.nereye yazsam acayip acayip şeyler söylüyolar.

arkadaşlar denedigim yollar şunlar;
1-tlc5940 ile 16 servo kontrolu
2-74hc595 ile 16 servı kontrolü
3-ccs c for döngüsü ile 16 servo kontrolü


ete

Mesajında verdiğin kısıtlama bence yanlış. Sonuçta bu sistemi kimse denememiştir. İşi  bilenler mutlaka kafayı çalıştırıp fikir üreterek sana vereceklerdir. Bu fikir sağlıklı olabilir, olmayabilirde. Değerlendirmeyi senin yapman gerekir. Yada deneyerek sonucu alman gerekebilir.
Kimse düşündüğü şeyin ne kadar sağlıklı olduğunu önceden kesitiremez. Buna bende dahilim. Bu nedenle bu mesajı yazarken tereddüt ettim. Vereceğim akıl ne kadar sağlıklı diye düşünmedim desem yalan olur. Vaz geçebilirdim de.
Her neyse bence fikir üretebilen her kes fikrini söylemeli ki arasından bir tanesini mantık yolu ile seçip deneyebilesin.

Şimdi gelelim asıl konumuza, bu çalışma için öncelikle elde neler var ve bunlarla neler yapılması gerekiyor ortaya koyulmalıdır.
ELimizde 16 adet servo var. Servo lar 0,5-2 ms aralığında puls ler ile çalışırlar. Ancak sinyalin peryodu 20 ms olmalıdır.
Yani servoya 2ms puls verdiğin zaman 18 ms de low peryodu olmalıdır. 0,5m puls verdiğin zaman 19,5ms low süresi olmalıdır.
Kısaca uygulanacak sinyal 50 hz lik bir sinyal olacak ama duty değeri  %2,5 ile %10 arasında değişecektir.
16 kanal için duty değerleri ayrı ayrı olacak ve bunlar bir şekilde program içinde ayarlanabilkecektir.
Burada önemli olan bu sinyalin nasıl üretilip servolara aktarılacağıdır. Önce sinyalleri nasıl üretebiliriz ona bakalım sonra aktarma işine kafa yorarız.
50 Hz lik bir sinyal normal şartlarda pic işlemcilerin HPWM olarak üretebilecekleri bir sinyal değildir. Üretebilirler ancak çok düşük frekanslı kristal kullanılması gerekir.  Zaten tek bir sinyal bize yetmiyor. O yüzden HPWM işini bir kenara bırakacağız.
O halde birinci yöntem olarak kesme kullanarak bunu yapabiliriz diyebiliriz.
Puls süremiz min 500us olacağı için bunu 5 parçaya bölersek 100us lik peryotlarla kesme oluşturup kesmeleri sayarak işlemi yerine getirebiliriz. Bir örnek vermek gerekir ise 1 nolu servo motora diyelimki 0,5ms puls 19,5ms de low süresi vereceğiz.
Her bir kanalın iki değişkeni olacak . Birisi PULS süresini tutacak diğeride kesmede bu süreyi sayacak.  O halde  1 nolu kanal için değerler şöyle olmalı. Puls Süresi (500/100=5) Low süresi ise 20000/100=200 ve 200-5=195 şeklinde olacaktır. 
Böylece  sayac1 önce 5 adet kesme sayacak ve bu süre zarfında kanal-1 çıkışı High olacak.
5. kesme sonunda kanal çıkışı low yapılıp 195 kesme sayılarak low sinyali verilecektir.
Benzer şekilde kanal-2 de diyelimki 0,8ms lik bir puls uygulanacak. O halde önce kanal-2 high yapılıp, Sayac-2 , 8 adet puls saydıktan sonra Kanal-2 çıkışı low yapılacak ve 192 kesme sonunda tekrar konum değiştirecektir.
Peki diyelimki 16 adet kanala program içinde süre verdik.
Kesme oluştuğunda her bir kanalın kesme sayacını nasıl saydıracağız.
Kesme oluşur oluşmaz hemen 0-15 arası bir döngü kuracağız.
Döngü içinde her bir sayacın durumunu kontrol edeceğiz.

   SAYAC(I)=SAYAC(I)-1
   IF SAYAC(I)=0 then
      Toggle Kanal.0(I)  'bu satırı aşağıda ayrıca açıklayacağım
       IF KANAL.0(I)=1 then
           SAYAC(I)=SURE(I)
       ELSE
           SAYAC(I)=200-SURE(I)
       ENDIF
    ENDIF
Görebileceğin gibi 0-15 arası 16 adet kanalın kontrolünü bu satırlarla sağlayabiliyorum.
Bu satırlarda kritik nokta kanal(I) değişkenidir. İndex değişkeni ile kanallara nasıl ulaşacağım bu önemlidir.
Zira kanalların konum değiştirmesini index değişkeni ile sağlayamazsan döngü hiç bir işe yaramayacaktır.
Bu sorunun çaresini şöyle bulabiliriz. KANAL  şeklinde bir Word değişkeni tanımlarsak Byte0, 8 bitlik bir portu,  Byte1 ise diğer bir portu kontrol edebilir.
Böylece Kanal isimli değişkende Kanal çıkışlarının high yada low olacaklarını belirler döngü sonunda bu bilgiyi portlara yazarız.
Bu yöntem bize kanal çıkışları için 74HC595 kullanma imkanınıda verebilir. Zira 2 x 8 bitlik KANAL bilgisini 2 adet 595'e yazarsak kanal çıkışlarını bu şekilde de kontrol etmiş olabiliirz.

16 kanal için kontrol işleminin Kesme etiketi içinde yapılması uzun bir kod gerektirir ve buna bağlı komut gecikmeleri işi birazcık aksatabilir. Bunu bir nebze olsun azaltmak için epeyce yüksek bir frekansta çalışılmalı. Gerekirse 48Mhz veya olabiliyorsa daha yüksek frekanslarda çalışarak kod gecikmeleri minimuma indirilmelidir.

Bu şekilde 16 kanaldan istenilen servo palslerini almak mümkün olur diye düşünüyorum.

Diğer bir metod da TLC5940 kullanılabilir diye düşünüyorum. Data sheet'e şöyle bir baktımda mümkün gözüküyor.
Her bir kanal için 12 bitlik PWM duty değeri verilebiiyor. Bu size daha hassas bir süre ayarı sağlayabilir. Ancak min frekans verdikleri formüle göre 193 hz gibi gözüküyor. Bunun çıkışlara ne şekilde yansıyacağını bilemiyorum. Birebir yansıyor ise bu entegreyi kullanmak biraz zor gözüküyor.

Şayet verdiğim birinci yöntemi daha önce denemedin ise deneyebilirsin. Elbette verdiğim kod örneğinin biraz daha işlenmesi gerekebilir. Anladığım kadarı ile CCS de çalışacaksın. Ne yazıkki bu konuda kod yardımı yapamam. Ama akılı basic kullanarak veririm sen CCS ye dönüştürebilirsin.

Umarım bir yardımım dokunmuştur.

Ete

mustafa_60

merhaba hocam k.bakmayın sizi kırdıysam sizden  ve forum kullanıcılarından özür dilerim.öncelikle index degişkenini anlamadım kanalların konumlarını index ile nasıl degişcez
2. olarak ''Böylece Kanal isimli değişkende Kanal çıkışlarının high yada low olacaklarını belirler döngü sonunda bu bilgiyi portlara yazarız.'' demişsiniz döngüye kadar tamam ancak örnek vermek gerekirse 1. pine 0.7 ms lik pals verdik ve bunu 1. pine yolladık fakat 74hc595 e bunu nasıl iletcez yani sen 1. pinine 0.7 ms lik pals ver nasıl diyecegiz bu kısmı anlayamadım.
3. olarak iletişim protokolü kullanabilirmiyiz mesela spi yada ı2c gibi daha kolay olmazmı_?

mustafa_60

bide unutmadan ben ccs c de bi şekilde kesme üretebiiyorum ancak bu kesmeleri bölme olayını nasıl kavrayabilirim örnekleri varsa sizde yollayabilirmisinz.

mustafa_60

zamanında şöyle döngülerle bi program yazmıştım ancak başarılı olmamıştı.


char srv1=100,srv2=100,srv3=100,srv4=100;
char srv5=100,srv6=100,srv7=100,srv8=100;
char srv9=100,srv10=100,srv11=100,srv12=100;

#define servo1  PORTC.F0
#define servo2  PORTC.F1
#define servo3  PORTC.F2
#define servo4  PORTC.F3
#define servo5  PORTC.F4
#define servo6  PORTC.F5
#define servo7  PORTC.F6
#define servo8  PORTC.F7
#define servo9  PORTD.F0
#define servo10  PORTD.F1
#define servo11  PORTD.F2
#define servo12  PORTD.F3




void rc_servo_1(char x ){  // 1 tane RC servo kotrol etmek için
char i,j,k;
for (j=1;j<=x;j++){
   for (i=1;i<=10;i++){
               servo1 = 1;
               for(k=0;k<srv1;k++) delay_us(3);
         servo1 = 0;
         delay_ms(15);
       }
  }
}

void rc_servo_2(char x ){  // 1 tane RC servo kotrol etmek için
char i,j,k;
for (j=1;j<=x;j++)
  for (i=1;i<=10;i++){
               servo1 = 1;
         for(k=0;k<srv1;k++) delay_us(3);
         servo1 = 0;

               servo2 = 1;
         for(k=0;k<srv2;k++) delay_us(3);
         servo2 = 0;
         delay_ms(15);
      }
}

void rc_servo_3(char x ){  // 1 tane RC servo kotrol etmek için
char i,j,k;
for (j=1;j<=x;j++)
  for (i=1;i<=10;i++){
               servo1 = 1;
         for(k=0;k<srv1;k++) delay_us(3);
         servo1 = 0;

               servo2 = 1;
         for(k=0;k<srv2;k++) delay_us(3);
         servo2 = 0;

               servo3 = 1;
         for(k=0;k<srv3;k++) delay_us(3);
         servo3 = 0;

         delay_ms(14);
      }
}

void rc_servo_6(char x ){  // 1 tane RC servo kotrol etmek için
char i,j,k;

for (i=1;i<=x;i++){
               servo1 = 1;
         for(k=0;k<srv1;k++) delay_us(3);
         servo1 = 0;

               servo2 = 1;
         for(k=0;k<srv2;k++) delay_us(3);
         servo2 = 0;

               servo3 = 1;
         for(k=0;k<srv3;k++) delay_us(3);
         servo3 = 0;

               servo4 = 1;
         for(k=0;k<srv4;k++) delay_us(3);
         servo4 = 0;

               servo5 = 1;
         for(k=0;k<srv5;k++) delay_us(3);
         servo5 = 0;

               servo6 = 1;
         for(k=0;k<srv6;k++) delay_us(3);
         servo6 = 0;

         delay_ms(10);
      }
}

void rc_servo_8(char x ){  // 1 tane RC servo kotrol etmek için
char i,j,k;

for (i=1;i<=x;i++){
               servo1 = 1;
         for(k=0;k<srv1;k++) delay_us(3);
         servo1 = 0;

               servo2 = 1;
         for(k=0;k<srv2;k++) delay_us(3);
         servo2 = 0;

               servo3 = 1;
         for(k=0;k<srv3;k++) delay_us(3);
         servo3 = 0;

               servo4 = 1;
         for(k=0;k<srv4;k++) delay_us(3);
         servo4 = 0;

               servo5 = 1;
         for(k=0;k<srv5;k++) delay_us(3);
         servo5 = 0;

               servo6 = 1;
         for(k=0;k<srv6;k++) delay_us(3);
         servo6 = 0;

               servo7 = 1;
         for(k=0;k<srv7;k++) delay_us(3);
         servo7 = 0;

               servo8 = 1;
         for(k=0;k<srv8;k++) delay_us(3);
         servo8 = 0;

         delay_ms(10);
      }
}


void rc_servo_12(char x ){  // 1 tane RC servo kotrol etmek için
char i,j,k;

for (i=1;i<=x;i++){
               servo1 = 1;
         for(k=0;k<srv1;k++) delay_us(3);
         servo1 = 0;

               servo2 = 1;
         for(k=0;k<srv2;k++) delay_us(3);
         servo2 = 0;

               servo3 = 1;
         for(k=0;k<srv3;k++) delay_us(3);
         servo3 = 0;

               servo4 = 1;
         for(k=0;k<srv4;k++) delay_us(3);
         servo4 = 0;

               servo5 = 1;
         for(k=0;k<srv5;k++) delay_us(3);
         servo5 = 0;

               servo6 = 1;
         for(k=0;k<srv6;k++) delay_us(3);
         servo6 = 0;

          servo7 = 1;
         for(k=0;k<srv7;k++) delay_us(3);
         servo7 = 0;

               servo8 = 1;
         for(k=0;k<srv8;k++) delay_us(3);
         servo8 = 0;

               servo9 = 1;
         for(k=0;k<srv9;k++) delay_us(3);
         servo9 = 0;

               servo10 = 1;
         for(k=0;k<srv10;k++) delay_us(3);
         servo10 = 0;

               servo11 = 1;
         for(k=0;k<srv11;k++) delay_us(3);
         servo11 = 0;

               servo12 = 1;
         for(k=0;k<srv12;k++) delay_us(3);
         servo12 = 0;

         delay_ms(10);
      }
}


char txt[4];
char srv = 100,i;                  // char tipinde mod ve i değişkenleri tanımlanır

void Bekle_20ms(char x){           // Servolara konumları devamlı
  rc_servo_12(x);                   // gönderilerek 20ms beklenir
}

void Servo(char s,char p){         // S değişkeni ile ifade edilen
  if (s == 1) srv1 = p;             // servoya p değişkeni ile ifade
  if (s == 2) srv2 = p;             // edilen konumları aktarılır
  if (s == 3) srv3 = p;
  if (s == 4) srv4 = p;
  if (s == 5) srv5 = p;
  if (s == 6) srv6 = p;
  if (s == 7) srv7 = p;
  if (s == 8) srv8 = p;
  if (s == 9) srv9 = p;             // servoya p değişkeni ile ifade
  if (s == 10) srv10 = p;             // edilen konumları aktarılır
  if (s == 11) srv11 = p;
  if (s == 12) srv12 = p;
  rc_servo_12(1);
}


void ileri(){
    bekle_20ms ( 1 ); // 1.Adım    // servolara konumları gönderilir

   servo (1,70);
   servo (2,70);
   servo (3,70);
   servo (4,70);
   servo (5,70);
   servo (6,70);
   servo (7,70);
   servo (8,70);
   servo (9,70);
   servo (10,70);
   servo (11,70);
   servo (12,70);                // Robot ileri gidecek şekilde
             bekle_20ms ( 1 ); // 1.Adım    // servolara konumları gönderilir
   servo (7,110);
   servo (9,110);
   servo (11,110);
   servo (1,140);
   servo (3,140);
   servo (5,140);
   servo (7,148);
   servo (9,148);
   servo (11,148);
   servo (8,110);
   servo (10,110);
   servo (12,110);
   servo (2,130);
   servo (4,160);
   servo (6,176);
   servo (8,148);
   servo (10,148);
   servo (12,148);





     }

void geri(){
bekle_20ms ( 1 ); // 1.Adım    // servolara konumları gönderilir

   servo (1,70);
   servo (2,70);
   servo (3,70);
   servo (4,70);
   servo (5,70);
   servo (6,70);
   servo (7,70);
   servo (8,70);
   servo (9,70);
   servo (10,70);
   servo (11,70);
   servo (12,70);                // Robot ileri gidecek şekilde                      // Robot geri gidecek şekilde
   bekle_20ms ( 10 ); // 1. Adım    // servolara konumları gönderilir
   servo (12,148);
   servo (10,148);
   servo (8,148);
   servo (6,160);
   servo (4,70);
   servo (2,130);
   servo (12,110);
   servo (10,110);
   servo (8,110);
   servo (11,70);
   servo (9,148);
   servo (7,148);
   servo (5,140);
   servo (3,140);
   servo (1,140);
   servo (11,110);
   servo (9,110);
   servo (7,110);
   servo (1,140);
   servo (3,140);
   servo (5,140);
   servo (7,110);
   servo (9,110);
   servo (11,110);

}

void sag(){                                // Robot sağa dönecek şekilde
    bekle_20ms ( 10 ); // 1.Adım           // servolara konumları gönderilir

}

void sol(){                                // Robot sola dönecek şekilde
    bekle_20ms ( 10 ); // 1.Adım           // servolara konumları gönderilir

}

void main(){
  TRISC    = 0X00;      //C PORTU ÇIKIŞ
  PORTC    = 0X00;     //C PORTU SİLİNİR
  TRISD    = 0X00;     // D portu çıkış yapılır
  PORTD    = 0X00;     // D portu silinir
  TRISE    = 0X00;     // E portun çıkış yapılır

  ADCON1   = 7;        // ADC kapatılır
  TRISA.F0 = 1;        // sağ engel algılayıcı giriş yapılır
  TRISA.F1 = 1;        // sol engel algılayıcı giriş yapılır
  TRISA.F2 = 1;       // ileri
  TRISA.F3 = 1;       //GERİ
  TRISA.F4 = 1;      // SAG
  TRISA.F5 = 1;       //SOL
      bekle_20ms ( 1 ); // 4.Adım
  while(1){
        PORTE.F0 = ~PORTA.F0; // sağ engel algılayıcısının değeri E0 LED'inde görünür
        PORTE.F1 = ~PORTA.F1; // sol engel algılayıcısının değeri E0 LED'inde görünür
        if((PORTA.F2 ==0) )  ileri();

       if((PORTA.F3 ==0) )  geri();

       if((PORTA.F4 ==0) )  sag();

       if((PORTA.F5 ==0) )  sol();


        if ((PORTA.F0 == 0)&&(PORTA.F1 == 0)) ileri();
        // Engel yok , engel olmadığı sürece ileri gidilir

        if ((PORTA.F0 == 1)&&(PORTA.F1 == 0)) sol();
        // Sağda engel var , engele çarpmamak için sola dönülür

        if ((PORTA.F0 == 0)&&(PORTA.F1 == 1)) sag();
        // Solda engel var , engele çarpmamak için sağa dönülür

        if ((PORTA.F0 == 1)&&(PORTA.F1 == 1)){         // Karşıda engel var
             for (i = 1;i<=6;i++) geri();            // 6 adım geri gidilir
             for (i = 1;i<=6;i++) sag();             // 6 adım sağa dönülür
       }
   }                                                 // Tekrar başa döner
}

ete

Her bir sayacın bir bölme oranı vardır.  TMR0 sayacını ele alalım. OPTION_registeri bölme oranını ayarlar.
Şayet 1/1 bölme oranı alırsak sayac işmecinin her bir pulsinde 1 sayar. 4Mhz de çalışanbir işlemci 1us lik bir peryodla çalışır. Bu durumda TMR0 de her bir 1us de bir sayar. Bölme oranını 1/2 yaparsan 2 işlemci palsinde TMR0 bir sayar. Bu sayacın 2u sn de bir sayması demektir. Bölme oranını 1/64 alırsan her 64 puls de bir sayacağı için bölme işlemi önem kazanır.
Bölme işini C de nasıl ayarlıyorsunuz bilemiyorum. Ancak fonksiyon parametresinde bölme oranıda veriliyor sanıyorum.
SOnuçta Kesme kısmında her bir çıkışın ne zaman high ne zaman low olacağını belirlemektesin. Aradaki süre işini kesme
ayarlıyor.   Kesme de elinde bir değişken var CIKIS diyelim CIKISA=%10110011 ve CIKISB=%00110110 şeklinde ayarlandığını düşünürsek. Bunu SPI ile 74595 ler aktardığın zaman süre işide otomatik ayarlanmaktadır. Zİra bilginin shift registerlere aktarılması onlarla ifade edilen mikrosaniye süresinde shift registerlere (595) aktarılır. Böylece beklenen PWM sinyalini shift register çıkışlarınıda görebilirsin. Süre işi dediğim gibi daima kesme içinde ayarlanmaktadır.

Haberleşme protokolünden neyi kast etmişsin anlamadım doğrusu. Normalde alindeki alternatifler şunlar.
Ya 40 pinli bir işlemci kullanıp 16 adet pini (2 adet Port eder) çıkış olarak kullanacaksın yada 18 pinli bir işlemci kullanıp buna 3 pin kullanarak 2 adet 74595 i seri bağlayıp kullanacaksın. Birinci alternatifte bir haberleşme ihtiyacın yok. İkincisinde 595 lere bilgi aktarmak için SPI protokolünü kullanman gerekiyor.

Ete

mustafa_60

hocam çok teşekkür ederim sabırla cevap verdiginiz için zira kafamda çogu şey oluşmuş durumda.

'' Kesme de elinde bir değişken var CIKIS diyelim CIKISA=%10110011 ve CIKISB=%00110110 şeklinde ayarlandığını düşünürsek. Bunu SPI ile 74595 ler aktardığın zaman süre işide otomatik ayarlanmaktadır. Zİra bilginin shift registerlere aktarılması onlarla ifade edilen mikrosaniye süresinde shift registerlere (595) aktarılır. Böylece beklenen PWM sinyalini shift register çıkışlarınıda görebilirsin. Süre işi dediğim gibi daima kesme içinde ayarlanmaktadır.''

hocam merak ettigimi konu şu mesela siz CIKIŞA degişkeninde 1. pini 1 yapmışsınız biz programda kesme oluşturup bu pine nasıl 0.7ms pals verip aktaracagız. bana bu olayı bi komut satırı şeklinde örnek vererek açıklarsanız çok memnun olurum.

ete

#7
Her 100 us de bir kesme oluşturuyoruz. 16 adet servo sayacımız var bunları saydırıyoruz. Bu sayma esnasında 16 adet çıkıştan kimisi. High kimisi low oluyor. Sonra bu çıkışların son durumunu cıkıs isimli değişkende tutuyor ve aynen 595 lere aktarıyoruz.
Daha iyi anlaman için örnekle açıklayayım.
Diyelimki aşağıdaki çıkış formatını 16 adet çıkışta görmek istiyoruz.
Cıkıs-0=1 ms. ( 1000 us eder kesme bazında 10 kesme süresidir 1000/100=10)
Cıkıs-1=0,7 ms (700 us eder kesme olarak 7 kesme süresi)
Cıkıs-2=0,8 ms (800us eder ve kesme olarak 8 kesme)
Cıkıs-x ......
İlk kesme oluştu kesme içinde ;
For I= 0 to 15
  Sayac(I)=sayac(I)-1
     If sayac(I)=0 then
         Toggle CIKIS.0(I)
          Sayac(I)=sure(I)
          If Cıkıs.0(I)=0 then sayac(I)=200-sure(I)
     EndIf
Next
Shiftout dta, clk,1,[cıkıs\16]
Pulsout kilit,1
Intcon.2=0
Resume
Enable
İşte bu kadar.
Şimdi lafla iredeleyelim ne yaptığımızı
Öncelikle hemen belirteyim bu bşr ham düşüncedir iyileştirilmesi gerekebilir. Mesela her kesme sonunda shift registerlere bir şey aktarmak gerekmez ancak sayaclardan birisi konum değiştirmiş ise aktarmak gerekir. O halde bşr tanede bit değişkeni kullanıp aktar gibi aktar=1 olmuşöise shift registerler çalışır değilse konum değişmediği için çalışmaz. Böylece 16 çıkıştan birisi bile konum değiştirse shift registerde de konum değişecek değilse değişmeyecektir.
Bu işlemi her 100 us de bir yaptığımız için shift register çıkışında rahatlıkla 0,7 0,5 gibi high sürelerini görebilmemiz gerekir. Umarım ne yapmak istediğimi anlamışsındır.
İrdelemeye devam edelim.
İlk kesmede çıkışları 595 lere aktardık diyelim.
İkinci kesmede sayaclar saydı ama henüz konum değiştiren olmadı kesmeden çıktık
Üçüncü kesmede konum değiştiren olmadımkesmeden çıktık
Dördüncüde bir şey olmadımkesmeden çıktık ama sayaclar hala sayıyor
Beşinci kesmede bir şey olmadı
Altıncıda bir şey olmadı
Yedinci kesmede sayac-1 sıfırlandı ve cıkıs.1 biti konum değiştirdi aktar=1 yapıldı ve değişen bit konumu 595 lere aktarıldı böylece bir nolu cıkış low oldu diğerleri hala high da
Sekizin ci kesmede cıkıs-2 konum değiştirdi ve bundeğer 595 lere aktarıldı böylece cıkısA(ilk 8 bit) =%11111001 şeklini aldı
Bu mantıkla sistem devam eder ve sonuçta sen çıkışlarda  aradığın süreleri görmüş olursun.
Hala bu mantığı anlamadı isen yazdıklarımı baştan bir kez daha okumanı öneririm.
Ete

mustafa_60

1-Shiftout dta, clk,1,[cıkıs\16]
Pulsout kilit,1
Intcon.2=0
hocam pic basic kullanmadıgım için bu satırda ne yaptıgınızı anlayamadım açıklarsanız sevinirim .

2-hocam biz timer0 ı 100uslik periyotlara bölecegiz ancak ben bunu yapamadım Örneğin 20 Mhz kristal frekansı ve 1:16 presecalar değeri için timer0 değerinin 1 artması için gereken süre

1/((20000000/4)/16) = 3,2us  çıkıyo bunun için kristal frekansınımı yükseltcez.

ete

Shiftout komutu bir veya birden fazla byte bitlerinin clk plasi eşliğinde data pininden çıkartılması yada aktarılması işlemini yapar.
Komuttaki 1 parametresi yollama işinin yüksek değerlikli bit den (bit 7) başlayacağını belirler.
595 lerin bir latch (kiit) bacağı vardır. Aktarılan bilgi anında çıkışta gözükmez. Kilit pinine bir puls verilmesi gerekir. Bu pals sayesinde aktarılan bilgi çıkışlara ayrıca aktarılır. 1 parametresi 10 us lik bir puls verildiğini gösterir ancak puls süresi 2 us den 10 us ye kadar bir değerde olabilir.

Timer hesabına gelince işlemci kristal frekansını 4 e bölerek komut çevrimi elde eder.  Senin işinde hız önemli. Bence en az 20 mhz de çalışman gerekir.
Hesabı şöyle yapmalısın.
4 mhz kristal için;
1 komut çevrimi 1 us dir 100 us için tmr0 ın 100 sayması gerekir. 1/1 bölme oranı ile olabilir ama normalde tmr0 için en küçük bölme oranı 1/2 dir. O halde tmr0 ın 50 sayması gerekir. O halde 256-50=206. Bu tmr0 ön yükleme değeri olacaktır. aslında biraz komut gecikmesi di hesaba katılmalıdır bu nedenle ön yükleme değeri 209 olarak alınmalıdır.
Bölme oranı 1/1 alınırsa.  100 us ve 7 us komut gecikmesi ile sayılacak rakam 100-7=93
256-93=163 olarak ön yükleme değeri bulunur.

20 Mhz için;
1 komut çevrimi 0,2 us 100/0,2=500 us eder 256 dan büyük olduğu için bölme kullanmak gerekir.
1/2 bölme oranı ile ön yükleme değeri 9 olarak hesaplanır. (500-7=493/2=247 ve 256-247=9)
1/4 bölme oranı ile 493/4=124 ve 256-124=132. Olarak ön yükleme değeri bulunur.
Ön yükleme değeri ne demek biliyorsundur umarım. Sayacı bu sayıdan başlatıyorsun 256 ya ulaştığı zaman otomatikman 100 us geçmiş oluyor ve aynı zamanda da kesme oluşuyor.
Bu nedenle kesme içinde aynı önyükleme değerinin tmr0 a yeniden verilmesi gerekir.
Kesme oluştuğu zaman Intcon.2 biti (flag) set edilir. Kesme içinde bu biti sıfırlayıp çıkman gerekir aksi halde yeniden kesme oluşmaz.
Umarım anlaşılmıştır.
Ete

mustafa_60

anladım hocam genel mantıgı anladım ancak işte program farkından dolayı sizin orda kullandıgınızı benim ccs c de uygulamam çok farklı bu nedenle  baya bi araştırma yapmam gerekiyo kısmetse 1 -2 güne uygulamaya geçerim bi sıkıntı olursa yine yazarım buraya hocam. iyi günler.

Powered by EzPortal