STM32 Programlama -STM32F4 Clock Configration-

Bu yazımda STM32F411 mikrodenetleyicisinin saat ayarlarını anlatacağım ve çipin sistem saatini 100Mhz e ayarlayacağım. Fakat, sizin herhangi bir STM32 mikrodenetleyicisini (en azından F4 serisi) istediğiniz herhangi bir frekansta çalıştırabilmeniz için bazı kavramlardan ve bazı terimlerden bahsetmek istiyorum. Bu sayede kullandığınız çip farklı dahi olsa mikrodenetleyiciniz için uygun saat ayarlarını yapabileceksiniz.

Saat Kaynağı(Clock Sourse)

Mikrodenetleyiciler farklı çevre birimleri ile ve kendi içerisindeki veri akışını kontrol etmek için stabil bir frekans kaynağına ihtiyaç duyarlar. Bu bahsettiğimiz frekansları genellikle osilatörler kullanarak elde ederiz.

STM32 mikrodenetleyicilerinde sistem saatini besleyebileceğimiz üç temel saat kaynağı vardır.

HSI(High Speed Internal) : Yüksek hızlı dahili osilatör ü kullanarak doğrudan sistem saatini besleyebiliriz. Bu osilatörün değeri kullandığınız mikrodenetleyicinin referance manuel inde yazmaktadır. Örneğin, benim kullandığım STM32F411 çip i 16Mhz HSI osilatöre sahip. Bu osilatör frekansını doğrudan sistem çalışma frekansı olarak veya PLL giriş frekansı olarak kullanabiliriz.

HSI osilatörü kullanmak maliyet açısından bir avantaj olacaktır(çipi kendi başına projelerde kullananlar için 🙂 biz zaten üzerinde harici osilatör barındıran kartlar kullanıyoruz) ve HSE osilatörlere göre daha düşük çalışmaya başlama süresine sahiptir.

HSE(High Speed External) : HSI osilatörlerde olduğu gibi HSE osilatörlerde doğrudan sistem çalışma frekansı veya PLL giriş frekansı olarak kullanılabilir. Kullanacağınız osilatörün frekans değeri ve bağlantıları referance manuelde yazmaktadır fakat biz genellikle çipleri üzerinde barındıran kartlar kullandığımız için bu osilatörler halihazırda çipimize bağlıdır. Örneğin, benim kullandığım kart üzerinde 25Mhz kristal osilatör barındırıyor.

HSE osilatörler HSI osilatörlere göre daha yüksek doğruluk oranına sahip frekanslar sağlamaktadır.

PLL(Phase Locked Loop) : Faz kilitlemeli döngü tamamı ile yeni bir yazı konusu olabilir. Bu yüzden şimdilik PLL için “Bir referans sinyal frekansının katlarını üreten frekans sentezleyici bir birimdir” demeyi tercih ediyorum. Referans sinyal olarak HSI veya HSE osilatör frekanslarını kullanabiliriz.

En basit tabiri ile PLL kullanarak bir saat frekansının katları olan çok daha yüksek saat frekansları elde edebilirsiniz.

Flash Prefetch ve Wait State

Günümüzde teknolojininde gelişmesiyle çok yüksek hızlarda çalışan mikroişlemciler üretilmektedir. Mikrodenetleyiciler yazımda da bahsettiğim gibi mikrodenetleyiciler içerisinde mikroişlemci ve bu mikroişlemci ye bağlı olan çevre birimlerinin bir araya gelmesi ile oluşmaktadır. Yani, mikroişlemcilerin hızlanması demek mikrodenetleyicilerinde hızlanması anlamına gelmektedir. Fakat bu bahsettiğimiz gelişme mikrodenetleyicinin tüm bileşenlerinde aynı oranda olmamıştır demem o ki çevre birimleri CPU lar kadar hızlı çalışamamaktadır. Buradaki çevre biriminden kastım çipimizin çalışması için gerekli kodu yüklediğimiz Flash hafıza birimidir.

Wait State denilen kavram CPU nun Flash hafızayı beklemesidir. CPU nun çalışma frekansına göre uygun wait state değerini belirlememiz gerekir.

Burayı şöyle örneklemek istiyorum; CPU ve Flah hafıza bir yükü beraber taşıyan iki insan olsunlar ve bunları yürüme hızları farklı olsun yani CPU Flash hafızan hızlı yürüsün. Yükü düzgün bir şekilde taşıyabilmeleri için hızlı yürüyenin her adımdan sonra belirli bir süre diğerini beklemesi gerekmektedir.

CPU belirli bir zamanda sadece bir satır kodu işlemektedir. Prefect buffer dediğimiz bellekte işlemcinin çalıştıracağı sonraki bir kaç talimat hali hazırda tutulur. Yani işlemcinin yapacağı bir sonraki işin prefecth buffer dediğimiz önbellekte tutulmasıdır.

Clock Configrations için gerekli olan bazı kavramlara değindim şimdi kullanacağımız bazı yazmaçlara bakalım.

Yazmaçlar

RCC (Reset Clock Configration) Yazmaçları

HSION(0) : Yüksek hızlı dahili osilatörü aktif etmek için kullanılan bittir. HSION bit i set edildiği zaman yüksek hızlı dahili osilatör aktif olur.

HSIRDY(1) : Yüksek hızlı dahili osilatör yazılım tarafından aktif hale getirildikten sonra osilatör stabil hale geldiğinde HSIRDY bayrağı donanım tarafından set edilir.

HSEON(16) : Yüksek hızlı harici osilatörü aktif etmek için kullanılan bittir. HSEON bit i set edildiği zaman yüksek hızlı harici osilatör aktif olur.

