STM32 StdPeriph ile ODR ve IDR Register Kullanımı

STM32 StdPeriph ile ODR ve IDR Register Kullanımı

Herkese merhabalar, bu yazımızda sizlerle STM32F4 serisi işlemcilerde GPIO pinlerinin tamamının çıktılarının ve girdilerinin tutulduğu Register değerleri okunacaktır.

Hadi başlayalım.

İlk olarak ODR ve IDR registerları nedir

ODR, Output Data Register ifadesinin karşılığıdır. Pin çıktılarını tutar. IDR, Input Data Register ifadesinin karşılığıdır. Pinlerin girdilerini tutar.
  • ODR ilgili GPIO portunun bütün pinlerinin output durumlarını tutan bir register olarak tanımlanır. Pin çıktılarını ODR registerı aracılığı ile okuyabiliriz veya direk olarak bu register değerini değiştirerek ayarlayabiliriz.
  • IDR ilgili GPIO portunun bütün pinlerinin input durumlarını tutan bir register olarak tanımlanır. IDR registerını kullanarak ilgili portun pinlerinin input durumları okunabilir. Bu sayede inputlar HIGH veya LOW olarak direk olarak buregister ile okunabilir.
Çalışmaya başlamadan sizlere ilgili işlemcinin datasheetini okumanızı öneriyorum. Aşağıdaki resimde ilgili GPIO portların IDR ve ODR registerlarının registerları gösterilmektedir. Bizim işlemcimiz STM32F429 olarak seçilmiştir.
STM32F429-39 ODR Register Datasheet
STM32F429-39 IDR Register Datasheet

Bu çalışmamızda STM32F429 Nucleo kartımızı kullanacağız.Input ve Output stateleri okumak ve değiştirmek için Mavi User butonu ve Yeşil Ledi kullanacağız.

  • Mavi User Butonu(B1) PC13'e bağlıdır.
  • Green Led(LD1) PB0'a bağlıdır
  • Blue Led(LD2) PB7'ye bağlıdır
  • Red Led(LD3) PB14'e bağlıdır

Görüldüğü üzere ilgili registerların son 16-bit değerleri bizim ihtiyacımız olan bitlerdir. Şimdi bu registerları kullanarak örneklerimize geçelim.

İlk olarak kullanacağımız GPIO portlarının yapılandırmalarını ayarlamalıyız. Aşağıdaki kod bloğunda ilgili yapılandırmayı görebilirsiniz. LED pinleri OUTPUT ve Button pini INPUT olarak tanımlanmıştır.

	GPIO_InitTypeDef GPIO_StructureLed;
	GPIO_InitTypeDef GPIO_StructureButton;

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
	
	GPIO_StructureLed.GPIO_Mode = GPIO_Mode_OUT; 
	GPIO_StructureLed.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_7 | GPIO_Pin_14 ; 
	GPIO_StructureLed.GPIO_OType = GPIO_OType_PP; 
	GPIO_StructureLed.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_Init(GPIOB, &GPIO_StructureLed);
	
	GPIO_StructureButton.GPIO_Mode = GPIO_Mode_IN;
	GPIO_StructureButton.GPIO_Pin = GPIO_Pin_13;
	GPIO_StructureButton.GPIO_OType = GPIO_OType_PP;
	GPIO_StructureButton.GPIO_PuPd = GPIO_PuPd_DOWN; 
	GPIO_StructureButton.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_Init(GPIOC, &GPIO_StructureButton); 
Şimdi ilk olarak ODR ve IDR registerlarını inceleyelim. Aşağıdaki kod bloğunda mavi user butonuna basıldığında LEDler yanacak ve bırakıldığında sönecek şekilde ayarlanmıştır.

	while(1)
	{
		if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_13))
			GPIO_SetBits(GPIOB,GPIO_Pin_0 | GPIO_Pin_7 | GPIO_Pin_14 );
		else
			GPIO_ResetBits(GPIOB,GPIO_Pin_0 | GPIO_Pin_7 | GPIO_Pin_14);
	}	
