Teknoloji

STM32F407VG – Register ile System Clock Ayarı

Herkese merhabalar , bu yazıda sizlere Register ile System Clock Ayarlarının nasıl olması gerektiği hakkında bilgiler vereceğim.
Sizlerin farklı STM kartları olabilir bu yüzden dökümanınızdan dikkatli inceleyerek hangi registera müdahale edeceğinizi unutmayın.

İlk olarak  #include "stm32f4xx.h"  şeklinde kütüphanemizi çağırıyoruz.

Devamında  kodları madde made yazıp , yazının sonunda tüm hali ile verilecektir.

 


1-   RCC->CR &= ~(1 << 0);
Bu kod RCC (Reset and Clock Control) kaydının CR (Control Register) alanında belirli bitlerin ayarlanması için kullanılır.
0. bit’i 0 yap demek , peki ne demek oluyor bu? Dökümana baktığımızda bu bit HSI bitidir, yani
” HSI –> OFF”  olarak ayarlandı.

 

2-  RCC->CR |= (1 << 16);
16. bit’i 1 yap demek oluyor, peki ne demek bu?  Dökümana baktığımızda bu bit HSE bitidir , yani
” HSE –> ON”  olarak ayarlandı.

 

while (!(RCC->CR & (1 << 17)));
1 << 17 ifadesi, ikili olarak 0x00020000’e denk gelir ve RCC kaydının 17. bitini temsil eder. Bu ifade ile 17. biti kontrol etmek istediğimizi belirtiyoruz.  & operatörü,RCC->CR  ve(1 << 17) arasında bit karşılaştırma işlemi yapar . Bu durumda, RCC->CR & (1 << 17) ifadesi, RCC kaydının 17. bitinin durumunu kontrol eder.  ! operatörü, bir ifadeyi ters çevirir. Yani, eğer ifade doğruysa, false (0) değerini döndürür ve eğer ifade yanlışsa, true (1) değerini döndürür.
Dolayısıyla, while (!(RCC->CR & (1 << 17))); kod satırı, RCC kaydının 17. bitinin durumunu sürekli olarak kontrol eder ve 17. bit ayarlanana kadar (1 değeri alana kadar) döngüyü devam ettirir. Bu, özellikle sistem saati için RCC konfigürasyonunu yaparken, belirli bir saat kaynağının hazır olması beklenirken kullanılabilir. Yani 17. bit 1 olduğunda HSE Hazır demek, biz işlem yapabilmek için bu bitdeki durumu sürekli kontrol ediyoruz ve hazır olduğunda artık HSE kullanılabilir demek oluyor.

 

3- RCC->CR |= (1 << 19);
Bu kod ; CR Registerinin 19. bitini 1 yap demek, peki ne demek oluyor bu? Dökümana baktığımızda bu bit CSSON bitidir, yani
” CSSON –> ON”  olarak ayarlandı.


 


4- RCC->PLLCFGR = 0;
Bu kod,  RCC (Reset and Clock Control) kaydının PLLCFGR (Phase Locked Loop Configuration Register) alanında belirli bitlerin ayarlanması için kullanılır. Burada bu Registera ait tüm bitleri sıfırlayarak Manuel bir Resetleme işlemi gerçekleştirdik.

 

5- RCC->PLLCFGR |= (1 << 22);
Bu kod,  22. biti “1” olarak ayarlar. Yani,  1(bir) seçilirse HSE ()  0(sıfır) seçilirse HSI aktif edilsin  demek.Biz 1 yaparak HSE  kullanacağımızı belirledik.

 

 

6- RCC->PLLCFGR |= (1 << 2);
Bu kod, PLLCFGR Registerındaki  2. biti “1” olarak ayarlar. Bu ayarlamalar neticesinde,  PLLM : 4 , olarak ayarlandı.
000100 olarak ikilik tabanda yazılabilir ama biz yukarda bütün bitleri sıfırladığımız için sadece 4’e tekabül eden biti 1 yapmamız yeterli olacaktır.

 

 

