CS 17

최성원·2022년 2월 7일
0

CS

목록 보기
15/16

Day-17

6장 입출력과 네트워킹

-컴퓨터는 외부와 어떻게 상호작용하는가

7. 저수준I/O

가장 단수한 I/O는 CPU가 읽거나 쓸 수 있는 비트에 물건을 연결한 형태의 I/O다.
이런 형태의 I/O가 널리 쓰이게 되면서 점점 더 복잡한 장치로 진화함

I/O 포트

LED는 발광 다이오드(반도체 장치)다.
다이오드는 전기를 회로도에 표시된 속이 빈 화살표 방향으로만 흐르도록 제한한다.
LED는 다이오드 역할을 하면서 부수적으로 빛도 나는 장치다.
포트의 종류(PortA, PortB, PortC, PortD, PortE, PortF)

포트 B는 세 가지 레지스터(DDRB, PORTB, PINB)에 의해 제어

  • DDRB(Data Direction Register B)는 데이터 방향 레지스터
  • PORTB는 출력 데이터를 저장
  • PINB는 핀의 값을 읽는다.


버튼을 눌러라

버튼이나 스위치가 설계된 방식으로 인해 컴퓨터가 이들의 값을 읽기는 쉽지 않음
푸시 버튼은 두 접점과 버튼이 눌리면 두 접점을 연결해주는 금속 조각으로 이뤄져 있다

R은 풀업(Pull-up)저항이라고 부름

  • 버튼이 눌리지 않은 경우
    • 저항이 프로세서의 인터럽트 요청(IRQ,Interrupt request)핀에 연결된 선의 전압을
      공급 전압(Voltage)까지 올려 논리 1을 만듬
  • 버튼이 눌릴 경우
    • 저항은 IRQ에 회로가 타지 않게 전압에서 흘러 오는 전류를 제한하면서 논리 0을 공급 버튼에 연결 된 금속 조각이 접점에 닿으면 금속 조각이 아주 잠깐 바운스되어 접점에서 떨어짐
      -버튼을 프로세서의 인터럽트 발생 핀에 연결했기 때문에 인터럽트가 여러 번 발생할 수 있음

디바운스하는 간단한 방법은 인터럽트 핸들러에 타이머를 설정하고 그 시간이 지나면
버튼 상태를 감지하는 것

접근 방식을 2가지 방법으로 실현 가능
1. 최초 인터럽트 시 타이머를 설정하는 방법
2. 안터럽트가 발생할 때마다 기존 타이머를 새 타이머로 재 설정하는 방법
어떤I/O포트에 연결된 버튼이 8개 있다고 가정하자, 이 I/O포트의 상태는 INB라는 8비트 unsigned char 변수를 통해 읽을 수 있다.
(unsigned char: 부호를 고려하지 않은 수)
유한 임펄스 응답 필터를 만들 수 있다.


유한 임펄스 응답 필터는 타이머 틱이 발생할 때마다 가장 오래된 값을 버리고
새 값을 넣으면서 각 값을 하나씩 시프트 한다.
그리고 배열 원소들을 OR해서 상태를 만들어내고, 원소가 2개(current와 previous) 있는
큐의 currnet 입력으로 넣는다.
currnet에 값을 넣기 직전에 기존 current 값은 previous로 옮긴다.
이제는 current와 previoust 상태를 XOR하면 어떤 버튼이 상태가 바뀌었는지 알 수 있다.
(XOR : 2개 입력이 서로 같으면 출력이 ‘0’ , 서로 다르며 ‘1’로 동작)
FILTER_SIZE는 필터의 원소 개수이며, 이 개수는 버튼의 잡음이 얼마나 많은 지와
인터럽트가 얼마나 자주 걸리는 지에 따라 정해야 한다.

빛이 있으라

7세이그먼트

  • 7개의 LED가 숫자 8형태로 나열
  • 소수점을 표현하는 LED가 하나 더 붙음
  • 가장 흔한 유형의 디스플레이


보통 각 LED마다 핀을 1개씩 연결하고, 핀 하나에는 모든 LED를 연결하여
LED 온오프를 한쪽 끝으로 제어하게 된다. (비용절감)
보통 디스플레이를 하나만 사용하는 경우는 드물다.
예를 들어 알람 시계는 숫자가 4개 필요하다.
각 디스플레이를 별도의 I/O 포트에 연결할 수도 있지만,
프로세서가 충분한 수의 포트를 제공하지 못하는 경우가 흔하다.
해법은 디스플레이의 애노드를 포트 A에 연결하고 캐소드를 B에 연결해서
디스플레이를 멀티플렉스 하는 것이다.

