Jfpoilpret'in kabul edilen cevabı çok iyi yazılmış, mükemmel derecede geçerli ve vakaların% 99'unda tam olarak açıkladığı şeyi yapacağım. Onun çözümleri sizin tanımladığınız parametrelerin içindedir, bu yüzden çok iyi çalışmalıdırlar. Ama " çok iyi " den daha iyi ne olabilir ? Mükemmellik! Sonuçta, soru kesin bir değer üretmekle ilgilidir. Dedi ki yeterince yakın çoğu durumda iyidir (tartışmalı olarak hepsi) ve 1 saniyenin 1 saniye olması gerektiğinde saatler gibi bir şeyle uğraşırken bile, hala kalıtsal parça kusurlarına maruz kalmanız gerekir.
Ne önereceğim her zaman mümkün değildir. Bazı durumlarda, bu mümkündür, ancak bu davadan çok daha fazla güçlük ve çaba ile. Bu duruma göre değişmeye değer mi? Amacım, gelecekteki referanslar için biraz daha iyi durumlarda daha iyi bir alternatif göstermek. Bu, elektronik konusunda geniş deneyime sahip olmayan acemi Arduino kullanıcıları ile yazılmıştır.
Daha ileri insanlar için bu muhtemelen çok ayrıntılı ve aptal görünecektir. Ama inanıyorum ki, aynı insanlar muhtemelen bunu zaten biliyorlar ve bu cevaba ihtiyaç duymuyorlar. Bu aynı zamanda her mikrodenetleyici ve her üretici ve mimari için de geçerlidir. Ancak diğer mikrodenetleyiciler için, doğru kayıtları ve reçete adlarını ve değerlerini bulmak için doğru veri sayfasına başvurmanız gerekir.
Sizin durumunuzda, belirli bir frekansa ve bununla ilgili güzel bir şeye ihtiyacınız var, tam olarak 56 kHz gerçekten çok kolay elde edilebilir (parçaların pratik kusurlarını saymamak). Yani bu da mükemmel bir örnek olay.
Bir sinyal üretmek, jfpoilpret tarafından iyi açıklandığı gibi mikrodenetleyicinin zamanlayıcılarına ve saat kaynağına bağlıdır. Cevabı sadece bir bakış açısıyla ilgilidir ve bu zamanlayıcılarla uğraşır. Ancak saat kaynağıyla da, hatta sinerji ve harika sonuçlar için daha da iyisi ile uğraşabilirsiniz. Ortam parametrelerini değiştirerek, bu durumda sistemi hackleyerek ve saat kaynağını değiştirerek, çok, çok daha kolay ve basit bir şekilde belirli bir sorunla başa çıkabiliriz.
İlk olarak, pin durumunu değiştirdiğinden, ISR'yi sinyal frekansından iki kat daha fazla yürütmeniz gerekir. Bu saniyede 112.000 kez. 56.000 ve 16.000.000, zaten belirtildiği gibi çok iyi bir şekilde toplanmıyor. Sinyal frekansını veya dokunma frekansını değiştirmemiz gerekir. Şimdilik değişmez bir sinyal frekansı ile başa çıkalım ve daha iyi bir saat hızı bulalım.
Sadece sıfır eklediğinizde ve bu tür bir matematik çoğu insan için en basit olduğu için, 56 kHz'den (veya 112 kHz'den daha büyük bir büyüklük sırasına sahip bir saat seçmek en basit yöntem olacaktır, ancak pratik olarak aynıdır). Ne yazık ki bu dünyadaki her şey bir şeyle bir çeşit uzlaşmadır. Her değer işe yaramaz.
İlk örnek çok düşük incelikli jeneratör hızıdır.
56.000 Hz'lik bir saat seçerseniz, her döngüde ISR'yi çağırmanız gerekeceği için başka bir şey yapamazsınız ve başka bir şey yapamazsınız. Tamamen işe yaramaz. 10 kat daha hızlı (560 kHz) hız seçerseniz, 9 (zamanlayıcının maksimum değerine ulaşması için 10 döngü - ISR işlevini çağırmak için bir döngü) işinizi yapmak için mikro denetleyici döngüleri olacaktır ve bu mümkün olmayabilir. Genellikle daha fazla hesaplama gücüne ihtiyacınız vardır.
Öte yandan çok büyük bir değer seçerseniz, 56 MHz olarak mikrodenetleyici bununla çalışamaz. Çok hızlı. Yani, sadece dükkandaki en büyük değeri seçmek de onu kesmeyecek.
Orijinal Arduino Uno R3'ün 16 MHz'de bir stok saati var, bu yüzden çalışması garanti edilen daha yavaş her şey. 56'dan büyük ve 16 MHz'den düşük bir büyüklük sırası olan bir sonraki değer 5,6 MHz'dir. Bu, ISR'yi her 50 döngüde bir araya getirebilecek ve mükemmel 112.000 Hz zamanlayıcı frekansını oluşturacaktır. Ve sinyaliniz tam olarak 56 kHz olacaktır. ISR çağrıları arasında programınızı yürütmek için 49 MCU döngünüz olacak, ancak yine de orijinal saatin hızının 1 / 3'ü kadardır. Baz olarak 112 kullanılabilir ve 11.2 MHz saat kullanılabilir ve bu da stok 16 MHz rezonatörün yaklaşık 2 / 3'ünü verecektir. ISR işlevi her 100 döngüde bir çağrılır ve yine de mükemmel bir 56 kHz sinyal üretir.
Ancak bu değerlerle ilgili iki büyük sorun vardır.
İlk sorun büyük ölçüde ihtiyaçlarınıza bağlıdır: Bulması kolay bir kayıt değeri (OCR iirc ) kullanan kesin sinyal frekansını elde etmek için maksimum hesaplama gücünüzün yaklaşık 1 / 3'ünü (11,2 MHz ile) feda edersiniz . Onunla iyi olabilirsin ya da olmayabilirsin.
İkinci sorun zor bir gösterici : Değerleri bulmak çok kolay, ancak çoğu zaman üretilen bir saat kaynağı olarak mevcut değiller. Bu, Farnell'in hem 5.6 MHz hem de 11.2 MHz'den yoksun rezonatör web sayfasıdır .
Bunu atlatmak için mevcut rezonatör değerlerine bakabilir ve tam olarak istenen değerleri üretmek için kullanılabilecek başka bir şey bulabiliriz. 56'yı 4'e bölersek 14 elde ederiz ve neyse ki 14 MHz rezonatör vardır. Bu bize çok daha yüksek hız ve daha fazla güç sağlar ve aynı derecede kolay kayıt değerini sağlar. ISR'yi saniyede 112.000 kez çağırmak için OCR kaydına ondalık 124 veya onaltılık 0x7C değerini koymamız gerekir, bu nedenle ISR'yi çağırmak için 124 döngü + 1 saymakla, istenen mükemmel değere ulaşırız.
NB
- ISR - interrupt service rutine (bu sadece oluşturulan interrupt'larda yürütülen koddur)
- Programınızın ne kadar büyük olabileceği bellek boyutuna bağlıdır! Saat hızı ile ilgisi yoktur ve ISR'yi ne sıklıkta çağırdığınızla hiçbir ilgisi yoktur.
Mikrodenetleyici program komutuyla başladığında bir sayaç artırılır. Bir kesinti oluşursa, ISR çağrılır ve bu değer özel bir kayıt defterinde saklanır. ISR kodu tamamlandığında, program sayacının değeri bu özel kayıttan geri yüklenir ve program, hiç olmadığı gibi kesildiği yerden devam eder.
Son derece aptalca bir örnek vereceğim. Eğer safkansanız, sizi uyarıyorum: Burun ve göz kanaması olabilir.
Bir yerden bir yere yürümek zorunda olduğunuzu düşünün. Adım adım yol talimatları ana programınız ve komutlarıdır. Ne kadar hızlı yürüdüğünüz veya koştuğunuz, "saat hızınıza" bağlıdır, ancak rota talimatlarına bağlı değildir (30 adım ileri, 1 tur 90 derece sola, 10 adım ileri, 45 derece sağa vb.) Her zaman aynıdır . Şimdi küçük bir çocuk veya açgözlü, yozlaşmış bir yerel politikacının ayakkabılarınızı çözdüğünü düşünün. Bu bir kesinti oluşturan olaydır. Sonra son adımından sonra durursun, diz çöküp ayakkabını tekrar bağla. Bu ISR programınız.
Sonra durduğunuz yerden devam edersiniz; en baştan başlamazsın. Dünyada ve her zaman dikkatsizce yürüdüğünüzde, ayakkabılarınızı her iki adımda bağlamanız gerekse bile umursamazsınız. Bununla birlikte, Olimpiyatlarda 100 metre koşmak (veya aç bir et yırtıcı hayvanından koşmak) gibi zaman kısıtlamaları ile yaparsanız, ayakkabılarınızı durdurmak ve bağlamak korkunç sonuçlar doğurabilir. Aynı şey mikrodenetleyiciler için de geçerlidir. Sadece bir satır kod çalıştırsanız bile, yavaş da olsa programınız devam edecektir. Hızı hiç umursamıyorsanız, sorun olmayacak. Zamanlayıcıya bağlı diğer eylemleri kullanmak gibi zamanla ilgili bir şeyler yapmanız gerekiyorsa, parazitlenme istenmeyen ve sorunlu olabilir.
Az ama öz! Daha hızlı bir saat her zaman daha iyi değildir. Daha yavaş saat kullanan cihazlar önemli ölçüde daha az güç kullanır. Bu, pille çalışan bir cihazda çok önemli bir nokta olabilir.
Gerekli döngüler bu formüllerden türetilir:
(saat hızı / (ölçekleyici değeri * gerekli ISR arama frekansı)) - 1