목표 : ATmega128A를 활용해 I2C통신으로 LCD를 사용합니다.

- I2C 통신의 전체적인 통신 타이밍도.(Start와 Stop신호 사이에 데이터와 주소 값을 송수신.)
※ 이전에 I2C통신을 정리한 바가 있으므로 I2C통신의 자세한 내용은 설명하지 않겠습니다.
ATmega128A에서 I2C통신
이전 글에서 I2C는 2개의 선을 이용한 통신 방식이라고 설명했습니다.
따라서 이와 같이 ATmega128A에서는 TWI(Two-wire Serial Interface)를 방식을 사용합니다. 이는 이름만 다르지 I2C통신과 같습니다.

- 데이터 시트에는 다음과같이 작성되어 있습니다. "All registers drawn in a thick line are accessible through the AVR data bus." 굵은 선으로 그려진 레지스터는 AVR 데이터 버스를 통해서 접근이 가능합니다. 즉, SW(코딩)을 사용해서 레지스터틔 값을 송수신 할 수 있습니다.
- SCL and SDA Pins : I/O포트 섹션에서 설명한대로 SCL및 SDA핀에 해당하는 포트 비트를 설정하여 활성화 가능. TWI사양을 준수하기 위해 SlewRate 리미터가 포함되어 있습니다. 즉, 입력단계에서는 50ns보다 짧은 채터링 현상을 억제할 수 있는 장치가 포함되어 채터링 현상을 억제 할 수 있습니다.
- Bit Rate Generator Unit : 마스터 모드에서 작동할 때 SCL 주기를 제어하며, TWI비트 전송 속도 레지스터(TWBR)의 설정과 TWI 상태 레지스터(TWSR)의 프리스케일러 비트에 의해 제어됩니다. 슬레이브의 CPU클록 주파수는 SCL주파수보다 16배 높아야합니다 따라서 다음 사진의 식을 사용해서 SCL주파수를 결정합니다.

- Bus Interface Unit : START/STOP 컨트롤러 및 중재 감지 하드웨어가 포함, TWDR에는 전송할 주소 또는 데이터 바이트 또는 수신된 주소 또는 데이터 바이트가 포함되어있습니다. 이외에도 버스 인터페이스 장치에는 전송 또는 수신할 (N)ACK 비트가 포함된 레지스터도 포함되어 있습니다. 이 (N)ACK 레지스터는 애플리케이션 소프트웨어에서 직접 액세스할 수 없습니다. 그러나 수신할 때는 TWI 제어 레지스터(TWCR)를 조작하여 설정하거나 지울 수 있습니다. 송신기 모드에서 수신된 (N)ACK 비트의 값은 TWSR의 값으로 결정
- Address Match Unit :
1) TWAn : 7비트 TWI슬레이브 주소를 결정
2) TWGCE : 1이면 전체 슬레이브 호출.
- Control Unit :
1) TWINT : TWI Interrupt Flag 1로 세팅하면 새로운 동작을 할 수 있는 준비상태, 준비 상태가 완료 되었을 때 0으로 세팅해주면 다음 동작을 시작합니다.(만약 TWINT가 0일 때, SCL Line은 LOW로 기능이 정지됩니다.)
2) TWEA : TWI Enable Acknowledge TWEA가 1이라면 데이터 시트의 조건이 충족되면 TWI버스에서 ACK신호 발생, TWEA가 0이라면 연결이 종료됩니다(이때 TWEA 비트를 다시 1로 작성하여 주소 인식을 재개 할 수 있다.).
3) TWSTA : TWI START Condition I2C통신에서 마스터가 되고자 할 때 TWSTA비트를 1로 세팅합니다. TWI하드웨어는 버스가 사용 가능한지 확인하고 버스가 비어있으면 버스에서 START조건을 생성합니다. 그러나 버스가 비어 있지 않으면 TWI는 STOP 조건이 감지될 때까지 기다린 다음 버스 마스터 상태를 청구하기 위해 새로운 START 조건을 생성합니다.
4) TWSTO: TWI STOP Condition 마스터 모드에서 TWSTO 비트를 1로 쓰면 I2C 직렬 버스에서 STOP 조건이 생성, 버스에서 STOP 조건이 실행되면 TWSTO 비트가 자동으로 지워집니다. 슬레이브 모드에서 TWSTO 비트를 설정하면 오류 조건에서 복구하는 데 사용할 수 있습니다. 이렇게 하면 STOP 조건이 생성되지 않지만 TWI는 잘 정의된 주소 지정되지 않은 슬레이브 모드로 돌아가고 SCL및 SDA 라인을 고임피던스 상태로 해제합니다.
5) TWWC: TWI Write Collision Flag TWWC비트는 TWINT가 LOW일때, TWDR 레지스터를 쓰면 세팅됩니다. 반대로 TWINT가 HIGH일 때 TWDR레지스터를 쓰면 TWWC 충돌 플래그는 초기화됩니다.
6) TWEN: TWI Enable : TWEN 비트는 TWI 작동을 가능하게 하고 TWI 인터페이스를 활성화합니다. TWEN이 1로 작성되면 PD0,PD1을 SCL 및 SDA 신호핀으로 사용합니다. TWEN이 0으로 작성되면 TWI가 꺼지고 진행 중인 작업에 관계없이 모든 TWI 전송이 종료됩니다.
7) TWIE: TWI Interrupt Enable TWIE가 1이고 SREG의 I-bit가 설정되면, TWINT flag=high일 때 TWI인터럽트 요청이 활성화 됩니다.
TWI Bus 동작 프로토콜
- 인터럽트 flag(TWINT)가 set이 되면(=1이 되면) 동작완료, clear(=0이 되면) 시작신호를 의미합니다.
- TWI통신은 인터럽트 기반의 바이트 단위를 전송하며, 바이트 단위로 송수신 될 때마다 TWINT가 High가 된다. 이를 Clear하게되면 동작을 시작한다.
위에서 설명한 내용대로 ATmega(AVR)에서 I2C통신으로 LCD를 사용 할 수있습니다. 다음은 코드내용입니다.



- 코드내용을 간단히 정리를 해보자면 I2C통신을 시작 할 때(Start) TWEN, TWSTA에는 1을 줘서 enable과 start신호를 준다 하지만 TWINT는 특수 레지스터이다. 간단하게 말하자면 처음에 1 (High)로 세팅을 해준다는 의미는 다음 동작을 실행하 준비가 완료되었다는 의미입니다. 이를 while문안에서 확인하는 이유는 다음 동작을 실행시킨다는 의미이며 만약 TWINT가 0이 되면 다음 동작을 실행합니다.
- 또한 마지막 사진의 내용은 데이터 시트에서 C언어를 사용해서 I2C 통신을 위해서 레지스터를 설정하기 쉽도록 정보를 제공합니다. 이를 바탕으로 I2C통신을 사용 할 수 있습니다.
- 아래 내용은 왜 주소한 비트는 쉬프트 연산을 하는지 그 이유이다. 두번째 타이밍도를 보면 0~6번까지는 Slave의 주소를 보내주고 마지막 한 비트는 주소를 입력해주기 위해서 R/W값을 0으로 해줘야합니다. 우리는 지금 현재 레지스터에 값을 쓰기만 하기 때문에 이렇게 주소에 한비트를 밀어주면 R/W에 들어갈 값이 0이기 때문에 다음처럼 쉬프트 연산을 사용해 한비트를 밀어줍니다.


펌웨어실습_git저장소