7- RCC->PLLCFGR |= (168 << 6);
Bu kod, PLLCFGR Registerındaki  6. biti “168” olarak ayarlar. Bu ayarlamalar neticesinde,  PLLN : 168 , olarak ayarlandı.
Yukardaki atamalardan farklı olarak bu atam ; onluk tabana göre kaydırma işlemi ile yapıldı.

168  –> 1010 1000
Eğer isterseniz her bir “1” bit için ayrı ayrı atama yapabilirsiniz. (Sıfırlar için atama yapmaya gerek yok , Yukarda hepsi bir anda sıfırlandı)
RCC->PLLCFGR |= (1 << 9);
RCC->PLLCFGR |= (1 << 11);
RCC->PLLCFGR |= (1 << 13);

Ama bu atama işlemi fazla sayıda kod içeridiği için karmaşıklığı artırıyor bu yüzden ondalık(Decimal) tabanda yada onaltılık(Hecdecimal) tabanda yazılarak tek satırlık kodlara çevirildiğini birçok yerde görürüz.


 

8- RCC->PLLCFGR |= (0 << 24);
Bu kod mikrodenetleyicinin PLLQ ayarını 2 olarak ayarlar. Bu, bazı özelliklerin doğru şekilde çalışması için gereklidir. Peki bu işlem registarlara tam olarak nasıl yazılıyo? Bunuda aşağıdaki görselden inceleyelim.

Sadece 24. biti 0 yapmak geri kalanlarıda 0 yapmak demek , hepsi sıfır olunca PLLQ : 2 olarak elde edilir.
Dipnot: PLLQ ; USB OTG FS, SDIO, RNG clock işlemleri için kullanılır , eğer bu işlemler kullanılmayacaksa yukardaki gibi hepsi sıfırlanmasında fayda var ama formule uygun bir sonuç çıktığından emin olunmalı.

PLLCFGR (Phase Locked Loop Configuration Register) Nedir ?

Bir mikrodenetleyici veya diğer dijital cihazlarda, sistem saatleri gibi belirli işaretleyiciler önemlidir. Bu saat işaretleyicileri, dijital devrelerdeki işlemlerin zamanlama ve senkronizasyonunda kullanılır. Sistem saatleri genellikle bir osilatör devresinden elde edilir ve bu devrelerin kararlılığı, sistemin doğru şekilde çalışması için kritik önem taşır.

PLL, bir sinyali belirli bir frekansa kilitleyen bir elektronik devredir. Bu devreler, sistem saat sinyallerinin kararlılığını artırmak için kullanılır. PLLCFGR, PLL devresinin özelliklerini belirleyen bir kayıt defteridir. Bu kayıt defteri, mikrodenetleyicilerde sıklıkla kullanılır ve diğer dijital cihazlarda da benzer şekilde kullanılabilir.

PLLCFGR kayıt defteri, PLL devresinin giriş frekansını, çıkış frekansını, kararlılık parametrelerini ve diğer ayarlarını içerir. Bu kayıt defteri, sistem tasarımında önemli bir rol oynar çünkü doğru şekilde ayarlanması, sistemin doğru şekilde çalışmasını sağlar ve sistem performansını artırır.

Örneğin, bir mikrodenetleyicinin çalışma frekansını belirlerken PLL devresi kullanılabilir. PLLCFGR kayıt defteri, PLL devresinin çalışma frekansını ve diğer parametreleri ayarlamak için kullanılır. Bu sayede, mikrodenetleyici işlemleri doğru şekilde zamanlanır ve hatalı işlemler önlenir.

Sonuç olarak, PLLCFGR kayıt defteri, bir sistemin saat sinyallerinin doğru zamanlanmasını sağlamak için kritik öneme sahip bir ayar kaynağıdır. Bu kayıt defterinin doğru şekilde ayarlanması, sistem performansını artırır ve istikrarlı bir çalışma sağlar.

Yukarıda yaptığımız PLLN,PLLM ve PLLQ ayarlamalarını formül üzeri görelim;

Formüldekileri Yerine Koyarsak;

