| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
| 29 | 30 | 31 |
- 코틀린
- 다이나믹 프로그래밍
- kotlin
- 구현
- BFS
- c++
- 누적합
- 프로그래머스
- 백준
- C
- 이분탐색
- JavaScript
- 동적계획법
- 컴퓨터 비전
- level3
- level2
- cpp
- 임베디드
- 2018 KAKAO BLIND RECRUITMENT
- java
- dfs
- Stack
- 그리디
- 통신 인터페이스
- 다이나믹프로그래밍
- dp
- 자바
- 컴퓨터비전
- 우선순위큐
- lv2
- Today
- Total
코드를 느껴바라
[임베디드] 라즈베리파이로 7-Segment 제어해서 스톱워치 만들기 본문
라즈베리파이로 7-Segment를 제어해서 버튼을 눌렀을때 0~9 반복 동작하게 하기
우선 준비할 데이터 시트는 7-Segment와 라즈베리파이 4 Model B의데이터 시트이다.


우선 각각의 다이오드를 어떨때 켜고 끌지에 대해서만 생각하면 간단하게 구현할 수 있다.
코드부분
코드에 대해서 먼저 설명을 하자면 나는 좀 이해하기 쉽고 간단하게 하기 위해
각각의 7-Segment의 다이오드 명에 대해서 라즈베리파이 GPIO 핀번호 몇번에 꽂았는지에 대해서 배열로 저장을 해주었다.
//up
pin_num['g'] = 14;
pin_num['f'] = 15;
pin_num['a'] = 18;
pin_num['b'] = 23;
//down
pin_num['e'] = 22;
pin_num['d'] = 10;
pin_num['c'] = 9;
pin_num['p'] = 11;
0~9까지의 숫자 각각에 대한 그 순간 쳐야할 다이오드 명의 조합에 대해서
문자열 배열로 저장을 해서 저장을 해주었다.
volatile char* turn_led_str [10]={"abfedc", "bc", "abged", "abgcd", "fgbc", "afgcd", "afedcg", "abc", "abcdefg", "abfgcd"};
이렇게 저장을 해주면 turn_led_str의 인덱스 별로 불러와서 각 문자에 대해서 반복을 돌며 켜주고 난 후 sleep(1)을 통해서
1초 켜주면 된다.
그리고 각 카운트 시작마다 전부 꺼주고 시작하도록 한다.
회로 구성
회로 구성은 아래의 참고사진이 있으나 알아보기 힘들기 때문에 간단히 설명을 해보겠다.

우선 7-Segment의 상단에 공통 vcc를 연결해줘서 Common Anode 방식을 통해서 LOW일때 불이 들어오도록 해주었다.

