STM8 Programlama -IAR- #7 (GPIO-OD,PP,Float,WPU)

Uygulama yapma ve kod yazmaya başlamak konusunda geç kaldığımızın farkındayım fakat konuları iyice kavrayıp kafada soru işareti bırakmak istemiyorum. Bu yüzden olayı sindire sindire gidip, oldu bittiye getirmemeye çalışıyorum. Bu yazımızda GPIO’nun I/O durumları özelliklerine değineceğiz.

GPIO General-Purpose Input/Output türkçesi Genel Amaçlı Giriş/Çıkış kontrol edilebilir dijital sinyal pinleridir. Bu pinleri giriş ve çıkış olmak üzere iki durum için ayarlayarak kullanabiliriz.

Output için 2 pin konfigürasyonu mevcuttur bunlar;

  • OD Open Drain
  • PP Push-Pull
  • PB4 ve PB5 Pini için True Open-Drain
GPIO Block Diagram

Yukarıda GPIO Blok Diyagramı bulunmakta. Diyagramdaki kesik çizgili alanın içerisi GPIO pininin iç taraftaki bağlantı şeklini göstermektedir. OD,PP ve T (True Open-Drain) durumlarını açıklayalım;

  • OD (Open Drain) ve T (True Open-Drain): pini OD olarak seçecek olursak pin alt taraftaki mosfetin drain ucuna bağlı olacak ve yukarıdaki mosfet devre dışı bırakılacaktır. Aslında yukarıdaki mosfet var fakat sanal olarak yoktur.
    True Open-Drainde ise üst taraftaki mosfet ve Pull-Ip direnci gerçekten yoktur. Dolayısıyla bu (T) pinlerinde Push-Pull ve Pull-Up seçenekleri seçilse bile fiziki olarak orada o malzemeler olmadığı için isteğimiz gerçekleşmeyecek (T) pinleri diğer GPIO pinleri gibi çalışmayacaktır. Her iki durumda da yük pine seri bağlanmalıdır. Bir LED çalıştıracağımızı var sayalım, pinin katodunu pine anodunu direnç ile + beslemeye bağlamalıyız. Yeterince açıklayıcı olduğu düşünerek PP’ye geçiyorum.
  • PP (Push-Pull): Bu seçenekte ise pin çıkışı her iki mosfetin arasına bağlıdır. Dolayısıyla pinden Lojik 1 ve Lojik 0 sinyalini doğrudan alabiliriz. PP’u da aşağıdaki resim gibi düşünebiliriz.

Input için 2 pin konfigürasyonu mevcuttur bunlar;

  • Floating
  • WPU (Wake Pul-Up)

Pin input olarak kullanılacaksa blok diyagramdaki iki mosfet pasif konuma geçer ve pin doğrudan IDR(Input Data Register)’a gider. Aslında schmitt trigger’dan geçer fakat pin analog giriş olarak kullanılacağında schmitt trigger devreye alınabilir.

  • Floating : İlgili pin float olarak konfigüre edilirse giriş sinyali doğrudan IDR’ye ulaşır. Bu durum daha pin analog giriş olarak kullanılacaksa ve girişin kararlı olduğu durumlarda kullanılır.
    Mesela ilgili pin bir entegre ile haberleşiyor olsun. Entegre çıkışı için iki durum olduğu için (Lojik 0 veya Lojik 1) bu pini float olarak kullanmakta bir sakınca yoktur.
  • WPU :İlgili pinde blok diyagramda görünen pull-up direnci aktif edilir. Buda girişten okuyacağımız durumlar arasında kararsızlık varsa pini boşta bırakmamış olur.
    Mesela girişe bir buton bağlıysa bu seçenek kullanıldığında herhangi bir pul up direncine gerek kalmadan butonu pin ve GND arasına bağlayabiliriz.

    Ayrıca Giriş için ilgili pinde özellik mevut ise External Interrupt kullanmak mümkündür. Ext.Interruptı kısaca şöyle bilelim: İlgili pinde bu özellik aktif edilirse pinin lojik seviye değişim anlarında program stm8s_it.c dosyasındaki ilgili rutine yönlenir ve ilgili kodları işleyip ana döngüde kaldığı yerden devam eder.

Evet Çıkış durumlarını anladığımıza göre artık kod kısmına geçebiliriz.
Her zamanki gibi ilgili kütüphaneyi dahil etmeliyiz.

#include "stm8s_gpio.h"

Dahil ettikten sonra kullanacağımız portu GPIO_DeInit(GPIOx); fonksiyonu ile sıfırlayalım. GPIOx parametresinde x yerine MCU’da var olan herhangi bir port ismi olabilir bunlar; GPIOA,GPIOB,GPIOC,GPIOD.

