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;

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;


Input için 2 pin konfigürasyonu mevcuttur bunlar;
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.
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****/