2008년 09월 24일
TWI Slave Interrupt
인터넷에 TWI를 Slave Interrupt 로 작성한것은 몇가지 있다.
그런데 보면 Slave Receive 만 Interrupt로 작성하고 Slave Transmit는 포함이 되어있지 않다.
그래서 오늘 해보았다.
그냥 폴링방법을 Interrupt 문에 맞추어서 넣어주면 동작 잘한다.
void init_TWI(void)
{
TWAR = SLAVE_ID << 1;
TWCR = (1<<TWEA) | (1<<TWEN) | (1<<TWIE); // SLAVE
sei();
}
char rData[10]; // 수신 버퍼
char tData[10] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'}; // 송신 버퍼
unsigned char rCnt = 0; // 수신 버퍼 카운터
unsigned char tCnt = 0; // 송신 버퍼 카운터
volatile char rFlag = 0; // 수신 완료 플래그
ISR(TWI_vect)
{
volatile unsigned char flag;
flag=TWSR & 0xF8;
switch(flag)
{
case TW_SR_SLA_ACK:
rCnt = 0;
// 데이터를 수신하기 위해서 수신버퍼카운터를 0으로 초기화
TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
break;
case TW_SR_DATA_NACK:
break;
case TW_SR_DATA_ACK:
rData[rCnt++] = TWDR;
// 수신버퍼카운터를 1씩 증가시켜 데이터를 저장
TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
break;
case TW_SR_STOP:
rCnt = 0;
// 수신 완료 플래그 셋 => 메인문에서 처리
rFlag = 1;
TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
break;
case TW_ST_SLA_ACK:
tCnt = 0;
TWDR = '*'; // 첫번째 데이타 전송
TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
break;
case TW_ST_DATA_ACK:
putchar(tData[tCnt]);
TWDR = tData[tCnt++]; // 데이터 전송 반복
TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
break;
case TW_ST_DATA_NACK:
printf("\r\n"); // 전송 완료
TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN) | (1<<TWIE);
break;
}
}
# by | 2008/09/24 13:02 | AVR | 트랙백 | 덧글(1)