HSERDY(17) : Yüksek hızlı harici osilatör yazılım tarafından aktif hale getirildikten sonra osilatör stabil hale geldiğinde HSERDY bayrağı donanım tarafından set edilir.

HSEBYP(18) : HSE kaynağı olarak bir kristal jenaratör veya başka bir kaynak kullanıyorsanız yani kristal osilatör kullanmıyorsanız bypass bitini set etmelisiniz.

PLLON(24) : PLL birimini aktif hale getirir.

PLLRDY(25) : PLL kaynak frekansı kilitlendiği zaman donanım tarafından set edilen bayrak.

PLLM(5:0) : PLL M değerinin yüklendiği bitler. Tablo aşağıdaki gibidir. Burada dikkat etmemiz gereken nokta PLL M değeri en az 2 en fazla 63 olabilir.

PLLN(14:6) : PLL N değerinin yüklendiği bitlerdir. Tablo aşağıdaki gibidir ve PLLN değeri 50 ile 432 arasında olmalıdır.

PLLP(17:16) : PLL P değerinin yüklendiği bitlerdir. Değerler tablo verilmiştir.

PLLSRC(22) : PLL referans frekansının seçilmesi için kullanılan bittir. PLLSRC biti 1 yapıldğı zaman HSE osilatör, 0 yapıldığı zaman HSI osilatör giriş frekansı olarak seçilmiş olur.

PLL N M P Değerlerinin hesaplanması yukarıdaki formüllerde verilmiştir. Fakat siz daha kolay bir şekilde bu değerleri hesaplamak istiyorsanız CubeMX programından faydalanabilirsiniz. CubeMX programı CLOCK CONFIGRATIONS bölümünde istenilen frekans için gerekli yolu ve gerekli bölme çarpma değerlerini göstermektedir.

HPRE(7:4) : Sistem çalışma frekansı ile AHB hattı arasındaki bölme faktörünün ayarlandığı bitler. Bölme faktörü değerleri aşağıdaki gibidir.

PPRE1(12:10) : AHB hattı ile APB1 hattı arasındaki bölme faktörünü belirler. APB1 çalışma frekansının reference manual de yazan max değerden yüksek olmamasına dikkat etmeliyiz.

PPRE2(15:13) :AHB hattı ile APB2 hattı arasındaki bölme faktörünü belirler. APB2 hattı çalışma frekansı AHB hattı ile aynı olabileceği için bölme faktörü olarak istediğimiz değeri kullanabiliriz.

LATENCY(3:0) : CPU çalışma hızına göre belirlememiz gereken wait state değeri için kullanılan bitler.

PRFTEN(8) : Prefetch buffer ın aktif edildiği bittir.

Daha önceki yazılarımda da söylediğim gibi kullanmadığımız ve bahsetmediğimiz bir sürü yazmaç ve bitleri var bunları reference manuel den araştırmanızı tavsiye ederim.

Adım adım Clock Configration(PLL kullanarak)

1 – Her şeyden önce sistem saati olarak hangi kaynağı kullanacağımızı ve sistem çalışma frekansını belirlemeliyiz.

2 – Belirlediğimiz kaynak ve frekans değeri için gerekli olan çarpma ve bölme faktörlerini hesaplamalıyız.(Bu kısmı hızlı bir şekilde geçmek istiyorsanız CubeMX programından gerekli değerlere bakabilirsiniz)

3 – İlk iki aşamadan sonrasını kod üzerinden anlatmaya devam edeceğim.

// Sistem saat kaynağı olarak PLL ve giriş frekansı içinde HSE kullanacağım
. Sistem çalışma frekansını 100Mhz e ayarlayacağım.

// 1. HSE osilatörü aktif hale getir ve hazır hale gelmesini bekle
RCC->CR |= RCC_CR_HSEON; 
while (!(RCC->CR & RCC_CR_HSERDY)); 

// 2. Flash Prefetch i aktif hale getir ve uygun wait state değerini ata
FLASH->ACR = FLASH_ACR_PRFTEN | FLASH_ACR_LATENCY_3WS; 

// 3. AHB, APB1 ve APB2 hatları için uygun bölme faktörü değerlerini ayarla
// AHB bölme faktörü
RCC->CFGR |= RCC_CFGR_HPRE_DIV1;  // 
AHB frekansı 100 Mhz

// APB1 bölme faktörü 
RCC->CFGR |= RCC_CFGR_PPRE1_DIV2; 
//APB1 freakansı 50 Mhz

// APB2 bölme faktörü 
RCC->CFGR |= RCC_CFGR_PPRE2_DIV1; 
 // APB2 frekansı 100 Mhz

// 4. PLL kapalı durumdayken gerekli ayarlamaları yap //M:25 N:400 P:4 
RCC->PLLCFGR = (PLL_M <<0) | (PLL_N << 6) | (PLL_P <<16) | (RCC_PLLCFGR_PLLSRC_HSE); 

// 5. PLL i aktif hale getir ve hazır hale gelmesini bekle
RCC->CR |= RCC_CR_PLLON; 
while (!(RCC->CR & RCC_CR_PLLRDY)); 

// 6. Sistem saat kaynağı olarak PLL i seç ve ayarlanmasını bekle
RCC->CFGR |= RCC_CFGR_SW_PLL; 
while (!(RCC->CFGR & RCC_CFGR_SWS_PLL)); 

SystemCoreClockUpdate(); // Bu fonksiyon sistem saat frekansını SystemCoreClock adlı bir 
değişkene yükler böylelikle yaptığınız ayarın doğruluğunu test 
edebilirsiniz.

2 comments

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s