BASIC4MCU | 통신 | I2C-IIC,TWI | AT24C256 시리얼 EEPROM - 11. TWI - 1바이트 randum read, write
페이지 정보
작성자 키트 작성일2017-09-01 10:53 조회1,866회 댓글0건본문
![]()
7. 1바이트 randum read, write
GPIO로 엑세스 했던 윗 예제를 TWI로 만든 예제입니다.
웹에서 몇개 소스를 검색해서 짜집기한 것입니다.
포트는 원래 TWI 전용 포트에 연결 했던 것이라서 변동없이 그대로 사용하면 됩니다.
#include
#include
#include
//
#define WP_hi PORTD.2=1
#define WP_lo PORTD.2=0
//
#define TWINT 0x80
#define TWEA 0x40
#define TWSTA 0x20
#define TWSTO 0x10
#define TWWC 0x08
#define TWEN 0x04
#define TWIE 0x01
//
// TW_MT_xxx - master transmitter
// TW_MR_xxx - master receiver
// TW_ST_xxx - slave transmitter
// TW_SR_xxx - slave receiver
//
#define TW_START 0x08
#define TW_REP_START 0x10
#define TW_MT_SLA_ACK 0x18
#define TW_MT_SLA_NACK 0x20
#define TW_MT_DATA_ACK 0x28
#define TW_MT_DATA_NACK 0x30
#define TW_MT_ARB_LOST 0x38
#define TW_MR_ARB_LOST 0x38
#define TW_MR_SLA_ACK 0x40
#define TW_MR_SLA_NACK 0x48
#define TW_MR_DATA_ACK 0x50
#define TW_MR_DATA_NACK 0x58
#define TW_ST_SLA_ACK 0xA8
#define TW_ST_ARB_LOST_SLA_ACK 0xB0
#define TW_ST_DATA_ACK 0xB8
#define TW_ST_DATA_NACK 0xC0
#define TW_ST_LAST_DATA 0xC8
#define TW_SR_SLA_ACK 0x60
#define TW_SR_ARB_LOST_SLA_ACK 0x68
#define TW_SR_GCALL_ACK 0x70
#define TW_SR_ARB_LOST_GCALL_ACK 0x78
#define TW_SR_DATA_ACK 0x80
#define TW_SR_DATA_NACK 0x88
#define TW_SR_GCALL_DATA_ACK 0x90
#define TW_SR_GCALL_DATA_NACK 0x98
#define TW_SR_STOP 0xA0
#define TW_NO_INFO 0xF8
#define TW_BUS_ERROR 0x00
//
char str[50];
//
void TX0_CH(char ch) { while(!(UCSR0A&0x20)); UDR0=ch; } // 송신 1바이트
void TX0_STR(char *str){ while(*str)TX0_CH(*str++); } // 송신 ?悶?/span>
//
void TWI_WRITE(int add,char d){
WP_lo;
TWCR=TWINT|TWSTA|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_START))); //START Complete ?
TWDR=0xA0; TWCR=0x84; while(!((TWCR&TWINT)&&(TWSR&TW_MT_SLA_ACK))); //Slave Address Write Mode Complete?
TWDR=add>>8; TWCR=0x84; while(!((TWCR&TWINT)&&(TWSR&TW_MT_DATA_ACK))); //Address Complete?
TWDR=add&0xFF; TWCR=0x84; while(!((TWCR&TWINT)&&(TWSR&TW_MT_DATA_ACK))); //Address Complete?
TWDR=d; TWCR=0x84; while(!((TWCR&TWINT)&&(TWSR&TW_MT_DATA_ACK))); //Data Write Complete?
TWCR=TWINT|TWSTO|TWEN; //stop
delay_ms(5);
WP_hi;
}
//
char TWI_READ(int add){
char d;
WP_lo;
TWCR=TWINT|TWSTA|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_START))); //START Complete ?
TWDR=0xA0; TWCR=TWINT|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_MT_SLA_ACK))); //Slave Address Write Mode Complete?
TWDR=add>>8; TWCR=TWINT|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_MT_DATA_ACK))); //Address Complete?
TWDR=add&0xFF; TWCR=TWINT|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_MT_DATA_ACK))); //Address Complete?
TWCR=TWINT|TWSTA|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_REP_START))); //START Complete ?
TWDR=0xA1; TWCR=TWINT|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_MR_SLA_ACK))); //Slave Address read Mode Complete?
TWCR=TWINT|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_MR_DATA_NACK))); //Data Read Complete?
d=TWDR;
TWCR=TWINT|TWSTO|TWEN; //stop
WP_hi;
return d;
}
//
void main(void){
char d;
PORTD=4; DDRD=4; //SCL(PD0),SDA(PD1),WP(PD2) 출력 설정
TWBR=72; TWSR=0; //TWPS=0 => 4^TWPS=4^0=1 // 100kHz
// TWI_CLOCK=F_CPU/(16+2*TWBR*4^TWPS)
// 100000=16000000/(16+2*TWBR)
// TWBR=(16000000/100000 - 16)/2=72
//
UCSR0B=8; UBRR0L=8; // 115200 @16MHz 송신
//
d=TWI_READ(0);
sprintf(str,"\r\nrandum read, before %02x\r\n",d); TX0_STR(str);
//
d++;
//
TWI_WRITE(0,d);
//
d=TWI_READ(0);
sprintf(str,"randum read, after %02x\r\n",d); TX0_STR(str);
while(1);
}//--
PORTD=4; DDRD=4; //SCL(PD0),SDA(PD1),WP(PD2) 출력 설정
UART와 마찬가지로 SCL(PD0),SDA(PD1)은 출력으로 설정하지 않아도 TWI 설정을 하면 자동으로 입출력이 결정 됩니다.
선언부가 많아서 조금 복잡해보이겠지만 공부하는데에는 더 좋을겁니다.^^
데이터시트에는 TWI 관련 내용이 좀 많습니다.
한가지씩 공부하다보면 언젠간 다 배우겠죠^^
이참에 TWI를 마스터하려는 분들은 웹에 설명글이 많으니 검색해서 공부하세요
한가지씩 공부 끝날 때마다 카페에 소스 올려주세요..^^
댓글 0
조회수 1,866등록된 댓글이 없습니다.