News:

Değerli Üyelerimiz,
Forumumuzun altyapısını, sizlere daha iyi bir deneyim sunabilmek adına güncelledik. 2.0.14 sürümünden 2.1.4 sürümüne geçiş yaparak güvenlik, performans ve kullanım kolaylığı açısından önemli iyileştirmeler sağladık.

Main Menu

18f4550 Hakkında Sorular.

Started by x-nomek, 23 October 2012, 17:12:10

Previous topic - Next topic

x-nomek

Pic18f4550 yeni başladım başka forumlarda biraz araştırdım ve Osilator ayarları 16f göre farklı geldi tam anlayamadım.
Şimdi ben USB kısmını kullanmayacağım (Şu anlık Usb ile işim yok) ve CPU hızını da 48 Mhz çalışmasını istiyorum bu iş için #fuses ayarlarından neleri aktif neleri kapatacağımı tam olarak anlayamadım. CCS C kullanıyorum. Mesela usb kullanmayacağımı belirtmek gerekiyor mu ?gerekiyorsa hangi komutu yazacağım PIC' e bağlayacağım Kristal 20 mhz veya farklı da olabilir.Yardım ederseniz sevinirim.
ve 16f628a da kendi içindeki gibi 18f4550 nin osilatör varmıdır.
18f lerde kesme işlemi bittikden sonra pic programda kaldıgı yerden degil en baştan tekrar başlaması için ne yapabilirim (bir kaç araştırma yaptım return ve cpu_reset gibi ccs c komutları kullanmadan POP diye bir asm komutu varmış bu komut 18f ler içinmiş  ama tam olarak nasıl kullanılır anlayamadım .)

smit

You do not have permission to view links! Sign up or Log in
Pic18f4550 yeni başladım başka forumlarda biraz araştırdım ve Osilator ayarları 16f göre farklı geldi tam anlayamadım.
Şimdi ben USB kısmını kullanmayacağım (Şu anlık Usb ile işim yok) ve CPU hızını da 48 Mhz çalışmasını istiyorum bu iş için #fuses ayarlarından neleri aktif neleri kapatacağımı tam olarak anlayamadım. CCS C kullanıyorum. Mesela usb kullanmayacağımı belirtmek gerekiyor mu ?gerekiyorsa hangi komutu yazacağım PIC' e bağlayacağım Kristal 20 mhz veya farklı da olabilir.Yardım ederseniz sevinirim.
USB kullanmayacağını belirtmene gerek yok. işlemciye 20Mhz kristal bağlayıp aşağıdaki ayarları yaparsan işlemci 48Mhz'de çalışır.
#fuses HSPLL,USBDIV,PLL5,CPUDIV1
#use delay(clock=48000000)


You do not have permission to view links! Sign up or Log in
ve 16f628a da kendi içindeki gibi 18f4550 nin osilatör varmıdır.
Vardır. Kullanabilmek için
#fuses INTHS,USBDIV,PLL5,CPUDIV1
#use delay(clock=8000000)

programının main döngüsünün içinede

setup_oscillator(OSC_8MHZ|OSC_INTRC|OSC_31250|OSC_PLL_OFF);

Yazman gerekir.

You do not have permission to view links! Sign up or Log in
18f lerde kesme işlemi bittikden sonra pic programda kaldıgı yerden degil en baştan tekrar başlaması için ne yapabilirim (bir kaç araştırma yaptım return ve cpu_reset gibi ccs c komutları kullanmadan POP diye bir asm komutu varmış bu komut 18f ler içinmiş  ama tam olarak nasıl kullanılır anlayamadım .)
işlemci en baştan işlem yapsın istiyorsan interrupt bittikten sonra cpu_reset komutunu çalıştırırsen işlemci kendini resetleyerek enerjiyi ilk verdiğin andaki yapması gereken işlemleri yapar. Bunu önermiyorum çünkü her defasında tekrar osilatör tanımlayacak tekrar pinleri tanımlayacak. Bu durum önerilmez.