이렇게 두가지 방식이 있는데 차이점은 공통 부분을 전원에 연결하냐 그라운드에 연결하냐 차이인데
풀업, 풀다운이랑 비슷해보이지만 다르다고 한다.
| 공통 애노드 | VCC | LOW 출력 |
| 공통 캐소드 | GND | HIGH 출력 |
Common Anode, Common Cathode 중에 Common Anode방식을 좀 더 많이 사용한다고 한다.
그 이유는 대부분의 MCU는 전류를 흡수(sink) 하는 능력이 더 좋아서 실무에선 오히려 더 안정적이라고 보는 경우 많다고 함.
코드
#include<stdio.h>
#include<fcntl.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/mman.h>
#include<string.h>
#define GPIO_BASE (0xFE200000)
#define GPIO_SIZE (256)
#define GPIO_IN(g) (*(gpio+((g)/10))&=~(7<<(((g)%10)*3)))
#define GPIO_OUT(g) \
(*(gpio+((g)/10)) &= ~(7<<(((g)%10)*3))), \
(*(gpio+((g)/10)) |= (1<<(((g)%10)*3)))
#define GPIO_SET(g) (*(gpio+7)= 1 <<g)
#define GPIO_CLR(g) (*(gpio+10)= 1 <<g)
#define GPIO_GET(g) (*(gpio+13)& (1 <<g))
volatile unsigned *gpio;
volatile int pin_num ['z'+1] = {0,};
volatile char* turn_led_str [10]={"abfedc", "bc", "abged", "abgcd", "fgbc", "afgcd", "afedcg", "abc", "abcdefg", "abfgcd"};
volatile char leds [] = {'a','b','c','d','e','f','g', 'p'};
int main(int argc, char **argv){
int gno, i, mem_fd;
void * gpio_map;
//up
pin_num['g'] = 14;
pin_num['f'] = 15;
pin_num['a'] = 18;
pin_num['b'] = 23;
//down
pin_num['e'] = 22;
pin_num['d'] = 10;
pin_num['c'] = 9;
pin_num['p'] = 11;
if(argc < 2){
printf("Usage: %s GPIO_NO\n", argv[0]);
return -1;
}
gno = atoi(argv[1]);
mem_fd = open("/dev/mem", O_RDWR|O_SYNC);
if(mem_fd < 0){
perror("open /dev/mem failed");
return -1;
}
gpio_map = mmap(
NULL,
GPIO_SIZE,
PROT_READ|PROT_WRITE,
MAP_SHARED,
mem_fd,
GPIO_BASE
);
if(gpio_map == MAP_FAILED){
printf("[Error] mmap() : %d\n", (int)gpio_map);
close(mem_fd);
return -1;
}
gpio = (volatile unsigned *)gpio_map;
for(int i=0; i<sizeof(leds); i++){
GPIO_OUT(pin_num[leds[i]]);
}
GPIO_IN(gno);
int digit = 0;
while(1){
int pressed = (GPIO_GET(gno) == 1);
for(int k=0; k<sizeof(leds); k++){
GPIO_CLR(pin_num[leds[k]]);
}
int digit = 0;
while(1){
int pressed = (GPIO_GET(gno) == 0); // 풀업이면 LOW가 눌림
if(pressed){
// 먼저 전체 끄기
for(int k=0; k<sizeof(leds); k++){
GPIO_SET(pin_num[leds[k]]);
}
// 현재 숫자 켜기
for(int j=0; j<strlen(turn_led_str[digit]); j++){
GPIO_CLR(pin_num[turn_led_str[digit][j]]);
}
sleep(1); // 1초 간격으로 증가
digit = (digit + 1) % 10;
}
else{
usleep(20000); // CPU 과부하 방지
}
}
}
munmap((void *)gpio, GPIO_SIZE);
close(mem_fd);
return 0;
}
출처
https://datasheets.raspberrypi.com/rpi4/raspberry-pi-4-datasheet.pdf
The Ultimate Guide to 7 Segment Display: Pinout, Working, and Datasheet - Jotrin Electronics
Displays are widely utilized in embedded systems and devices, with one standout example being the timers on kitchen appliances, digital clocks, and the dramatic bomb timers often seen in movies. What unites them all is the use of seven-segment displays to
www.jotrin.com
7-Segment LED Displays Guide with Arduino Interfacing | Sensors a..
7-segment LED displays are basically used to display numerical values from 0 to 9 and few characters like A, b, C, d, e, F, H, L, O, P, U etc.7-segment displays are widely used in digital clock.
www.electronicwings.com
'개발 > 임베디드(Embedded)' 카테고리의 다른 글
| [임베디드] TC275 STM 신호등 : 외부 인터럽트(ERU)와 Flag 기반 상태 머신 구현 (2) | 2026.02.23 |
|---|---|
| [임베디드] 리눅스 디바이스 드라이버로 GPIO LED 제어하기 (Linux Kernel) (0) | 2026.02.13 |
| [네트워크] I2C 통신 인터페이스 개요 (2) | 2026.02.06 |
| [네트워크] U(S)ART 통신 인터페이스 (0) | 2026.02.06 |
| [네트워크] 임베디드 통신 개요 (Embedded Communication Overview) (0) | 2026.02.05 |
