본문 바로가기
Firmware Programming

[STM32F429ZI] 8x8 LED (1088BS) 제어

by TYB 2024. 1. 18.
반응형

 

대부분의 모듈은 이런 번호배치를 가짐 . 모듈번호 적힌 곳 왼쪽이 1

 

 

 

 

공통 행 양극 방식: 행에 High를 주고 열에 Low를 주면 Led 동작에 최적화된 정격전류가 흐름으로써 불이 켜진다.                                        공통 열 양극 방식 :행에 Low를 주고 열에 HIgh를 주면 Led 동작에 최적화된 정격전류가 흐름으로써 불이 켜진다.

 

왜 행에 High를 주고 열에 Low 를 줘야되는지 모르겠다면 아래 링크를 보고 오자.

https://program-developers-story.tistory.com/21

 

[STM32F429ZI] GPIO를 통한 LED 제어

GPIO(General Purpose Input Output) 범용 입출력 장치 다양한 용도로 사용하는 입출력 장치가 되겠다. 보드를 정면으로 바라봤을때 좌측라인이 아래 핀맵사진의 내용이다. 핀맵은 앞으로 전자회로 부품

program-developers-story.tistory.com

 

 

위 그림의 핀의 숫자는 모듈의 물리적인 핀 번호를 의미함. 행은 실제 매트릭스에 표시되는 행이나 열을 의미함.

 

 

LED 매트릭스 연결 회로도 모듈의 실제 핀을 STM32의 해당되는 포트에 연결해주면 되겠다. 저항이 있는 포트는 330Ohm 저항 연결필요!

 

pin1~8이  그림 상에는 PD0~PD7로 나와있고, pin9~16이 그림 상에는 PC0~PC7로 나와 있다.

만약 윗 그림과 같이 연결하려면 ioc파일에서 사용할 핀을 그것에 맞게 세팅해주면 된다.

 

비트 시프트 연산을 활용해서 8x8 matrix의 dot를 표현할 것이기 때문에 핀은 인접한 핀들로 해주어야 한다.

 

 

그림과 다르게 실제로 연결은 아래와 같이 하였다.

pin1 -> PD4 / pin2 -> PD6 / pin3 -> PE3 / pin4 -> PE4 / pin5 -> PD7 / pin6 -> PE6 / pin7 -> PD5 / pin8 -> PD2

pin9 -> PD0 / pin10 -> PE5 / pin11 -> PE7 / pin12 -> PD3 / pin13 -> PE2 / pin14 -> PD1 / pin15 -> PE8 / pin16 -> PE9

 

 

 

 

 

 

 

앞서 말했듯 회로도 상 저항 있는 핀들은 저항을 꽂아주면 된다.

 

그럼 이제 CUBE IDE를 열고, HW 연결대로 ioc 파일 세팅을 해주면 되는데 아래의 코드를 그대로 사용하기 위해서는 pin 번호에 맞게 labeling을 해줘야한다. pin setting은 모두 GPIO_OUTPUT이고 pin1~pin8을  COL1~COL8로 user labeling해주고,  pin9~pin16을  ROW1~ ROW8로 user labeling해주면 되겠다.

 

Online led matrix font generator with binary and hex codes for Arduino

 

Online led matrix font generator with binary and hex codes for Arduino

Online led matrix font generator with binary and hex codes for Arduino

www.riyas.org

여기 링크에서 8bit binary형태의 8칸 배열 생성 가능, 생성 후 아래 unsigned char처럼 변수명 주고 B를 0b로 바꿔서 넣어주면 됨.

 

 

 

아래의 코드를 dotmatrix.c 파일을 생성 후 복붙 

#include "dotmatrix.h"

GPIO_TypeDef *col_port[]=
{
	COL1_GPIO_Port,COL2_GPIO_Port,COL3_GPIO_Port,COL4_GPIO_Port,
	COL5_GPIO_Port,COL6_GPIO_Port,COL7_GPIO_Port,COL8_GPIO_Port
};