Push ve POP komutları kesmeye gittikten sonra program kaldığı yeri unutmasın diye kullanılır. kesmeye gitmeden mnce push komutları ile bazı değişkenler ve Programcounter saklanır. Kesme bittikten sonrada POP komutları ile bu bilgiler geri okunur.

sen yazmak istediğin programı daha ayrıntılı anlatır veya kod paylaşırsan daha çok yardımcı olabiliriz.

x-nomek

#2
Verdiginiz cvplar için teşekür ederim
You do not have permission to view links! Sign up or Log in

setup_oscillator(OSC_8MHZ|OSC_INTRC|OSC_31250|OSC_PLL_OFF);

kodunda su kısmı anlamadım OSC_31250 nedir nedemekdir?


Ben deneme olarak uzakdan kumanda yapcam 6 buton ile  uzakdaki 6 ledi  çaliştircam
Örnek ben 1 numaralı butona elim basılı oldugu müdetçe alıcıda ki bir numaralı led yanacak elimi çektigim an sönecek
bende bu işlemi kesmenin içinde yaptırmayı düşündüm yaptım devrede çalişiyor şu an


#int_RDA
void serial_isr()
{
{
    Bilgi=getc();
   
     Disable_interrupts(GLOBAL);     
       
    {if(Bilgi=='A') {LEDA=1} // alıcıya a A bilgisi geldimi LedA yı yakacak
    komutlar devam ediyor...
    enable_interrupts(GLOBAL);
}
void main()

{     Ayarlar();
       
     
      while(1)
      {
       delay_ms(100);
       PORTA=(0B00000000);   //Kesmeden cıktıkdan sonra Portları sıfırlıyor
      }
}

void ayarlar()
{
   Set_tris_B(0B00000010);
   Set_Tris_A(0B00000000);
   clear_interrupt(INT_RDA);
   clear_interrupt(INT_EXT);
   Disable_interrupts(GLOBAL);
  // PORTA=(0B00000000);
  // PORTB=(0B00000000);
   port_b_pullups(TRUE);

   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_uart(True);
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
}


Şimdi benim problemim şu ben birinci butona devamlı basılı tuttuğum zaman LedA belli bir Periyota yanıp sönuyor bende delay_ms gecikmesini artırdım ve bu belli Periyota yanıp sönmesini dahada azaldı ornek verecek olursak 10 sn bir yanıp sönerken 20 sn bir yanıp sönmeye başladı(led hızlı bir şekilde yanıp sönüyor) bende sonradan anladım artık pic kesmeye girmeden önceki yeri hafızada bir yerde kayıt altına alıyor ve kesmeden sonra oradan devam ediyor mesala delay_ms(1000) dediysem eger kesme geldiyse delay_ms gecikmesi 50 ms de kaldıysa kesme bittikden sonra 51 ms den baslayıp komutu tamamlıyor ..

ve benim sıkıntım devam lı elim buttona basılı fakat bu zaman zarfında pic kesmeden aniden cıkıp bir komut işleyip tekrar kesmeye giriyor ve bu şekilde devam ederek   

while(1)
      {
       delay_ms(100);
       PORTA=(0B00000000);   //Kesmeden cıktıkdan sonra Portları sıfırlıyor
      }

bu komudu yavaş yavaş tamamlıyor bunun sonucuda leda da kırpılma oluyor.
benim istediğim kesmeden cıktıkdan sonra gideceği yer her zaman delay_ms(1000) yeniden saymaya başlasın kaldıgı yerden degil ..

Şimdi ben bu şekilde bir algoritma geliştirirek ledleri yakıp sondurmeyi düşündüm tabikide bu işlemleri başka şekilde yapabiliyorsakda olabilir mesala örnek olarak bir soru daha sorcam pic bu şekilde sürekli kesmeye girmesi pic için sorun yaratırmı çünkü elim devamlı butona basılı tutacağım belki 10 sn. belki 5 dk. Bazı araştırdıÐım yerlerde sorun olur dediler bazıları hiçbirşey olmaz dedi.
Başka yöntemlerde kullanmak isterim mesala kesme yapmadan denedim bu seferde getch komutunda bilgi sürekli kalıyor negibi derseniz soyle ben vericiden button1 basılı tutuyorum ve elim basılı iken vericinin enerjisini kesiyorum ama alıcıda hayla leda yanıyor onun için kesme yontemine başvurmuştum

İşallah Derdimi Anlatabilmişimdir.

x-nomek

@Smit siteye girmiyor herhalde işleri var sanırım yoksa bunu cevaplardi diye tahmin ediyorum :) bana yardım edecek arkdaslar varmi başka ?

smit

Merhaba x-nomek
Biraz forumdan uzak kaldım kusura bakma geç cevap verdiğim için.

Kesme işleminin mantığı anlattığın gibi bir kesme bittikten sonra programın kaldığı yerden devam etmesidir. Bir kesme oluştuğunda işlemci programcounterı yani işlemcinin o an işlediği kodun satırını hafızıya alır. Kesmenin içindeyken sen bu hafızadaki değeri değiştirirsen program kesmeden çıktığında senin istediğin değere dallanabilir. Ama senin müdehalen sonucu böyle işlemler programın çökmesine ve işlemcinin saçma sapan bir yere dallanmasına sebebiyet verebilir. Bu işleri yapabilmek için işlemcinin iç yapısını evine giden yolun haritası gibi çok iyi bilmen gerekir.

Şimdi ilk önce senin istediğin gibi bir program yazmak için nasıl bir yol izlenebilir ona bakalım.

Butona basıldığı an verici 1 kere 'B' bilgisini alıcıya göndersin.
Alıcı 'B' bilgisini alınca üstündeki ledi yaksın.
Sen butona basılı tuttukça başa birşey yollamasın.
Butonu bıraktığın an  bu sefer 1 kere 'A' bilgisi alıcıya gitsin.
Alıcı 'A' bilgisini alınca üstündeki ledi söndürsün.

Burada yapman gereken verici devresindeki butonun geçiş hareketlerini kontrol etmek. Bu yöntemle işlemciyi yormamış olursun. Sadece Butonun 1-0 geçişlerinde bir kere komut gönderir ve bekler.

setup_oscillator(OSC_8MHZ|OSC_INTRC|OSC_31250|OSC_PLL_OFF);
olayına gelirsek işlemcinin içinde lowpower ve highPower olmak üzere iki tane osilator vardır. 31250 Low power osilatörü temsil eder. Sen kullanmayacağın için aslında yazmana gerek yoktur. Biraz kafanı karıştırmış oldum kusura bakma.

setup_oscillator(OSC_8MHZ|OSC_INTRC);

Sen yukarıdaki kısmı yazsan yeter.

x-nomek

#5
Çok tşk ederim Söylediklerini anlamiş bulunmaktayım
Yalnız ben bir kere butona bastım ve bilgi bir kere gitti karşi tarafta ledi yaktı karşidaki led sönmesi için elimin tekrar butondan çekmem lazım ki bir bilgide oyle gondersin ki sönsün buraya kadar hepsini anladım
Yalnız şöyle bir sıkıntı ortaya çıkar elim butona basılıyken kumandanın pili veya alıcının çekim alanı dişinda kaldı ve o anda elimizde button dan çektik yinede alıcı led yanacak çünkü ledi sondur bilgisi ulaşmadıgı için

ben onun için kesme yontemine başvurmuştum çünkü bilgi gelmedigi zaman otomatikmen kesme dişina çikiyor ve ledlerini direk sönduruyordu bu biraz ticari amaçli oldugu içn bu kadar ayrıntıya giriyorum gerçi su anlık projem rafa kalktı ama sayeden çok bilgi ögrendim tşk ediyorum smith
ileride tekrar ugraşcam ozaman başini çok agrıtırım  bilmiş ol :)

akrazi

internal osilator için asm de nasıl çalıştırmak gerekir.
32khz. gibi çalışıyor. sigorta ayarlarından başka nereyi değiştirmek gerekiyor?