Register değerlerini uVision Keil programı içerisindeki DEBUG ekranından kontrol edeceğiz. Aşağıdaki resimde butona basıldığında ve bırakıldığında GPIOB ve GPIOC portlarının IDR ve ODR registerlerini görmektesiniz. STM32F429 GPIO Ports IDR and ODR Registers in Debug Mode
Şimdi aşağıda bu registerların durumlarını inceleyelim.
Burada sadece benim ihtiyacım olan bitleri inceleyeceğim. Yani Ledlerin ve butonun bitlerini inceleyeceğim. Diğerlerinin durumları şu anda benim için çok önemli değil.
GPIOB ODR register değeri 0x00000000 iken 0x00004081 olmuştur. Datasheete göre ilk 16 bit önemli değil son 16 bite odaklanacağız.
0x4081 = 0b0100000010000001‬
Görüldüğü üzere binary karşılığı olan değerin 0. 7. ve14. bitleri HIGH durumdadır. Bu GPIOB pinlerinin 0. 7. ve 14. pinleri HIGH durumdadır demektir.
GPIOC IDR register değeri 0x0000DF4F iken 0x0000FF4F haline gelmiştir. Datasheete göre ilk 16 bit önemli değil son 16 bite odaklanacağız.
0xDF4F = 0b 1101 1111 0100 1111
0xFF4F = 0b ‭1111 1111 0100 1111‬
Görüldüğü üzere 0 olan 13. bit 1 olarak değişmiştir. Yani LOW durumdan HIGH duruma geçmiştir. Dolayısıyla buton basılı ve pin aktifleştirildi anlamına gelmektedir.

Aynı zamanda bu değerleri C programlama dilindeki bit kaydırma işlemleri ve maskeleme ile gerçekleştirebiliriz. Tek yapmamız gereken register değerlerini maskelemek. Maskeleme yaparken takip ettiğimiz değere dikkat etmeliyiz.

Aşağıdaki kod bloğunda maskeleme işlemini görmekteyiz. Bu fonksiyon sonuca göre TRUE veya FALSE döndürecektir.

#include <stdbool.h> //bool tipi kullanabilmek için bu header a ihtiyacımız bulunmaktadır
bool checkMaskForIDR(uint16_t IDR_Value, uint16_t mask_input){
	return IDR_Value & mask_input;
}

Aynı zamanda pin çıktılarını direk olarak ODR registeri ile de değiştirebiliriz. Bu registera atanan değer yardımı ile yeni çıktılarımızı belirlemekteyiz. Bu esnada gerekli pinler haricindeki pinlere bir değişiklik yapmamaya dikkat etmeliyiz. Çünkü diğer pinler başka amaçlar için kullanılıyor olabilmektedir. Bu yüzden önemli olan pinleri maskeleyerek registera atama yapılmalıdır.

Aşağıdaki kod bloğu sadece PB0, PB7 ve PB14 pinlerini HIGH yapacak ve diğerlerini LOW yapacaktır.

	if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_13))
		GPIOB->ODR = 0x00004081;
	else
		GPIOB->ODR = 0x00000000;

Eğer sadece gerekli olan pinleri değiştireceksek ilgili registeri o anki değeri ile atamak istediğimiz değeri OR maskesi yapmamız yeterlidir. Bu sayede sadece istediğimiz pinler değişecektir.

Aşağıdaki kod bloğu sadece PB0, PB7 ve PB14 pinlerini HIGH yapacak ve diğerlerinin değerleri değişmeyecek ve olduğu gibi kalacaktır.

	if(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_13))
		GPIOB->ODR |= 0x00004081;
	else
		GPIOB->ODR |= 0x00000000;

Bu yazımızda bu kadar.

Burak Hamdi TUFAN.


Tags


Share this Post

Send with Whatsapp

Post a Comment

Success! Your comment sent to post. It will be showed after confirmation.
Error! There was an error sending your comment.

Comments

  • There is no comment. Be the owner of first comment...