F(Pll clock input) = 8 (Mhz)
PLLN   =  168
PLLM   =  4
PLLQ   =  2
F(vco clock) = ?
F(PLL general clock output)   = ?

F(vco clock) = 8 x (168 / 4)
F(vco clock) = 336

F(PLL general clock output) = F(vco clock) / 2
F(PLL general clock output) = 336 /2
F(PLL general clock output) = 168

Sonuç olarak;

Giriş  => 8Mhz
Çıkış => 168 Mhz

 


9-RCC->CR |= (1 << 24);
Bu kod ; CR Registerinin 24. bitini 1 yap demek, peki ne demek oluyor bu? Dökümana baktığımızda bu bit PLLON bitidir,
Yukarıda ayarlanan tüm PLL ayarlarının sonunda bu  PLLON bitini aktif ederek PLL İşlemlerini başlatıyoruz.

while ((RCC->CR & (1 << 25)) == 0);
Bu kod ise ; CR Registerinin 25. bitini sürekli olarak kontrol eder ve PLL işlemi hazır olana kadar bekler , hazır olduğunda while’ın döngüsünden çıkar ve  yoluna devam eder.

Dipnot ; Yukardaki while işleminin mantığı burdaki while işlemi ile aynı sadece komutun gelmesi için (Bayrağın kalkması) uygun registarların uygun bitlerini kontrol ediyorlar. Yukarıda HSE_Ready bitinin bayrağı hazır olduğunda kalkıyor ve while döngüsü bu bayrağı takip ediyor burda ise PLLON_Ready bitinin bayrağı hazır olduğunda  kalkıyor ve while döngüsü bu bayrağı takip ediyor. Bu şekilde hazır olmamaları halinde while olduğu yerde sonsuz döngüye giriyor ve hazır oldukları an while’ın içerisinden çıkarak yolarına devam ediyorlar.

 

 

 


10- RCC->CFGR &= ~(3 << 0);
Bu kod , RCC clock configuration register (RCC_CFGR) içerisinde bulunan SW0 ve SW1 adlı 0. ve 1. bitlere müdahale ediyor . Amacımız ise herhangi bir arıza durumunda veya  başlama ve bekleme modundan çıkarken oluşan hatalarda alternatif bir osilatör seçimi yapmak ve bizde burda HSI  yani  bağımlı bir osilatör seçimi yapıyoruz.

0 bit sola kaydır dedik ve kaydırılacak veriyi ‘3’ olarak belirlerdik , bu ‘3’ sayısı ikili tabana göre ’11’ demek onaltılık tabana göre de ‘3’ demek

~(3 << 0); –> ~(0x3 << 0); –> ~(11 << 0);
Bu kodların hepsi aynı anlama geliyor.

Bu şekilde sadece 0. ve 1. bitlere yazılım ile müdehale ettik.


 

 

11- RCC->CFGR &= ~(0xF << 4);
Bu kod , yine aynı registerda bulunan bitlere yazılım ile müdehalemizi  sağlıyor. Buradaki amacımız ise 4. 5. 6. 7. bitlere müdahale etmek.  “HPRE” yani (AHB Prescaler) ait bitleri sıfırlayarak ‘system clock not divided’ işlemine sokmak, bu işlem Frekans değerinimizin herhangi bir bölme işlemine sokmadan doğrudan aktarımını yapmaya yarıyor.

~(0xF << 4) –> ~(1111 << 4) Bu ikisi aynı anlama geliyor , ilki onaltılık  ikincisi ikilik tabanda yazıldı.

 

12-  RCC->CFGR |= (101 << 10);
Bu kod, yine aynı registerda bulunan bitlere yazılım ile müdehalemizi  sağlıyor. Buradaki amacımız ise  “PPRE1” yani (APB1 – Low Speed Prescaler) ait bitlerini  belli bir oranda bölmek için  10.  11.  12.  bitlere müdahale etmek.

(101 << 10) –> (5 << 10)  Bu iki kod aynı anlama gelir , ilki ikilik tabanda ikincisi onluk tabanda yazıldı.

