본문 바로가기

Embedded

ATmega128간의 TWI 통신기능 구현하자 - 마스터 송신모드(Master Transmitter Mode) (Posted by H2K)


이제 본격적으로 TWI 통신에 대해서 알아보자. 첫 포스트에서 언급하였지만 TWI 통신에는 마스터 송신모드, 마스터 수신모드, 슬레이브 송신모드, 슬레이브 수신모드의 4가지 모드로 동작한다.

이번 포스트에서는 마스터 송신모드에 대해서 알아보자.




TWI - 마스터 송신 (Master Transmitter)


마스터 송신모드에서는 데이터를 슬레이브 device에 전송한다. 아래 그림은 이를 의미한다.


굳이 말하자면 바로 앞선 포스트에서 TWI 동작을 다루었는데 마스터 송신모드 이 외에 3가지 통신모드역시 이 틀에서 크게 벗어나지 못한다. 대동소이하다고 보면 될 것이다.

그럼 세부적인 전송절차에 대해 알아보자.

  1. 먼저 START 신호를 TWCR을 통해 슬레이브에 전송한다.
    TWCR = 0xA4;

    이는 TWI를 enable 시키고 TWINT를 1로 하여 TWINT 플래그를 클리어시킨 후 START 신호를 전송하게 된다.






  2. 상태 레지스터 TWSR을 통해 수신확인 수행하자
    Start 신호가 제대로 전송되었는지 확인하기 위해 상태 레지스터 TWSR을 통해 확인한다. START 신호가 출력되면 TWCR의 TWINT bit가 1로 되며, 상태 레지스터 TWSR이 0x08이 된다. 이를 체크하기 위해서 TWCR과 0x08을 bit AND하여 그 결과가 TRUE이면 TWINT가 1이 된 것을 나타내게 되며, TWSR은 상태값이 상위 5bit를 차지함으로 0xf8과 bit AND 시켜서 그 결과가 0x08이 나타나면 된다. 이를 코드로 나타내면~
    while(1)
        if((TWCR & 0x80) && ((TWSR & 0xF8) == 0x08)) break;


  3. 마스터 송신모드를 만들기 위해 SLA+W를 TWDR에 저장하고 TWCR을 통해 전송한다.
    마스터 송신모드를 만들기 위해 슬레이브 주소와 전송모드 bit를 0으로 하여 TWDR에 저장한다. 다음에 이를 전송하기 위해 TWCR의 TWINT를 1로 하여 TWINT 플래그를 0으로 만들고 TWEN bit를 1로 하여 TWI를 enable 시킨다. TWI가 enable 되면 TWDR 값을 전송하게 된다.
    unsigned char addr = 1;      // 슬레이브 주소를 임의로 1로 지정
    TWCR = 0xA4;
    
    while(1)
        if((TWCR & 0x80) && ((TWSR & 0xF8) == 0x08)) break;
    
    TWDR = addr << 1;
    TWCR = 0x84;                 // transmit


  4. SLA+W가 전송되고 확인신호가 수신되었는지 TWSR을 통해 확인하자 
    SLA+W 신호가 전송되고 ACK가 수신되면 TWINT는 1이 되고, 상태 레지스터 TWSR에 상태값이 저장될 것이다. 마스터 송신모드에서 가능한 상태값은 0x18, 0x20, 0x38중 하나의 값을 갖게 된다.
    0x18 : SLA+W 신호 송신 후 확인신호가 수신되었다는 의미
    0x20 : SLA+W 신호 송신 후 확인신호가 수신되지 않았다는 의미
    0x38 : SLA+W나 데이터 신호 송신 후 문제가 발생되었다는 의미
    따라서 0x18을 확인하면 정상적으로 ACK가 수신되었다는 것을 알 수 있다. 이외의 값은 에러처리를 하면 된다.
    unsigned char addr = 1;
    TWCR = 0xA4;
    
    while(1)
        if((TWCR & 0x80) && ((TWSR & 0xF8) == 0x08)) break;
    
    TWDR = addr << 1;
    TWCR = 0x84;
    
    while(1){
        if((TWCR & 0x80) && ((TWSR & 0xF8) == 0x18)) break;
        if((TWCR & 0x80) && ((TWSR & 0xF8) == 0x38)) return 38;
    }


  5. DATA를 전송하자
    데이터는 TWDR 레지스터에 저장하고, TWCR 레지스터의 TWINT를 1로 하여 TWINT 플래그를 0으로 클리어시키고, TWEN bit를 1로 하여 TWI를 enable 시킴으로 TWDR 레지스터의 데이터를 전송한다.
    unsigned char addr = 1;
    TWCR = 0xA4;
    
    while(1)
        if((TWCR & 0x80) && ((TWSR & 0xF8) == 0x08)) break;
    
    TWDR = addr << 1;
    TWCR = 0x84;
    
    while(1){
        if((TWCR & 0x80) && ((TWSR & 0xF8) == 0x18)) break;
        if((TWCR & 0x80) && ((TWSR & 0xF8) == 0x38)) return 38;
    }
    
    TWDR = data;
    TWCR = 0x84;


  6. Data 전송 후 ACK신호 확인하자
    data가 전송되고 ACK가 수신되면 TWINT는 1이 되고, TWSR에 상태값이 저장된다. 이때 마스터 송신모드에서 가능한 상태값은 0x28, 0x30중 하나의 값을 갖는다.
    0x28 : 데이터 신호 송신 후 확인신호가 수신되었다는 의미
    0x30 : 데이터신호 송신 후 확인신호가 수신되지 않았다는 의미
    따라서 TWSR에서 0x28값을 확인하면 된다.
    unsigned char addr = 1;
    TWCR = 0xA4;
    
    while(1)
        if((TWCR & 0x80) && ((TWSR & 0xF8) == 0x08)) break;
    
    TWDR = addr << 1;
    TWCR = 0x84;
    
    while(1){
        if((TWCR & 0x80) && ((TWSR & 0xF8) == 0x18)) break;
        if((TWCR & 0x80) && ((TWSR & 0xF8) == 0x38)) return 38;
    }
    
    TWDR = data;
    TWCR = 0x84;
    
    while(1)
        if((TWCR & 0x80) && ((TWSR & 0xF8) == 0x28)) break;


  7. 데이터 전송 완료 후 STOP 신호를 보내거나 다시 데이터를 보내기 위해 Repeated START 신호를 전송하자
    unsigned char addr = 1;
    TWCR = 0xA4;
    
    while(1)
        if((TWCR & 0x80) && ((TWSR & 0xF8) == 0x08)) break;
    
    TWDR = addr << 1;
    TWCR = 0x84;
    
    while(1){
        if((TWCR & 0x80) && ((TWSR & 0xF8) == 0x18)) break;
        if((TWCR & 0x80) && ((TWSR & 0xF8) == 0x38)) return 38;
    }
    
    TWDR = data;
    TWCR = 0x84;
    
    while(1){
        if((TWCR & 0x80) && ((TWSR & 0xF8) == 0x28)) break;
        if((TWCR & 0x80) && ((TWSR & 0xF8) == 0x30)) return 30;
    }
    
    TWCR = 0x94;
    


이로써 마스터 송신 모드에 대해서 알아보았다. 다음 포스트에서는 마스터 수신 모드에 대해서 알아보자 >_<