Merhaba arkadaşlar. STM8 ile ilgili bu yazımızda ilk uygulamamızı yapacağız. Uygulamamız içerisinde aynı zamanda STM8S serisi için clock modülü ve genel amaçlı giriş çıkış pinlerinden de bahsetmiş olacağız. Bu yazı dizisine ait uygulamalarda sıkça kullanacağımız ve elimizin altında olması gereken dökümanlara, STM8S REFERENCE MANUALSTM8VLD USER MANUALSTM8S003K3 DATASHEET linklerinden ulaşabilirsiniz..



Bir önceki yazımda söylediğim gibi uygulamalarda IAR derleyicisi kullanacağız. IAR ın 8KB lık derleme sınırı olan ücretsiz sürümünü buradan indirebilirsiniz.


Anlatımlarımıza ilk olarak STM8 e ait clock modülünden bahsederek başlayacağız. Bana göre yeni bir mcu serisinin dünyasına girerken ilk olarak clock modülünü kavramak önemlidir.


STM8 mikrodenetleyicisi master clock olarak 4 adet seçenek sunmaktadır. 

  1. 1-24 MHz  aralığında harici bir kristal osilatör (HSE-High Speed External)
  2. 24 MHz e kadar harici clock kaynağı (HSE user-ext)*
  3. 16 MHz frekansında dahili RC osilatör (HSI-High Speed Internal)
  4. 128 kHz frekansında dahili RC osilatör (LSI-Low Speed Internal)

*Bu şekilde bir clock kaynağı kullanılmak istenirse OSCIN pinine maksimum 24MHZ olmak üzere %50 doluluk oranına sahip bir kare dalga, sinüsoidal dalga veya üçgen dalga verilir. OSC OUT pini normal bir I/O pini olarak kullanılır.


 STM8S CLOCK YAPISI – REFERENCE MANUAL-SAYFA 78


Blok diyagramdan da görüldüğü gibi STM8 de 16 MHZ frekansında dahili bir RC osilatör bulunmaktadır. Uygulamalarımızda bu RC osilatörü 8/16 MHz olmak üzere konfigürasyonlarını yapacağız. Dahili olan bu osilatör HSI(High Speed Internal) olarak adlandırılmaktadır.  HSI osilatörü yapılandırmak için clock modülüne ait birkaç register bulunmaktadır. Şimdi kısaca bunlardan bahsedelim.


1.INTERNAL CLOCK REGISTER (CLK_ICKR) (Reset Değeri=0x01) 

HSI osilatörü ayarlamak için bu register ın sadece ilk iki bitini konfigüre edeceğiz.

HSIEN : (HSI Oscillator Enable)

0 =   HSI Dahili RC Osilatör Kapalı

1 =   HSI Dahili RC Osilatör Açık

HSIRDY : (HSI Oscillator Ready)

0 =   HSI Dahili RC Osilatör Hazır Değil

1 =   HSI Dahili RC Osilatör Hazır


2. CLOCK DIVIDER REGISTER (CLK_CKDIVR) (Reset Değeri=0x18) 

HSIDIV[1:0] : (HSI Clock Prescaler)

00 =   f_HSI = f_HSI_RC_Output

01 =    f_HSI = f_HSI_RC_Output/2

10 =    f_HSI = f_HSI_RC_Output/4

11 =    f_HSI = f_HSI_RC_Output/8

CPUDIV[2:0] : (CPUClock Prescaler)

000 =   f_CPU = f_Master

001 =    f_CPU = f_Master/2

010 =    f_CPU = f_Master/4

011 =    f_CPU = f_Master/8

100 =   f_CPU = f_Master/16

101 =    f_CPU = f_Master/32

110 =    f_CPU = f_Master/64

111 =    f_CPU = f_Master/128

HSI RC Osilatörü konfigüre edebilmek için sadece bu register ları ayarlamak yeterlidir.  Aşağıdaki gibi bir fonksiyon(alt program) ile MCU nun clock ayarları yapılabilir.

void InitClock(void)
  {
     CLK_ICKR_HSIEN = 1;
     while(!CLK_ICKR_HSIRDY);
     CLK_CKDIVR = 0x00;
  }