Aşağıdaki tablodan da görüldüğü gibi “101” yapmak “4” ‘e bölmek demek , sadece 4’e değil 8’e veya 16’ya da  bölünebilir ama 1’e  veya 2’ye  bölünemez çünkü APB1 Faz Hattı max 42 Mhz alıyor , 42Mhz den fazla veremeyiz ama aşağı verebiliriz.

Hesaplama;
168  /  1   =  168    (OLMAZ)
168  /  2   =  84      (OLMAZ)
168  /  4   =  42      (OLUR)
168  /  8   =  21      (OLUR)
168  /  16 =  10.5   (OLUR)

 

13- RCC->CFGR |= (100 << 13);
Bu kod, yine aynı registerda bulunan bitlere yazılım ile müdahalemizi  sağlıyor. Buradaki amacımız ise “PPRE2” yani (APB2 – High Speed Prescaler) ait bitlerini belli bir oranda bölmek için  13.  14.  15.  bitlere müdahale etmek.

(100 << 10) –> (4 << 13)  Bu iki kod aynı anlama gelir , ilki ikilik tabanda ikincisi onluk tabanda yazıldı.

Aşağıdaki tablodan da görüldüğü gibi “100” yapmak “2” ‘e bölmek demek , sadece 2’e değil 4’e , 8’e veya 16’ya da  bölünebilir ama 1’e   bölünemez çünkü APB2 Faz Hattı max 84 Mhz alıyor , 84 Mhz den fazla veremeyiz ama aşağı verebiliriz.

Hesaplama;
168  /  1   =  168    (OLMAZ)
168  /  2   =  84      (OLUR)
168  /  4   =  42      (OLUR)
168  /  8   =  21      (OLUR)
168  /  16 =  10.5   (OLUR)

 


Bu alanda yazılan kodlar ise yukarıdaki yapılan işlemlerde doğacak sıkıntıların önüne geçmek için yazılacak.
Yukarıda HSE ve PLLON bitlerini aktif ettikten sonra eğer aktif etme işlemi başarıyla gerçekleştiyse bu bitleri kontol eden  bitler (“HSERDY” ve “PLLRDY”) “1” sinyali dönecek yani “bayrak” kalkmış olacak. Bizler kalkan bu bayrakları tekrardan indirmek yani “0”a çekmek durumundayız. RCC’ye bağlı CIR (clock interrupt register) Registerlarında bu bayrakları yazılım ile indireceğiz.

14- RCC->CIR |= (1 << 19);  ve RCC->CIR |= (1 << 20);
Bu kodlar , yukarıda bahsedilen bayrakların inmesi için kullanıldı , dökümanı incelediğimizde bu  19. bit  “HSERDY”  bayrağını , 20. bit “PLLRDY” bayrağını temizliyor. Bitlerin isimleri  ‘HSERDYC’ ve ‘PLLRDYC’ sondaki “C” harfi “Clear”‘dan geliyor , bitler 1 olduğunda temizleme işlemi gerçekleşiyor.

 

 


Kodun Tamamı;

#include "stm32f4xx.h"
void RCC_Config(void) {
RCC->CR &= ~(1 << 0);
RCC->CR |= (1 << 16);
while (!(RCC->CR & (1 << 17)));
RCC->CR |= (1 << 19);
//---------------------------------
RCC->PLLCFGR = 0;
RCC->PLLCFGR |= (1 << 22);
RCC->PLLCFGR |= (1 << 2);
RCC->PLLCFGR |= (168 << 6);
RCC->PLLCFGR |= (0 << 24);
RCC->CR |= (1 << 24);
while ((RCC->CR & (1 << 25)) == 0);
RCC->CFGR &= ~(3 << 0);
RCC->CFGR &= ~(0xF << 4);
RCC->CFGR |= (101 << 10);
RCC->CFGR |= (100 << 13);
//---------------------------------
RCC->CIR |= (1 << 19);
RCC->CIR |= (1 << 20);
//---------------------------------
}
int main() {
RCC_Config();
while (1) {    }
}

 

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Göz Atın
Kapalı
Başa dön tuşu