GPIO_DeInit(GPIOA);

Şimdi GPIO_Init(); fonksiyonu ve parametrelerini inceleyelim.

GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin, GPIO_Mode_TypeDef GPIO_Mode);
// I.Parametre Değerleri GPIO_TypeDef* (GPIOx)
GPIOA
GPIOB
GPIOC
GPIOD

// II.Parametre Değerleri GPIO_Pin_TypeDef (GPIO_Pin)
GPIO_PIN_0 = ((uint8_t)0x01), /*!< Pin 0 selected */
GPIO_PIN_1 = ((uint8_t)0x02), /*!< Pin 1 selected */
GPIO_PIN_2 = ((uint8_t)0x04), /*!< Pin 2 selected */
GPIO_PIN_3 = ((uint8_t)0x08), /*!< Pin 3 selected */
GPIO_PIN_4 = ((uint8_t)0x10), /*!< Pin 4 selected */
GPIO_PIN_5 = ((uint8_t)0x20), /*!< Pin 5 selected */
GPIO_PIN_6 = ((uint8_t)0x40), /*!< Pin 6 selected */
GPIO_PIN_7 = ((uint8_t)0x80), /*!< Pin 7 selected */
GPIO_PIN_LNIB = ((uint8_t)0x0F), /*!< Low nibble pins selected */
GPIO_PIN_HNIB = ((uint8_t)0xF0), /*!< High nibble pins selected */
GPIO_PIN_ALL = ((uint8_t)0xFF) /*!< All pins selected */

// III.Parametre Değerleri GPIO_Mode_TypeDef; (GPIO_Mode)
GPIO_MODE_IN_FL_NO_IT      = (uint8_t)0x00,  /*!< Input floating, no external interrupt */
GPIO_MODE_IN_PU_NO_IT      = (uint8_t)0x40,  /*!< Input pull-up, no external interrupt */
GPIO_MODE_IN_FL_IT         = (uint8_t)0x20,  /*!< Input floating, external interrupt */
GPIO_MODE_IN_PU_IT         = (uint8_t)0x60,  /*!< Input pull-up, external interrupt */
GPIO_MODE_OUT_OD_LOW_FAST  = (uint8_t)0xA0,  /*!< Output open-drain, low level, 10MHz */
GPIO_MODE_OUT_PP_LOW_FAST  = (uint8_t)0xE0,  /*!< Output push-pull, low level, 10MHz */
GPIO_MODE_OUT_OD_LOW_SLOW  = (uint8_t)0x80,  /*!< Output open-drain, low level, 2MHz */
GPIO_MODE_OUT_PP_LOW_SLOW  = (uint8_t)0xC0,  /*!< Output push-pull, low level, 2MHz */
GPIO_MODE_OUT_OD_HIZ_FAST  = (uint8_t)0xB0,  /*!< Output open-drain, high-impedance level,10MHz */
GPIO_MODE_OUT_PP_HIGH_FAST = (uint8_t)0xF0,  /*!< Output push-pull, high level, 10MHz */
GPIO_MODE_OUT_OD_HIZ_SLOW  = (uint8_t)0x90,  /*!< Output open-drain, high-impedance level, 2MHz */
GPIO_MODE_OUT_PP_HIGH_SLOW = (uint8_t)0xD0   /*!< Output push-pull, high level, 2MHz */
}GPIO_Mode_TypeDef;

II. parametre değerlerinden GPIO_PIN_LNIB, GPIO_PIN_0……_1……_2……_3 pinlerini GPIO_PIN_HNIB, GPIO_PIN_4……_5……_6……_7 pinlerini, GPIO_PIN_ALL ise bütün pinleri seçeceğini söylemektedir.
III. parametrede dikkat etmemiz gerken bir durum SLOW ve FAST durumudur. Her pin bu özelliği taşımayabilir. Bu bilgiye datasheetden pin descriptions sayfasından ulaşılabilir. Sayfada Speed sütunu altında O1,O2….. gibi işaretler ilgili pinin hangi frekansa kadar çalışma sağlayabildiği hakkında geniş bilgiler vermektedir.
Diğer mikrodenetleyicelerde sıkça rastlanılmayan bir durum ise HIZ özelliğidir. Bu özellik ile pin yüksek empens konumuna alınır. Yerine göre oldukça kullanışlı olabiliyor.

Şimdi gpio kütüphanesindeki Output olarak seçtiğimiz pinler için kullanabileceğimiz fonksiyonlara göz atalım.

