2023. 4. 8. 20:31ㆍ[Harman] 세미콘(semiconductor) 아카데미-반도체설계/임베디드 시스템을 위한 SW 구조설계
STM32F411RE보드를 이용하여 내부 소스코드 확인 및 GPIO_Read, GPIO_Write, GPIO_Toggle 함수를 이용하여 소스코드 작성 후 LD2 LED를 점등 및 소등 하였다.
저번 시간에 GPIO PORT를 확인하며 본 레지스터는 데이터를 저장하는 기억장치로 RAM에 저장된다.
- 레지스터
레지스터는 각종 상태, 전송 속도, DATA길이 등의 상태들을 저장하는 데이터이다. 이 레지스터를 확인하려면 해당 소스코드의 헤더파일을 찾아 해당 함수를 호출하여 리턴값을 확인하면 된다. (16비트 레지스터는 16가지의 데이터를 저장하는 것이라 보면 된다.)
- GPIO
GPIO의 16개 핀을 묶어 놓은 것을 GPIO 포트라 한다. 그러면 GPIO PORTA는 해당 포트안에 16개의 GPIO핀이 존재한다 보면 된다. 우리가 사용하는 포트(NUCLEO-F411RE)는 PORT가 A, B, C로 3개 존재한다.
현재 System Core - GPIO에서 볼 수 있는 PA5는 PORTA의 5번 레지스터를 의미한다.
우리가 사용하는 GPIO의 레지스터는 5개가 존재한다. (Signal on pin, GPIO output level, GPIO mode, GPIO Pull-up/pull down, Maximum output speed)
현재 PA5에 GPIO output level에 Low가 들어가 있으므로 output level 레지스터의 5번 자리에 Low가 들어가 있게 된다.
GPIO PORT에는 각각의 기능들이 나눠져 있다.
각각의 레지스터에는 자신이 설정한 기능들이 2비트로 입력되어 있다.
GPIO포트들 중에는 pull up / pull down 레지스터가 존재하는데 11비트의 Reserved는 없는 기능이라 보면 된다.
GPIO port pull-up/pull-down register는 기능이 3가지있다 보면 된다.
그외에도 데이터를 입력받는 input data register와 output data register 또한 존재하는데 해당 기능의 레지스터를 살펴보면 비트가 아닌 r, rw등의 알파벳이 적혀있는 것을 확인할 수 있다.
해당 레지스터의 뜻은 레퍼런스 메뉴얼의 1.1 List of abbreviations for registers에서 알 수 있다.
레지스터 약어를 나타내주는 목록들로 위의 입력 레지스터의 r은 읽기만 가능한 레지스터 / rw는 읽고 쓸 수 있는 레지스터로 각각의 레지스터들 마다 값에 따라 기능이 나눠져 있는 것을 확인할 수 있다. (r이 있는 레지스터에는 데이터를 쓰는 것이 불가)
rw | 읽고 쓸 수 있는 레지스터 |
r | 읽기만 가능한 레지스터 |
w | 쓰기만 가능한 레지스터 |
인터럽트 레지스터에 레지스터 약어가 많이 존재한다.
Peding regiset는 인터럽트 실행 후 변경된 인터럽트 데이터의 설정을 클리어 해주는 기능(RESET 시켜주는 인터럽트)이라 보면 된다. (인터럽트는 Peripheral을 통해 설정한다 / main문의 무한루프를 잠시 세워두는 것으로 사용)
GPIO alternate function register 또한 존재한다.
해당 레지스터는 한 덩어리당 포트 핀 1개를 의미한다.(low register = 8개의 핀) 그러나 우리가 사용하는 포트는 16개의 핀으로 구성되어 있는데 low register만 사용하면 8개의 핀만 나타낼 수 있으니 high regiser로 추가 레지스터를 설정한다.
MODER(Configure) 레지스터 = 해당 포트가 어떤 기능을 할 지 설정하는 레지스터
INPUT, OUTPUT, bit set/reset 레지스터 = 해당 포트들의 상태를 설명하는 레지스터
STM32보드를 사용하기에 앞서 CubeIDE를 이용하여 보드와 디버깅을 최신버전으로 업데이트 해주는 것이 좋다.
Run - Debug 시 Edit Configuration에서 에뮬레이터, 결선상태(swd / jtag)등을 설정할 수 있다.
디버거는 자신에게 맞는 디버거를 다운로드 받아 사용할 수 있는데 이 디버거를 설정하는 방법이 있다
디버거를 설정할 프로젝트 선택 - Properties - Run/Debug Setting에서 설정가능하다.
System Core - GPIO에서 각 레지스터들의 설정을 변경할 수 있다.
System Core이외에도 헤더파일에서의 함수를 불러와 main문에 추가하여 설정을 변경할 수도 있다.
먼저 우리가 사용하는 푸쉬버튼 핀은 전처리기로 0x2000이란 값이 GPIO_PIN_13이라는 상수에 저장되어 있는것을 확인할 수 있다.
0x2000 -> 0b 0010 0000 0000 0000 -> 13번핀
(전처리기) # define A B = A의 상수를 B로 정의한다. (전처리기로 정의된 상수는 ROM에 저장된다.)
ex)
define c 100 = c가 100인 상수로 정의
define a c+100 = a는 c+100(200)인 상수로 정의
C언어나 다른 언어를 할 때 주소값
0x00으로 주소 지정 = 16진수
0O00으로 주소 지정 = 8진수
0b00으로 주소 지정 = 2진수
숫자 = 10진수
해당 코드는 B1_Pin에 GPIO_PIN_13이란 값을 넣는다 -> GPIO_PIN_13에 0x2000이라는 주소값을 넣는다 -> B1_Pin만 사용해도 0x2000이 입력된다.
현재 초록 불이 들어오는 LD2의 주소값은 0x0020이란 것을 확인할 수 있다.
이제 헤더파일의 함수를 들고와 소스코드를 작성하여 LD2를 점등하고 소등해 보도록 하자.
GPIO와 관련된 헤더파일은 위의 경로를 통해 볼 수 있다.
- LD2 점등 1
먼저 HAL_GPIO_WritePin 함수를 통해 LD2를 점등시켜 보도록 한다.
우리가 사용하는 포트는 PA5로 GPIOA를 입력하면 된다. 각 함수의 매개변수는 해당 매개변수 설명에 맞게 입력해주면 된다.
LD2를 점등시키기 위해서는 Core - Src - main.c의 main문에서 while안에 코드를 작성하도록 한다.
GPIO_PIN_SET = HIGH값
GPIO_PIN_RESET = 0 (LOW값)
해당 코드를 작성 후 RUN 시켰을 시 정상적으로 LD2가 점등되는 것을 확인할 수 있다.
- LD2 점등 2
이번엔 HAL_GPIO_ReadPin함수를 이용하여 푸쉬버튼의 입력을 받으면 LD2 점등, 푸쉬버튼을 때면 소등하는 코드를 작성해 보도록 한다.
해당 코드 작성 후 RUN 시켰을 시 버튼 누르면 LED 점등, 땠을 시 소등되는 것을 확인할 수 있다.
- LD2 점등 3
이번엔 HAL_GPIO_TogglePin함수를 이용하여 핀을 토글시켜 LD2를 점등, 소등 시켜보도록 한다.
main문 시작 시 MX_GPIO_Init() 함수를 먼저 실행하므로 LD2핀이 LOW인 상태이다. 이때 HAL_GPIO_TogglePin함수를 이용하여 토글 시 LOW -> HIGH값으로 변하므로 LD2가 점등되는 것을 확인할 수 있다.
- 토글을 이용하여 푸쉬버튼을 누를 시 1초 점등, 1초 소등을 3번 반복하는 코드를 작성
HAL_GPIO_ReadPin함수를 조건문으로 걸어 HLA_TogglePin함수를 이용하여 점등, 소등 시켰다.
- 코드 해석
해당 코드를 해석해보면
먼저 HAL_GPIO_ReadPin함수를 조건문으로 받는다.
현재 푸쉬버튼이 OFF된 상태로 가정해 보면 PC13에 HIGH값이 들어가는 것을 알 수 있다.
HAL_GPIO_ReadPin 함수를 살펴보면 (GPIOx->IDR & GPIO_Pin) 이 true일 시 bitstatus에 GPIO_PIN_SET값이 / false일 시 GPIO_PIN_RESET값이 리턴값으로 반환되는 것을 볼 수 있다.
조건문의 GPIOx->IDR의 IDR은 포트 입력 데이터 레지스터이므로 현재 푸쉬버튼이 OFF상태라 PC13에 VDD가 입력되고 있으므로 해당 부분에만 1이 들어가게 된다. 또한 GPIO_PIN은 0x2000으로 13번 레지스터가 같은 HIGH값이 된다.
그러므로 GPIO_PIN_SET을 리턴값으로 반환한다.
if문이 true로 해당 부분을 실행하게 된다. 조건문에서 PinsState가 GPIO_PIN_RESET와 같이 않으면 true이다. 현재 PinState가 GPIO_PIN_RESET을 입력받은 상태로 해당코드를 수행하게 된다.
BSRR은 포트의 bit set/reset regiset를 나타내는데 현재 매개변수로 받은 GPIO_Pin을 시프트 레지스터로 16U 왼쪽 이동시키면 모든 레지스터가 0의 값을 가지게 된다.
BSRR의 13 레지스터에 0을 입력하게 되므로 bit set/reset regiset는 0일 시 아무런 동작을 시키지 않으므로 LD2가 소등된다.
만약 푸쉬버튼을 누르게 되면 PC13에 VDD가 입력되지 않아 처음 if문에 false를 받게 되어
GPIOx->BSRR에 GPIO_Pin(0x2000)을 입력받아 LD2가 점등하게 된다.
'[Harman] 세미콘(semiconductor) 아카데미-반도체설계 > 임베디드 시스템을 위한 SW 구조설계' 카테고리의 다른 글
임베디드 시스템을 위한 SW 구조설계 6 (3) | 2023.04.18 |
---|---|
임베디드 시스템을 위한 SW 구조설계 5 (1) | 2023.04.16 |
임베디드 시스템을 위한 SW 구조설계 4 (0) | 2023.04.15 |
임베디드 시스템을 위한 SW 구조설계 3 (0) | 2023.04.12 |
임베디드 시스템을 위한 SW 구조설계 1.2 (0) | 2023.04.08 |