본문 바로가기

공부생각/AVR C

I2C IO-expander를 이용한 keypad의 구현

Embedded System Project 에서 구현했던 것들...
Embeddad System 에서 하는 프로젝트는 Atmega32, 서보모터, LCD, keypad 등을 이용해서 자동차를 설계하고, 그 자동차를 트렉을 따라갈 수 있게 설계하고, 그 트렉에 대한 알고리즘과 한바퀴 도는데 걸리는 최소시간을 가지고 점수를 매기는 프로젝트였다.

외국에서 하는 처음프로젝트였는데 꽤나 재미있는 프로젝트였다.

막상할때는 정말 어렵다고 생각했었는데, 하고나면 -_- 정말 쉬워보인다 제길...


1. Servo motor _ 서보모터 (앞선 글을 참조하도록...)
2. 4x4 matrix Keypad _ 키패드
3. Tachometer _ 타코미터
4. Delay _ 정확한 딜레이

이번시간은 키패드구현에 대해서 말해보겠다.



1. 개괄적인 설명

키패드는 인풋을 유저부터 받는데에 아주 큰 역할을 한다.
디스플레이도 있다면 키보드가 더할나위없이 강력한 인풋 디바이스가 됨은 당연지사.
이번 프로젝트에서는 I2C-IO expander를 가지고 keypad에서 인풋을 받아 속도나 servo의 회전값을 수정하였다.

어디에 쓰건간에 알고있는 것을 정리할테니 꼭 도움이 되기를 바라며...


아래는 간단한 회로도이다.


 
Keypad의 인풋을 받기 위해서는 슬롯이 모자라기에 I2C-IO expander이라는 것을 사용해 준다. 마치 멀티플러그와 같은 역할.

그리고 I2C-IO expander 와 Atmega32는 TWI (Two Wire Inteface)를 통해서 정보를 주고받는다.

키패드의 결과는 8비트의 2진수를 가지고 어떤 특정한 버튼이 눌렸는지 유저가 직접 프로그래밍으로 확인해야 한다.(어떤 원리로 확인하는 지는 나중에...)

자 그럼 간단하게 정리하면

버튼이 눌림-> 8비트를 의 결과를 Atmega32로 보냄->MCU내에서 그 결과값을 가지고 어느 버튼이 눌렸는지 확인 -> LCD에띄움(이건 부수적인거고)

이런식으로 된다는 얘기다.


2. 어느버튼이 눌렸는지 확인하는 방법

강의자료에 있는 그림자료를 잘라왔다.


이게 방법이다. 저쪽에 여덟개의 비트는 각 와이어의 비트를 의미한다.
각각의 가로와 세로 와이어는 서로 닿지 않는 상황이다(버튼이 눌리지 않았다면)
버튼이 눌리면 와이어가 닿는데, 이때 값이 바뀌게 된다. 위의 왼쪽 그림에서 세로 와이어들은 0으로 마치 회로도에서 ground와 같은 역할을 한다. 그런 상태에서 만약 오른쪽처럼 두 와이어가 닿았다면? 1이었던 가로줄 두번째와이어 조차도 ground에 닿아 0이되어버린다.

이런 원리를 이용한 것이 키패드 키 디텍이다.

버튼이 눌리면 외부인터럽트를 수행한 다음에 저렇게 와이어에 1111 0000 을 대입하고 값의 변화가 있는지 확인한다. 만약 버튼이 눌려있다면 위에서 설명한 바와 같이 특정 가로와이어가 아까는 1을 넣었었는데 0으로 바뀌어서 나타날 것이다.

3. TWI (Two Wire Interface)

자 그럼 TWI (Two Wire Interface) 를 신경쓸 차례다.
아까 말했듯이 I2C-IO expander 하고 Atmega32 는 두 포트로 통신을 하는데,
SCL과 SDA가 그것이다.

간단하게 말해 SCL은 클럭이며 SDA는 데이터를 보내는 통로이다.
그리고 8비트의 데이터를 한핀으로 전송하기 위해서 SCL이 뛰는동안 SDA는 한비트씩 차례대로 값을 보내게 된다. 그것이 TWI의 개괄적인 설명이다.

일단 Atmega에서 TWI 파트를 찾아서 꼭 읽어보도록 하자. 솔직히 구현하는데는 다 읽을 필요는 없지만 어떻게 TWI라는 것을 이용해서 서로 대화하는지 알 필요가 있다. datasheet에 자세한 설명과 함께 예제 코드도 있으니까 꼭 확인하길 바란다.

-start
일단 TWI를 가지고 대화를 시작하겠다는 start명령이 필요하다. 이것은 레지스터를 set(1로바꿈)시켜줌으로써 이루어진다. 특정 레지스터를 set하고 set이 정말 되었는지, 안되었다면 while문을 사용해서 될때까지 기다리고 이런식이다. start명령이 끝나고 TWI관련된 Atmega안에 있는 레지스터가 "이제 통신을 시작하라" 라는 상태를 띄게 되면 TWI를 가지고 통신할 수 있는 것이다.

- write or read
start 명령 이후에 write 나 read를 해준다. read의 경우 8비트의 아웃풋이 나올테고, write의 경우는 TWI를 이용해서 I2C IO expander에 값을 씌워주는 것이므로 void가 될 것이다.

-stop
write or read의 명령이 끝나고 난 뒤에 stop을 해준다. 이 명령은 "이제 통신 끝났음" 을 알려주게 되는 것이다. 

TWI는 잘 쓰이는 것이기 때문에 구글에서 라이브러리를 검색하면 쉽게 구할 수 있을 것이다.

아래는 소스코드이다. 필요하면 보고, 퍼갈때는 리플이라도 남겨주기 바람..




질문이 있으면
KissTheRainSC _AT._ hotmail.com