스위치 입력을 사용하는 LED 점등 & 채터링

마이크로프로세서

2020. 5. 25. 03:08

[그림] 이전 소스코드

 

1. 스위치 회로 구성

[그림] ATmega128 키트의 스위치 회로

  • 이전에는 LED 출력만 사용했다. 이번엔 스위치입력을 사용해서 누를 때마다 LED의 패턴이 변하게 해보자.
  • 스위치 회로는 위와 같이 구성되어있다. PD0번 포트에만 스위치가 연결되어있고, 나머지PDx는 비어있다.
  • 스위치는 내부 풀업저항(VCC쪽에 연결) 연결되어있으며, 때문에 0일 때 눌린 것, 1일 때 떨어진 것이다.

 

2. 문제 2 : 누르고 있는 동안 계속 변하는 문제

  • 먼저 PIND는 부논리로 누를 때 0, 뗄 때 1이 된다. 여기에 Bitwise Not 연산(~)을 취한다.
  • 그러면 PIND는 누를 때 1, 뗄 때 0인 정논리로 변하게 된다 (우리의 사고방식과 비슷하며 while조건과 동일)
  • 여기에 0x01과 Bitwise AND(&)연산을 취한다. PIND의 0번 핀에만 현재 스위치가 연결되어있고,
  • 나머지 1~7번 핀은 연결되어있지 않아서 Don't Care 상태이다. 0x01과 AND하여 이를 모두 0으로 꺼준다.

 

  • 따라서 while(!(~PIND & 0x01))이 의미하는 것은 스위치가 눌리지 않으면 무한히 대기하라는 것으로
  • 해석 할 수 있다. 그러네 여기에는 문제가 있다. 만약 스위치를 잠깐 눌렀다 떼도, 프로세서는
  • 16MHz의 클록으로 돌기 때문에, 아주 오랫동안 누르고 있는 것 처럼 읽히게 되고, 그러면 계속
  • 외부의 while문이 돌게 되어서 아래 사진처럼 누르고 있을 때 신호가 아주 빠르게 변하게 된다.

 

 

  • 이 문제를 해결하기 위해 코드를 아래처럼 바꾼다. 버튼을 누르면 한번 신호를 바꾸고나서
  • 뗄 때까지 다시 기다려주는 것이다. 이렇게 하면 한번 누를 때 떼지 않으면 한번만 신호가 변하게 된다.

 

3. 문제 3 : 채터링 문제

  • 그러나 다시 문제가 생겼다. 스위치를 빠르게 누르면 가끔씩 한번에 2번씩 패턴이 변하는 문제이다.
  • 이 것은 "채터링"이라는 문제에 의해 발생하는 것인데, 스위치를 열고 닫을 때 미세한 진동이 생겨서
  • 신호가 튀게 되는 것이다. (이를 채터링 혹은 바운스 한다고 한다)
  • 이를 해결하는 방법을 디바운스라고 하는데 HW적으로 구현하는 방법과 SW적으로 구현하는 방법
  • 두가지가 있는데, HW구현은 회로를 직접 만들어야해서 자금이 소모되므로 SW적으로 처리해본다.

 

  • SW적인 디바운스 처리방법은 바운싱자체를 막는 것이 아니라, 바운싱 될때 잠깐 기다리고나서
  • LED 패턴을 변경하는 식으로 구현하면 이러한 문제를 어느정도 막을 수 있다 (완전하게는 못 막음)

 

  • 위와 같이 바운싱 딜레이를 20ms를 줘서, 처음에 스위치가 열리거나 떼지면 20ms기다리고,
  • 바운싱이 어느정도 잦아들면 그 때 신호를 바꿔주는 것이다.
  • 이렇게 해서 어느정도는 채터링이 해결된다. 이제 한번 누를 때 신호가 한번씩 잘 바뀌게 된다.

 

4. Reference

 

마이크로 프로세서 및 실습 Ⅰ

마이크로 프로세서 및 실습

www.kocw.net