임베디드/STM32 (ARM Cortex - M4)

[STM32] LED BAR 제어

O_oz 2023. 10. 16. 21:06
반응형

위와 같은 LED BAR를 제어해 볼 예정이다

LED가 8개, 그에 상응하는 핀이 각 2개씩 총 16

영어가 쓰여있는 부분을 + 전극을 결선해주면 되고 반대부분은 저항을 물려서 - 전극과 연결해준다

 

이처럼 연결하자

점퍼 케이블의 반대편은 개발 보드에 연결할 것이다

 

개발 보드에 연결하기 전에

어떤 포트의 어떤 핀에 연결할지 정해보자

 

포트 D의 0번 핀부터 7번핀까지 활성화해서 LED 제어에 사용해보겠다

프로젝트에서 ioc를 눌러 PD0 부터 PD7까지 GPIO_Output으로 활성화하고 저장을 눌러 Code Generation 해주자

 

그러면 main.c에

위와 같은 코드가 자동으로 생성되어 있을 것이다

 

Core -> Src에 LED BAR를 제어할 새로운 소스파일을 하나 생성해야 한다

led.c로 소스 파일을 생성하자

#include "main.h"		// for GPIO, HAL

void led_all_on(void)
{
//	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7, 1);
	HAL_GPIO_WritePin(GPIOD, 0xff, 1);
}

void led_all_off(void)
{
//	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7, 0);
	HAL_GPIO_WritePin(GPIOD, 0xff, 0);
}

GPIO 구조체와 HAL 명령어를 사용하기 위해 main.h를 include 해주고

LED BAR의 전체 LED를 키고 끄는 함수를 작성하였다

 

main.c로 돌아와

led.c에서 생성한 led 함수들을 사용하기 위해

위와 같이 Private function prototypes 부분의 유저 코드에 각각 extern 해주었다

 

main의 while 문 안에 100ms마다 LED BAR를 점등하는 코드를 작성했다

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  led_all_on();				// led bar를 다 켰다가
	  HAL_Delay(100);			// 100ms를 기다리고
	  led_all_off();			// led bar를 다 껐다가
	  HAL_Delay(100);			// 100ms를 기다린다
  }
  /* USER CODE END 3 */
}

 

 

이제 아까 점퍼 케이블을 개발 보드에 연결하는 일만 남았다

 

데이터 시트를 보면 CN8, CN9 커넥터에 PD0번부터 PD7번이 존재한다는 것을 알 수 있다

0부터 7까지 점퍼 케이블을 순서대로 연결해주도록 하자

 

PD0부터 PD7까지 위와 같이 연결하고 브레드 보드에 전기를 공급해주기 위해 CN 8 9번과 11번 핀을 +, - 전극에 연결해준다

 

프로젝트를 컴파일 후 다운로드 해주면 아래와 같이 LED BAR가 깜빡이는 것을 확인할 수 있다

 

 

추가적으로 각각의 LED에 접근하는 방법에 대하여 알아볼 것이다

아까 LED 전체를 껐다 키는 함수는 아래와 같다

void led_all_on(void)
{
//	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7, 1);
	HAL_GPIO_WritePin(GPIOD, 0xff, 1);
}

void led_all_off(void)
{
//	HAL_GPIO_WritePin(GPIOD, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7, 0);
	HAL_GPIO_WritePin(GPIOD, 0xff, 0);
}

HAL_GPIO_WritePin()은

GIPIx의 Pin 상태를 설정한다는 함수이고

Pin의 상태는 0과 1이 있다

 

즉 위의 led_all_on 함수는 GPIOD의 0xff에 해당하는 핀들의 상태를 1로 바꾼다는 의미이다

이렇게 되면 while 문 안에서 LED BAR의 상태가 0과 1을 오가기 때문에 LED가 켜졌다 꺼졌다한다

 

그럼 0xff의 의미는 뭘까?

이전에 개발 보드 내의 LED를 제어했을 땐 (https://oz-97.tistory.com/28 참조)

이처럼 Pin Number를 명시하여 하나의 LED를 토글 시키는 것을 확인할 수 있다

LED BAR 제어 함수의 0xff는 LED BAR에 해당하는 Pin 8개의 Pin Number를 한번에 표현했다고 볼 수 있다

8개의 LED가 있고 각 자리가 한 비트씩 차지한다고 했을 때

8개의 LED를 가진 LED BAR는 8비트로 표현가능하고 이를 16비트로 표현하면 0x♡♡가 되며전체 LED를 가리키는 것이 0xff이다

 

이 사실을 할면 비트 연산자를 가지고 LED를 순서대로 하나씩 키는 것이 가능하다

 

led.c에 아래 코드를 추가하고 main.c에서 이를 실행하면

void led_on_up(void)
{
	for (int i = 0; i < 8; i++)
	{
		led_all_off();
		HAL_GPIO_WritePin(GPIOD, 0x01 << i, 1);
		HAL_Delay(200);
	}
}

for 문을 돌면서 Pin Number가 00000001부터 10000000까지 비트 쉬프트 연산이 진행된다

 

실행하면 위와 같다

 

이렇게 여러개의 LED를 16진수나 | 연산자를 사용해 원하는 모양을 출력하는 연습을 해도 좋을 것 같다

 

반응형