void GPIO_Write(GPIO_TypeDef* GPIOx, uint8_t PortVal);

Parametrelerden GPIOx GPIO portunu PortVal ise 8 bit değer olarak girilmesi gerekir.
PIC için CCS’de kod yazanlarımız varsa hatırlayacaktır; output_b(0b00000001); komutu ile B0 pini SET edilirdi. Burada da aynı durum söz konusu tek fark binary sayı sisteminde değilde hexadecimal sayı sistemiyle yazmamız gerekiyor. Mesela PortVal parametresini 0xFF olarak yazarsakbütün pinler Lojik 1 olacaktır.

void GPIO_WriteHigh(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins);
void GPIO_WriteLow(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins);
void GPIO_WriteReverse(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins);

PortPins yerine GPIO_PIN_0………..GPIO_PIN_7 parametrelerinden birisi gelmelidir.

Şimdi de gpio kütüphanesindeki Input olarak seçtiğimiz pinler için kullanabileceğimiz fonksiyonlara göz atalım.

uint8_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
uint8_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
BitStatus GPIO_ReadInputPin(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin);

GPIO_ReadInputData : GPIO giriş portunun tamamının verisini unsigned int değerinde geri döndüren foksiyon. Mesela mikrodenetleyicimizin A portunun tamamına giriş olarak seçili olsun(Zaten STM8S103F3’de A portuna ait 3 pin bulunmakta; PA1,PA2,PA3). Girişlerin tamamının Lojik 1 olduğunu varsayarsak GPIO_ReadInputData(GPIOA); fonksiyonu bize Hex Sayı sisteminde 0x0E değerini döndürecektir.
GPIO_ReadOutputData : Çıkışın Lojik seviye durumunu gösteren fonksiyon.
GPIO_ReadInputPin : Pinin okuma işlemini pin bazında geri döndüren fonksiyondur.

Aşağıdaki kod ile buton ile LED kontrol kodları bulunmaktadır. Kodların olduğu proje dosyasını buradan indirebilirsiniz. Umarım Faydalı olumuştur. Bir sonraki yazımızda görüşmek ümidiyle… Hoşçakalın.

/**
  ******************************************************************************
  * @file    Project/main.c 
  * @author  N7A TECHNIC
  * @brief   Main program body
   ******************************************************************************
  *        www.n7a.web.tr
  ******************************************************************************
  */ 


/* Includes ------------------------------------------------------------------*/
#include "stm8s.h"
#include "stm8s_clk.h"
#include "stm8s_gpio.h"
/* Private defines -----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
void delay(uint32_t x);
/* Private functions ---------------------------------------------------------*/

void main(void)
{
  /* Infinite loop */

  CLK_DeInit();
  CLK_HSECmd(DISABLE);
  CLK_LSICmd(DISABLE);
  CLK_HSICmd(ENABLE);
  while(CLK_GetFlagStatus(CLK_FLAG_HSIRDY)==0);
  
  CLK_ClockSwitchCmd(ENABLE);
  CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV4);
  CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);
  
  GPIO_Init(GPIOB,GPIO_PIN_5,GPIO_MODE_OUT_OD_HIZ_FAST);
  GPIO_Init(GPIOD,GPIO_PIN_4,GPIO_MODE_OUT_PP_LOW_FAST);
  GPIO_Init(GPIOD,GPIO_PIN_5,GPIO_MODE_OUT_PP_LOW_FAST);
  
  GPIO_Init(GPIOA,GPIO_PIN_1,GPIO_MODE_IN_PU_NO_IT);
  while (1)
  {
    if(GPIO_ReadInputPin(GPIOA,GPIO_PIN_1) == 0)
    {
      GPIO_WriteHigh(GPIOD,GPIO_PIN_4);
      GPIO_WriteHigh(GPIOD,GPIO_PIN_5);
      GPIO_WriteLow(GPIOB,GPIO_PIN_5);
    }
    else
    {
      GPIO_WriteLow(GPIOD,GPIO_PIN_4);
      GPIO_WriteLow(GPIOD,GPIO_PIN_5);
      GPIO_WriteHigh(GPIOB,GPIO_PIN_5);
    }
  }
  
}

void delay(uint32_t x)
{
  while(x--);
}

#ifdef USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *   where the assert_param error has occurred.
  * @param file: pointer to the source file name
  * @param line: assert_param error line source number
  * @retval : None
  */
void assert_failed(u8* file, u32 line)
{ 
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif


/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

Teorik Eğitim:

Uygulama:

Bir yanıt yazın

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

Whatsapp Hattı