İlk satırda, HSI Osilatörü enable ediyoruz. Bu bit reset durumunda lojik1 değerini aldığından bu satırı yazmasakta olur. Bir sonraki satırda enable edilen HSI Osilatörün hazır hale gelmesi bekleniyor, hazır hale geldikten sonra bir sonraki satıra geçiliyor. Son satırda ise, HSI ön bölücüsü “1” olarak ayarlanıyor. Yani f_Master = f_HSI olarak ayarlanmış oluyor. f_HSI = 16MHz olduğundan f_Master = 16MHz olur. CPUDIV bitleri ilede CPU prescaler değeri aynı şekilde “1” e ayarlanmış oluyor. Böylece  CPU ya giden frekans 16MHz e ayarlanmış oluyor.


STM8S serisinin clock modülünde bulunan register ların tümüne aşağıdaki tablodan bakılabilir. Bu register lardan CLK_PCKENx   register ları önemlidir. Bu register lar ile mcu nun içerisindeki çevresel birimlerin clock ları aktif yada pasif hale getirilebilir. Bu sayede güç tüketimi konusunda tasarruf sağlanmış olur. Diğer ayarlar için reference manual da clock modülü kısmı daha detaylı olarak incelenebilir. 



STM8S in clock yapısını inceledikten sonra genel amaçlı giriş/çıkış portlarını inceleyelim. Giriş/çıkış pinlerine ait 5 adet register bulunmaktadır. Bunlar PxODR, PxIDR, PxDDR, PxCR1, PxCR2 registerlarıdır. İlk olarak PxODR register ından incelemeye başlayalım..


1. PORT OUTPUT DATA REGISTER (Px_ODR) (Reset Değeri=0x00)  

Bu register ilgili porta 8 bitlik veriyi yazmak için kullanılır.


2. PORT INPUT DATA REGISTER (Px_IDR) (Reset Değeri=0xXX)

Bu register ilgili porttan 8 bitlik veri okumak için kullanılır. Bu register ın reset değeri, mikrodenetleyicinin bağlı olduğu devreye bağlıdır.   


3. PORT  DATA DIRECTION REGISTER (Px_DDR) (Reset Değeri=0x00)

Bu register ile ilgili portun giriş olarak mı çıkış olarak mı kullanılacağı ayarlanır.

0 =  Pin, giriş olarak kullanılacak..

1 =  Pin, çıkış olarak kullanılacak..


4. PORT  CONTROL REGISTER 1 (Px_CR1) (Reset Değeri=0x00)

— Pin giriş modunda kullanılacak ise (DDR = 0)

0 =  Pin, open-drain olarak kullanılacak..

1 =  Pin için pull-up direnci aktif edilecek..

— Pin çıkış modunda kullanılacak ise (DDR = 1)

0 =  Pin, open-drain olarak kullanılacak..

1 =  Pin, push-pull olarak kullanılacak.. 


5. PORT  CONTROL REGISTER 2 (Px_CR2) (Reset Değeri=0x00)

— Pin giriş modunda kullanılacak ise (DDR = 0)

0 =  Pin için harici kesme pasif durumda..

1 =  Pin için harici kesme aktif durumda..

— Pin çıkış modunda kullanılacak ise (DDR = 1)

0 =  Port hızı 2MHZ e kadar..

1 =  Port hızı 10MHZ e kadar..


Genel amaçlı giriş/çıkış portlarına ilişkin tüm register lar ı toplu olarak aşağıdaki tabloda görebiliriz.


Bu kısımdan sonra aşağıdaki ilk uygulamamızda kullanacağımız giriş/çıkış pinlerine ait ayarlarının yapıldığı fonksiyon aşağıdaki şekildedir.

void InitGPIO(void)
{
   // LED ÇIKIŞI (PD0)
   PD_DDR_DDR0 = 1;
   PD_CR1_C10  = 1;
   PD_ODR_ODR0 = 0;
 
   // BUTON GİRİŞİ (PB7)
   PB_DDR_DDR7 = 0;
   PB_CR1_C17  = 0; 
}


Kit üzerinde bulunan butonumuz PB7 pinine bağlanmış durumda. Ledimiz ise PD0 pinine bağlı durumda..


GPIO pinlerini ayarlamak için kullandığımız alt programda,  ilk  olarak ledimizin bağlı olduğu pin çıkış olarak koşullandırılmış.  Pin leri ayarlamak için istersek tüm portu “Px_DDR = 0xXX” gibi tek komutla istersek, “Px_DDR_DDRx=X” şeklinde pin pin ayarlayabiliriz. IAR bunu desteklemektedir. Led çıkışı için CR1 register ına “1” yazılmıştır. Pin push-pull olarak kullanılacaktır. Daha sonra pinin data register ına lojik 0 değeri yazarak tamamlıyoruz.

