Pages

MATRİS BUTON YAPISI VE MİKRODENETLEYİCİ İLE UYGULANMASI (STM32F746VGT6)

 


Matris buton yapısı basitçe, satırları ve  sütunları ortaklayarak belirli bir tarama ve kesişim mantığı ile basılan butonun algılanmasına dayanır. Bu yapının dezavantajlarından biri aynı anda sadece bir butona basılabilmesidir. Ancak bu şartın gerekli olmadığı sistemlerde bağlantı sayısından oldukça tasarruf edilmesini sağlar. Bu yazımdaki örnek üzerinden konuşmak gerekirse 36 adet butonu mikrodenetleyici üzerinden normal bağlantı ile kontrol etmek istersek 36 farklı giriş pini tanımlamamız gerekir. Ancak matris buton mantığında ise bu sayı 6 satır ve 6 sütun olmak üzere yalnızca 12 pin ile gerçekleştirilebilir.



6x6 Matris Buton Yapısı


KiCad ile 6x6 buton matris yapısı için örnek bir kart tasarladım. İki adet pin header 36 led ve 36 adet buton bulunmakta. 6 satır ve 6 sütunun mikrodenetleyici bağlantısı için iki adet dişi header kullandım.

Kod kısmında ise satırlar ve sütunların giriş ve çıkış olarak iki farklı şekilde tanımlanması gerekiyor. Satırlar çıkış sütunlar ise giriş olarak tanımlanır. Satırlar sırası ile aktifleştirilip o satırda bulunan herhangi bir sütunda bulunan butona basılıp basılmadığı kontrol edilir. İlgili satır pini lojik 1 diğerleri lojik 0 değerine çekilerek sütunlar sırası ile okunur. Eğer herhangi bir sütun pininde 1 değeri okunursa  o satır ve o sütundaki butona basıldığı program tarafından  anlaşılır. Program içerisinde istenilen durum gerçekleştirilir. Ben buton uygulamamda klavye mantığı ile STM32F746VGT6 mikrodenetleyicisini kullanarak USB_OTG_FS üzerinden Virtual Com Port class'ı ile C# arayüzü üzerinden haberleşerek her butona basıldığında bir karakter gönderdim. Konumuz matris buton algoritması olduğu için kod kısmında USB haberleşmesinden bahsetmeyeceğim. 

GPIOA 0-5 pinlerini çıkış,  GPIOD7, GPIOB 3-7 pinleri ise giriş olarak tanımlandı. Çıkış pinleri (satırlar) sırası ile 1 konumuna çekildikten sonra tüm girişler (sütunlar) okunarak butona basılıp basılmadığı kontrol ediliyor. Basıldığı durum için benim kodumda USB üzerinden ilgili karakteri gönderiyor. Bu sayede daha az bağlantı ile daha fazla buton kullanarak mikrodenetleyici pinlerimizden tasarruf etmiş oluyoruz. Ancak yukarıda da belirttiğim gibi aynı anda iki butona basmak mümkün değil. Projenizde bu koşulun sağlanması gerekiyorsa ve daha az pin kullanmanız gerekiyorsa shift register kullanarak yine pinden tasarruf edip buton sayısını artırabilirsiniz.

/*
 * 	GPIOA_0		ROW1	|	GPIOD_7		COLUMN1
 * 	GPIOA_1		ROW2	|	GPIOB_3		COLUMN2
 * 	GPIOA_2		ROW3	|	GPIOB_4		COLUMN3
 * 	GPIOA_3		ROW4	|	GPIOB_5		COLUMN4
 * 	GPIOA_4		ROW5	|	GPIOB_6		COLUMN5
 * 	GPIOA_5		ROW6	|	GPIOB_7		COLUMN6
 */


#include "main.h"
#include "usb_device.h"

uint8_t buffer[64];
char* data;


void SystemClock_Config(void);
static void MX_GPIO_Init(void);


void column1(void);
void column2(void);
void column3(void);
void column4(void);
void column5(void);
void column6(void);

int main(void)
{

	HAL_Init();
	SystemClock_Config();
	MX_GPIO_Init();
	MX_USB_DEVICE_Init();

	while (1)
	{

		column1(); 
		HAL_Delay(5);
		column2();
		HAL_Delay(5);
		column3();
		HAL_Delay(5);
		column4();
		HAL_Delay(5);
		column5();
		HAL_Delay(5);
		column6();
		HAL_Delay(5);

	}
}



void column1(void)
{


	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);  //ROW1
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);//ROW2
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);//ROW3
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);//ROW4
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);//ROW5
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);//ROW6

	if(GPIOA -> IDR & (1<<0))
	{

		if((GPIOD -> IDR & (1<<7)))//COLUMN1
		{
			data = "1";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<3)))//COLUMN2
		{
			data = "2";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<4)))//COLUMN3
		{
			data = "3";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<5)))//COLUMN4
		{
			data = "4";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<6)))//COLUMN5
		{
			data = "5";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<7)))//COLUMN6
		{
			data = "6";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
	}

}

void column2(void)
{

	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);	//ROW2
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
	if(GPIOA -> IDR  & (1<<1))
	{


		if((GPIOD -> IDR & (1<<7)))
		{
			data = "7";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<3)))
		{
			data = "8";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);

		}
		else if((GPIOB -> IDR & (1<<4)))
		{
			data = "9";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<5)))
		{
			data = "10";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<6)))
		{
			data = "11";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<7)))
		{
			data = "12";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
	}

}

void column3(void)
{


	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET); //ROW3
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
	if(GPIOA -> IDR  & (1<<2))
	{


		if((GPIOD -> IDR & (1<<7)))
		{
			data = "13";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<3)))
		{
			data = "14";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<4)))
		{
			data = "15";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<5)))
		{
			data = "16";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<6)))
		{
			data = "17";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<7)))
		{
			data = "18";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
	}

}

void column4(void)
{


	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET); //ROW4
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);

	if(GPIOA -> IDR & (1<<3))
	{

		if((GPIOD -> IDR & (1<<7)))
		{
			data = "19";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<3)))
		{
			data = "20";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<4)))
		{
			data = "21";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<5)))
		{
			data = "22";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<6)))
		{
			data = "23";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<7)))
		{
			data = "24";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
	}

}

void column5(void)
{

	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); //ROW5
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
	if(GPIOA -> IDR  & (1<<4))
	{


		if((GPIOD -> IDR & (1<<7)))
		{
			data = "25";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<3)))
		{
			data = "26";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);

		}
		else if((GPIOB -> IDR & (1<<4)))
		{
			data = "27";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<5)))
		{
			data = "28";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<6)))
		{
			data = "29";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<7)))
		{
			data = "30";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
	}

}

void column6(void)
{


	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); //ROW6
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
	if(GPIOA -> IDR  & (1<<5))
	{


		if((GPIOD -> IDR & (1<<7)))
		{
			data = "31";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<3)))
		{
			data = "32";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<4)))
		{
			data = "33";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<5)))
		{
			data = "34";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<6)))
		{
			data = "35";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
		else if((GPIOB -> IDR & (1<<7)))
		{
			data = "36";
			CDC_Transmit_FS((uint8_t *) data,strlen(data));
			HAL_Delay(10);
		}
	}

}

Emre Aytur

Gömülü Sistemler, Elektronik, Teknoloji