BASIC4MCU | 통신 | I2C-IIC,TWI | AT24C256 시리얼 EEPROM - 7. 1바이트 randum read, write
페이지 정보
작성자 키트 작성일2017-09-01 10:50 조회2,100회 댓글0건본문
#include
#include
#include
//
#define WP_hi PORTD.2=1
#define WP_lo PORTD.2=0
//
#define SDA_hi DDRD.1=0
#define SDA_lo DDRD.1=1
//
#define SCL_hi DDRD.0=0
#define SCL_lo DDRD.0=1
//
#define ACK_data 0
#define NACK_data 1
//
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 eeprom_clock(){ delay_us(1); SCL_hi; delay_us(1); SCL_lo; }
//
void eeprom_start(){
delay_us(1); SDA_hi; SCL_hi; delay_us(1); SDA_lo; delay_us(1); SCL_lo;
}
//
void eeprom_stop(){
SDA_lo; delay_us(1); SCL_hi; delay_us(1); SDA_hi; delay_us(1);
}
//
void eeprom_nack(){
SDA_hi; eeprom_clock();
}
//
void eeprom_ack(){
SDA_lo; eeprom_clock();
}
//
void eeprom_write(char d){
char i;
for(i=0;i<8;i++){
if(d&(0x80>>i))SDA_hi; else SDA_lo;
eeprom_clock();
}
eeprom_nack();
}
//
char eeprom_read(char ack){
char i,d=0;
SDA_hi;
for(i=0;i<8;i++){
delay_us(1); SCL_hi; delay_us(1);
if(PIND.1)d|=0x80>>i;
SCL_lo;
}
//
if(ack==ACK_data)eeprom_ack();
else eeprom_nack();
//
return d;
}//
void Wr_randum(int add,char data){
WP_lo;
eeprom_start();
eeprom_write(0xA0);
eeprom_write(add>>8);
eeprom_write(add&0xFF);
eeprom_write(data);
eeprom_stop();
delay_ms(5);
WP_hi;
}
//
char Rd_randum(int add){
char ch;
WP_lo;
eeprom_start();
eeprom_write(0xA0);
eeprom_write(add>>8);
eeprom_write(add&0xFF);
eeprom_start();
eeprom_write(0xA1);
ch=eeprom_read(NACK_data);
eeprom_stop();
WP_hi;
return ch;
}
//
void main(void){
char d;
PORTD.2=1; DDRD.2=1; //wp
UCSR0B=8; UBRR0L=8; // 115200 @16MHz 송신
d=Rd_randum(0);
sprintf(str,"\r\nrandum read, before %02x\r\n",d); TX0_STR(str);
//
d++;
//
Wr_randum(0,d);
//
d=Rd_randum(0);
sprintf(str,"randum read, after %02x\r\n",d); TX0_STR(str);
while(1){}
}
//임의의 어드레스에서 1바이트를 읽고 쓰는 간단한 예제입니다.
(부팅 시 0번지를 읽은 후 1을 더해서 다시 저장, 부팅마다 1씩 증가)
//
앞부분 강좌의 파형과 소스코드를 비교 해보세요
//
WP PD2 (10K 풀업)
SDA DD1 (1K 풀업)SCL DD0 (1K 풀업)
연결은 위와 같이하고,
통신은 TX0(PE1) 하나만 사용하고 있습니다.
//
코드비젼의 i2c.h 라이브러리에 버그가 있어서 사용하려다가 포기하고 직접 만들었습니다.
2.05.03에만 있는 버그인지 모르겠지만
이 때문에 원인을 찾느라 몇시간 허비 했습니다.^^
//
SDA (DD1 1K 풀업), SCL (DD0 1K 풀업)
PORTD.0, PORTD.1 레지스터에 0이 들어가있는 상태에서(리셋 초기값)
DDRD.0, DDRD.1 레지스터가 출력으로 되면 PORTD.0과 PORTD.1의 0이 출력되고
DDRD.0, DDRD.1 레지스터가 입력으로 되면 외부 1K 풀업저항에 의해서 1이 됩니다.
//
GPIO로 만든 것이니 어느 포트로도 I2C 통신이 가능합니다.
//
풀업저항이 커지면 딜레이를 더줘야합니다.
오늘 만든 것이니 버그가 있는지 체크 해보세요^^
댓글 0
조회수 2,100등록된 댓글이 없습니다.