GPIO_TypeDef *row_port[]=
{
	ROW1_GPIO_Port,ROW2_GPIO_Port,ROW3_GPIO_Port,ROW4_GPIO_Port,
	ROW5_GPIO_Port,ROW6_GPIO_Port,ROW7_GPIO_Port,ROW8_GPIO_Port
};

uint16_t col_pin[] =
{
	COL1_Pin,COL2_Pin,COL3_Pin,COL4_Pin,
	COL5_Pin,COL6_Pin,COL7_Pin,COL8_Pin
};

uint16_t row_pin[] =
{
	ROW1_Pin,ROW2_Pin,ROW3_Pin,ROW4_Pin,
	ROW5_Pin,ROW6_Pin,ROW7_Pin,ROW8_Pin
};


unsigned char all_on[] =//all on 문자 정의
{
	0b11111111,
	0b11111111,
	0b11111111,
	0b11111111,
	0b11111111,
	0b11111111,
	0b11111111,
	0b11111111
};

unsigned char woo[] =
{
	0b00011000,
	0b00100100,
	0b01000010,
	0b00111100,
	0b00000000,
	0b11111111,
	0b00011000,
	0b00011000
};

unsigned char chang[] =
{
	0b00100100,
	0b11111100,
	0b00100100,
	0b01010111,
	0b10001100,
	0b01110100,
	0b10001100,
	0b01110000
};
unsigned char min[] =
{
	0b00000010,
	0b01111010,
	0b01001010,
	0b01001010,
	0b01111010,
	0b00000010,
	0b00100000,
	0b00111110
};


void write_column_data(int col)
{
	for(int i = 0; i < 8; i++)
	{
		if(i == col)
		{
			HAL_GPIO_WritePin(col_port[i], col_pin[i], 0);//on
		}
		else
		{
			HAL_GPIO_WritePin(col_port[i], col_pin[i], 1);//off
		}
	}
}


void write_row_data(unsigned char data)
{
	unsigned char d;

	d = data;//0b00111100

	for(int j = 0; j < 8; j++)
	{
		if (d & (1 << j))//1을 0만큼 shift하면 00000001 , 1만큼 shift하면 00000010 그걸 data와 AND연산
		{
			HAL_GPIO_WritePin(row_port[j],row_pin[j],1);
		}
		else
		{
			HAL_GPIO_WritePin(row_port[j],row_pin[j],0);
		}
	}
}


int dotmatrix_main_test(void)
{
	static int index=0;
	//공통 양극 방식 도트매트릭스
	//COL High, ROW Low
	if(index < 200)
	{
		for(int idx = 0; idx < 8; idx++)
		{
			write_column_data(idx);
			write_row_data(woo[idx]);

			HAL_Delay(1);

		}
	}
	else if(index>200&&index<400)
	{
		for(int idx = 0; idx < 8; idx++)
		{
			write_column_data(idx);
			write_row_data(chang[idx]);

			HAL_Delay(1);
		}
	}
	else if(index>400&&index<600)
	{
		for(int idx = 0; idx < 8; idx++)
		{
			write_column_data(idx);
			write_row_data(min[idx]);
			HAL_Delay(1);
		}
	}
	if(index==600)
	{
		index=0;
	}
	index++;
	return 0;
}

  

dotmatrix.h

#include "main.h"

void write_column_data(int col);
void write_row_data(unsigned char data);
int dotmatrix_main_test(void);

 

자 이제 main.h에 가서 #include "dotmatrix.h"를 해주고, main.c의 main문에 while(1) 내부에 dotmatrix_main_test();를 추가해주면 된다.

 

 

결과는 아래와 같다. 동영상으로 보면 1초에 60 frame이기 때문에 1행 단위로 업데이트 되는것이 보이지만, 실제로 사람눈은 그렇게 민감하지 않기 때문에 정상적으로 켜져있는 것으로 보인다.

 

만약 글자가 더 빠르게 혹은 느리게 변하기를 원한다면 dotmatrix_main_test함수 내부의 index를 비교하는 조건문의 조건을 낮추거나 높이면 된다.

 

 

 

 

반응형