디스플레이 애노드는 병렬로 연결된다. 각 디스플레이의 캐소드는 자신만의 출력 핀에 연결된다.
어떤 디스플레이 세그먼트가 켜지려면 해당 디스플레이의 애노드가 1인 동시에 캐소드가 0이어야 한다.
이 디스플레이가 작동하기 위해 사람의 시각의 잔상효과를 활용한다.
우리 눈과 두뇌는 1/24초 보다 짧은 간격으로 깜빡거리는 경우, 빛이 켜져 있는 것으로 인식한다.
앞의 푸시 버튼 예제에서 사용한 것과 비슷한 타이머 인터럽트 핸들러를 사용해
짧은 시간 간격으로 디스플레이를 계속 변경하면서 세그먼트를 짧게 켰다 껐다 하면
세그먼트가 계속 켜진 것처럼 보이게 할 수 있다.

빛, 동작, 그리고 상호 연동

어떤 장치에 버튼과 디스플레이가 함께 있는 경우도 종종 있다.

버튼이 12개 있는 전화기 스타일의 키패드와 숫자4개를 표시하는 디스플레이며,
버튼과 디스플레이의 입력을 멀티플렉싱하여 푸시 버튼 12개 사용하기 위해
핀을 12개 추가 하지 않고 단지 3개만 추가하면 된다.
모든 푸시 버튼은 풀업 저항에 의해 논리 1로 끌어 올려진다.
디스플레이가 선택되지 않는 경우 버튼을 눌러도 B 출력이 모두 1이기 때문에 아무 효과가 없다.
가장 왼쪽 디스플레이가 선택된 경우 B0B_0가 로우이고,
맨 윗줄의 버튼 중 어느 하나를 누르면 그와 연결된 C 입력이 로우가 된다.
디스플레이와 푸시 버튼이 똑같은 신호에 의해 선택되기 때문에,
상태를 스캔하는 코드를 타이머 인터럽트 핸들러에 함께 넣을 수 있다.

밝기 조절

어떻게 밝기를 조절 할 수 있을까?

디스플레이의 듀티사이클을 조절함으로써 밝기를 조절할 수 있다.
왼쪽 그림에서 각 디스플레이는 전체 시간의 1/4 동안만 켜져 있고, 오른쪽은 1/8만 켜져있다.
결과적으로 오른쪽의 디스플레이는 왼쪽의 디스플레이보다 절반 정도의 밝기로 보인다.
‘밝기’는 디스플레이가 켜져있는 평균 시간과 관련이 있다.
하지만 듀티 사이클과 사람이 인지하는 밝기 사이의 관계는 선형이 아닐 것이다.

그레이의 2ⁿ가지 그림자

센서를 읽어서 모터,바퀴,놉 같은 회전축의 위치를 알아내야 하는 경우가 종종 있다.
이럴 땐 회전축에 스위치를 넣거나 광센서가 읽을 수 있는 검은색과 흰색 점을 사용해
위치를 알아낼 수 있다.
어떤 접근 방법을 택하든 축의 위치를 2진수로 인코딩해야 한다.

위 그림에서 흰 부분은 0 검은 부분은 1이다.
000,001,010,011,100,101,110,111

여기서 문제는 기계적인 내성에 있다.
제대로 그려진 인코더를 사용한다고 해도 여전히 회로가 각 비트를 읽으면서
전파 지연으로 인한 문제가 생긴다.

위 그림처럼 인코더가 완벽하게 그려지지 않은 경우도 있다.
01234567이 읽히리라 예상했지만 실제로는 201023645767이 읽힌다.

벨 전화 연구소의 미국 물리학자 프랭크 그레이는 이 문제를 살펴보다
각도가 달라질 때 비트가 하나씩만 달라지는 다른 인코딩 방법을 발명했다.

우리가 살펴본 3비트 인코더에서 그레이의 이름을 따서 그레이 코드로 부르며
그레이 코드로 각도를 표현하면 000,001,011,010,110,111,101,110이다.

profile
각성구

0개의 댓글