AVR 임베디드 학습/AVR 이론 공부

ATmega328 i2c통신 학습하기(feat.mpu6050)(2탄)

9bexel9 2024. 10. 10. 23:19

1탄에 이어 i2c 통신 이론을 데이터시트를 통해 학습해 보고 직접 프로그래밍해 보겠다.

 

우선 1탄에서 설명하려 했던 twi bus이다 레지스터 학습까지 완료했으니 이거부터 설명하고 넘어가도록 하겠다.

  1. START비트를 활성화하여 통신을 시작한다.
  2. START신호가 보내지고 통신이 시작되면 자동적으로 TWINT는 set 된다. 
  3. 통신이 제대로 성공했다면 SLA+W(7bit address + 1bit wirte) 값을 TWDR에 싣는다. 
  4. SLA+W가 보내지면 ACK신호가 수신 측으로부터 보내져 제대로 통신이 되었는지 확인할 수 있다.
  5. 통신이 제대로 성공했다면 보내고 싶은 데이터를 TWDR에 싣는다.
  6. data가 보내지면 ACK신호가 수신 측으로부터 보내져 통신이 되었는지 확인할 수 있다.
  7. STOP비트를 활성화하여 통신을 종료한다.
TWSR 에러 레지스터는 ACK와 같은 역할을 한다고 볼 수 있다.
TWINT 비트를 set 하면 하드웨어적으로 TWINT 비트는 clear 된다.
소프트웨어적으로 TWINT비트를 set 해줘야 신호를 보낼 수 있다.
(소프트웨어 set -> 하드웨어 clear 됨 -> 신호가 전송되면 set 됨) 

 

이렇게 이론으로만 하면 이해가 안 되니 코드로 다시 설명해 보겠다.

i2c_init


일단 통신을 하기 위해서는 초기값이 설정되어있어야하지 않겠나? 이전 시간에 레지스터 관련 설명했으니 init은 넘어가겠다.

 

i2c_write


i2c_write

우선 i2c_write다. 위에 그림과 비교해 가면서 코드 분석을 한 줄씩 해보겠다.

twi_bus에 start에 해당되는 부분이다. 즉 위 22-10 그림을 참고해 보면 1,2번에 해당된다.

start비트를 보냄으로 i2c통신을 시작한다. (이후 TWSR0로 ACK신호 수신받음)

22-10 그림에서 3,4번에 해당된다.

주소값(7bit) + 쓰기(1bit) 값을 SDA로 보내준다.

22-10 그림에서 5,6번에 해당된다.

모듈에 레지스터 주소와 데이터를 SDA를 통해 수신 측에 보낸다.

22- 10 그림에서 7번에 해당된다.

stop비트를 보냄으로 i2c통신을 종료한다. ACK신호가 없는 이유는 통신을 종료하기 때문에 필요 없다?라고 해석하면 될듯하다.

 

i2c_read


다음은 read이다.

read는 write와는 다르게 다음과 같이 프로그래밍해줘야 한다..(이유는 모름)

즉 wirte와 같이 모듈의 주소, 레지스터 주소입력하는 것까지는 write와 동일하고 그 이후 restart(Rs) 재시작을 하여 SLA+R로 데이터를 읽어야 한다.

22-19 그림에서 Rs, SLA+R에 해당된다  restart하고 SLA+R 하는 것을 확인할 수 있다.

22- 19그림에서 data, NACK, P에 해당된다.

모듈로부터 받을 데이터를 SDA를 통해 받고 stop비트를 통해 통신을 종료한다.

다음 그림에서 $08 $18 등등 확인할 수 있을 것이다. 이는 아까 설명한 TWSR0에 TW3~TW7비트에 해당되는 에러 + ACK 확인 값이다. 프로그래밍한 값들과 비교하면 쉽게 알 수 있을 것이고 데이터시트를 참고해 보면 하나하나 의미를 알 수 있을 것이다.