BASIC4MCU | 통신 | I2C-IIC,TWI | AT24C256 시리얼 EEPROM - 12. TWI - page write(64bytes) & Sequential read(256Bytes)
페이지 정보
작성자 키트 작성일2017-09-01 10:53 조회2,196회 댓글0건본문
8. page write(64bytes) & Sequential read(256Bytes)
GPIO로 엑세스 했던 윗 예제를 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++); } // 송신 문자열
//
void TWI_WRITE(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?
TWDR=d; TWCR=TWINT|TWEN; 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;
}
//
char wr_buf[64]; // 64byte
//
void TWI_Page_WRITE(int add){
unsigned int i;
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?
for(i=0;i<64;i++){ TWDR=wr_buf[i]; TWCR=TWINT|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_MT_DATA_ACK))); }
TWCR=TWINT|TWSTO|TWEN; //stop
delay_ms(5);
WP_hi;
}
//
char rd_buf[16][16]; // 256byte
//
void TWI_Seq_READ(int add,unsigned int cnt){
unsigned int i;
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?
for(i=0;i<(cnt-1);i++){
TWCR=TWINT|TWEA|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_MR_DATA_ACK))); //Data Read Complete?
rd_buf[0][i]=TWDR;
}
TWCR=TWINT|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_MR_DATA_NACK))); //Data Read Complete?
rd_buf[0][i]=TWDR;
TWCR=TWINT|TWSTO|TWEN; //stop
WP_hi;
}
//
void main(void){
unsigned int i,k;
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 송신
//sprintf(str,"\r\npage write\r\n"); TX0_STR(str);
for(i=0;i<64;i++)wr_buf[i]=i; TWI_Page_WRITE(0);
for(i=0;i<4;i++){
for(k=0;k<16;k++){ sprintf(str,"%02x ",wr_buf[i*16+k]); TX0_STR(str); }
sprintf(str,"\r\n"); TX0_STR(str);
}
for(i=0;i<64;i++)wr_buf[i]=(i+64)&0xFF; TWI_Page_WRITE(64);
for(i=0;i<4;i++){
for(k=0;k<16;k++){ sprintf(str,"%02x ",wr_buf[i*16+k]); TX0_STR(str); }
sprintf(str,"\r\n"); TX0_STR(str);
}
for(i=0;i<64;i++)wr_buf[i]=(i+128)&0xFF; TWI_Page_WRITE(128);
for(i=0;i<4;i++){
for(k=0;k<16;k++){ sprintf(str,"%02x ",wr_buf[i*16+k]); TX0_STR(str); }
sprintf(str,"\r\n"); TX0_STR(str);
}
for(i=0;i<64;i++)wr_buf[i]=(i+192)&0xFF; TWI_Page_WRITE(192);
for(i=0;i<4;i++){
for(k=0;k<16;k++){ sprintf(str,"%02x ",wr_buf[i*16+k]); TX0_STR(str); }
sprintf(str,"\r\n"); TX0_STR(str);
}
//
sprintf(str,"\r\nSequential read\r\n"); TX0_STR(str);
TWI_Seq_READ(0,256);
for(i=0;i<16;i++){
for(k=0;k<16;k++){ sprintf(str,"%02x ",rd_buf[i][k]); TX0_STR(str); }
sprintf(str,"\r\n"); TX0_STR(str);
}
while(1);
}
//---
아래 함수의 인수및 코드가 일부 변경되었으니 8번 GPIO 글과 비교해보세요
//
void TWI_Page_WRITE(int add){
unsigned int i;
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?
for(i=0;i<64;i++){ TWDR=wr_buf[i]; TWCR=TWINT|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_MT_DATA_ACK))); }
TWCR=TWINT|TWSTO|TWEN; //stop
delay_ms(5);
WP_hi;
}
//--아래 함수는 루프문의 내용으로 조금 변경 해봤습니다.
//
void TWI_Seq_READ(int add,unsigned int cnt){
unsigned int i;
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?
for(i=0;i
if(i!=(cnt-1)){ 마지막이 아니면;i++){<>TWCR=TWINT|TWEA|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_MR_DATA_ACK))); //Data Read Complete?
}
else{ 마지막이면TWCR=TWINT|TWEN; while(!((TWCR&TWINT)&&(TWSR&TW_MR_DATA_NACK))); //Data Read Complete?
}
rd_buf[0][i]=TWDR;
}
TWCR=TWINT|TWSTO|TWEN; //stop
WP_hi;
}
//이글을 마지막으로 시리얼 eeprom 강좌를 마칩니다.
24C128,24C256,24C512 이 세가지 모델이 모두 비슷하므로 유용하게 사용할 수 있습니다. ^^
댓글 0
조회수 2,196등록된 댓글이 없습니다.