Buton girişi için ise ilk olarak PB7 pini giriş olarak tanımlanmıştır. Ardından da CR1 register ından pin, open-drain olacak şekilde ayarlanarak tamamlanmıştır.


Aşağıda ise kit üzerindeki yeşil led i belirli aralıklarla toggle yapan(led blinking) kodları verilmiştir…

#include <iostm8s003k3.h>
 
#define   LED_OUTPUT   PD_ODR_ODR0   
#define   BUTON_INPUT  PB_IDR_IDR7   
 
void InitClock(void)
{
   CLK_ICKR_HSIEN = 1;
   while(!CLK_ICKR_HSIRDY);
   CLK_CKDIVR = 0x00;
}
 
void InitGPIO(void)
{
   // LED ÇIKIŞI (PD0)
   PD_DDR_DDR0 = 1;
   PD_CR1_C10  = 1;
   PD_ODR_ODR0 = 0;
 
   // BUTON GİRİŞİ (PB7)
   PB_DDR_DDR7 = 0;
   PB_CR1_C17  = 0; 
}
 
void __delay(void)
{
  unsigned long int j=150000;
  while(j--);
}
 
void main(void)
{
  InitClock();
  InitGPIO();
 
  for(;;)
  {
    LED_OUTPUT = 1;
    __delay();
    LED_OUTPUT = 0;
    __delay();
  }
}


Aşağıda da butona basıldığında kit üzerindeki yeşil ledi yakan kodlar verilmiştir…

#include <iostm8s003k3.h>
 
#define   LED_OUTPUT   PD_ODR_ODR0   
#define   BUTON_INPUT  PB_IDR_IDR7   
 
void InitClock(void)
{
   CLK_ICKR_HSIEN = 1;
   while(!CLK_ICKR_HSIRDY);
   CLK_CKDIVR = 0x00;
}
 
void InitGPIO(void)
{
   // LED ÇIKIŞI (PD0)
   PD_DDR_DDR0 = 1;
   PD_CR1_C10  = 1;
   PD_ODR_ODR0 = 0;
 
   // BUTON GİRİŞİ (PB7)
   PB_DDR_DDR7 = 0;
   PB_CR1_C17  = 0; 
}
 
void __delay(void)
{
  unsigned long int j=150000;
  while(j--);
}
 
void main(void)
{
  InitClock();
  InitGPIO();
 
  for(;;)
  {
    LED_OUTPUT = BUTON_INPUT;
  }
}


Aşağıda da butona basıldığında kit üzerindeki yeşil ledi söndüren kodlar verilmiştir…

#include <iostm8s003k3.h>
 
#define   LED_OUTPUT   PD_ODR_ODR0   
#define   BUTON_INPUT  PB_IDR_IDR7   
 
void InitClock(void)
{
   CLK_ICKR_HSIEN = 1;
   while(!CLK_ICKR_HSIRDY);
   CLK_CKDIVR = 0x00;
}
 
void InitGPIO(void)
{
   // LED ÇIKIŞI (PD0)
   PD_DDR_DDR0 = 1;
   PD_CR1_C10  = 1;
   PD_ODR_ODR0 = 0;
 
   // BUTON GİRİŞİ (PB7)
   PB_DDR_DDR7 = 0;
   PB_CR1_C17  = 0; 
}
 
void __delay(void)
{
  unsigned long int j=150000;
  while(j--);
}
 
void main(void)
{
  InitClock();
  InitGPIO();
 
  for(;;)
  {
    LED_OUTPUT = !BUTON_INPUT;
  }
}

 


Geldik yazımızın sonuna. Bu yazımızda STM8S VL Discovery Kiti üzerinde, STM8S003 mikrodenetleyicisini kullanarak Clock  ve GPIO  konfigürasyonlarını nasıl yapıldığını öğrendik. Bundan sonrada yine aynı kit üzerinde çeşitli uygulamalar yaparak, STM8 mikrodenetleyicisini öğrenmeye çalışacağız. Bir sonraki yazımızda görüşmek üzere, hoşçakalın…

Ferudun GÖKCEGÖZ

fgokcegoz@yahoo.com