회원가입 ID/PW 찾기

1) 지식 창고는 본인이 작성한 콘텐츠(팁/노하우/리소스/강좌 등)을 무료 혹은 가상화폐인 납포인트를 통해 공유하는 공간입니다.
2) 본인이 작성한 콘텐츠에 대해서만 지식 창고에 등록할 수 있으며, 저작권에 위배되는 콘텐츠는 사전경고 없이 삭제될 수 있습니다.
3) 콘텐츠 구매 및 첨부파일 다운로드는 회원그룹 '연구원' 이상 가능하오니, 경험치를 쌓아 진급한 후에 이용 부탁드립니다.
4) 무료 콘텐츠의 본문은 구매절차 없이 즉시 이용할 수 있으며, 판매 납포인트가 있는 콘텐츠는 구매 후 이용할 수 있습니다.
5) 콘텐츠 판매에 따른 납포인트 수익은 지정한 비율(50%)에 따라 판매자에게 지급하며, 납포인트 수익을 통해 진급을 빨리할 수 있습니다.
6) 구매 후 평가를 하면 구매 납포인트의 20%를 돌려 드립니다.

콘텐츠 수 2,652

ATMEGA128 UART & EEPROM(I2C)

마이크로프로세서 구매수 0 2010.01.11 14:02:50
판매자 까까 판매 납포인트 무료 평점 1.0점 / 총 1명 참여

/****************************************
* MDA-MULTI SENSOR
* MCU : AVR  (ATMEGA128)
* COMPILER : IAR
* FILE NAME : I2C.C
****************************************/
/*****************************************
        < 배선 하기 >
PD0,PD1 ==> [SERIAL EEPROM] SCL,SDA
PE0,PE1 ==> [RS-232C] RX,TX
******************************************/
/*****************************************
        동작 설명
MDA-Multi MICOM PROGRAMER의 "데이터 통신 윈도우"를 선택하고
화면에서 마우스의 오른쪽 버튼을 클럭 후 "시리얼 초기화"를 선택하고
통신포트 설정 윈도우에서 통신포트를 초기화 한다.

라이트 명령으로 값을 써넣고,
리드 명령으로 값을 확인한다.

예)
W 0010 12 [엔터] -> 0010번지에 12H값, 라이트 성공시 OK! 메세지 디스플레이 된다.
R 0010 [엔터]  -> 0010번지의 값이 디스플레이 된다.
******************************************/
#include "iom128.h"     // I/O가 정의 되어 있는 헤더 파일
// I2C 핀 정의
#define   SCL_DIR    DDRD_Bit0   // SCL_DIR 비트
#define   SDA_DIR    DDRD_Bit1   // SDA_DIR 비트
#define   SCL_OUT    PORTD_Bit0  // SCL_OUT 비트
#define   SDA_OUT    PORTD_Bit1  // SDA_OUT 비트
#define   SCL_IN     PIND_Bit0   // SCL_IN 비트
#define   SDA_IN     PIND_Bit1   // SDA_IN 비트
// UART 비트 정의
#define   UDRE   UCSR0A_Bit5     // UDRE 비트
#define   RXC    UCSR0A_Bit7     // RXC 비트
#define   MPCM   UCSR0A_Bit0     // MPCM 비트
#define   U2X    UCSR0A_Bit1     // U2X 비트
#define   UCSZ0  UCSR0C_Bit1     // UCSZ0 비트
// 24LC32 상수
#define   WR24   0xa4            // 쓰기 명령(1 0 1 A2 1 A0 0)
#define   RD24   0xa5            // 읽기 명령(1 0 1 A2 1 A0 1)
// ASCII 코드 및 메시지
__flash unsigned char ASCII[]="0123456789ABCDEF"; // 16진 ASCII 코드
__flash unsigned char ERR_MSG[]="ERROR ? ";
__flash unsigned char OK_MSG[]="OK ! ";
__flash unsigned char NO_HEX[]="Not Hexa. ? ";
__flash unsigned char NO_CO[]="Not Command ? ";

// 데이터 저장 버퍼
unsigned char BUFFER[15]; // 키 입력 버퍼
unsigned int ADDR;        // EEPROM 어드레스 상위,하위
unsigned char EDATA;      // EEPROM 데이터
unsigned char I2CDATA;    // I2C 전송
unsigned char I2CADR;     //  I2C 어드레스, 방향
unsigned char I2CSTAT;    //  I2C 스테터스
unsigned char C_FLAG;     //  캐리 플래그

void Error(char val)
{
    PORTC = val;
    while(1);
}

// UART 초기 설정
void SERIAL(void)
{
   U2X = 0;
   MPCM = 0;
   UBRR0H = 0;      // 7.3728[MHz]일 경우 9600[bps]
   UBRR0L = 47;
   UCSR0B = 0x18;     // 송신,수신 인에이블
   UCSR0C = 0x06;
}
// 송신
void PUT(unsigned char TX_D)
{
      while(!UDRE);  // 송신 ?
      UDR0 = TX_D;    // 송신
}
// 수신
unsigned char GET(void)
{
      while(!RXC);  // 수신 ?
      return(UDR0);  // 수신
}
// 캐리지 리턴, 라인 피드
void CR_LF(void)
{
      PUT(0x0d);   // 캐리지 리턴 송신
      PUT(0x0a);   // 라인 피드 송신
}
// 에러 송신
void ERROR(void)
{
  unsigned char i;
   CR_LF();   // 캐리지 리턴,라인 피드 송신
   for (i =0; i<8; i++){
      PUT(ERR_MSG[i]);
   }
}
// 에러 송신
void OK(void)
{
  unsigned char i;
   CR_LF();   // 캐리지 리턴,라인 피드 송신
   for (i =0; i<5; i++){
      PUT(OK_MSG[i]);
   }
}
// 16진 에러 송신
void NOT_HEX(void)
{
  unsigned char i;
   CR_LF();   // 캐리지 리턴,라인 피드 송신
   for (i =0; i<12; i++){
      PUT(NO_HEX[i]);
   }
   CR_LF();   // 캐리지 리턴,라인 피드 송신
}
// 코맨드 에러 송신
void NOT_COMMAND(void)
{
  unsigned char i;
   CR_LF();   // 캐리지 리턴,라인 피드 송신
   for (i =0; i<14; i++){
      PUT(NO_CO[i]);
   }
   CR_LF();   // 캐리지 리턴,라인 피드 송신
}
/*  I2C 함수들  */
// 5[ms] 지연 함수

void DELAY(unsigned int i)
{
   while(i--);
}

// SCK 주기 함수
void HALF(unsigned char i)
{
   while(i--);
}
// I2C 초기 설정
void S_INIT(void)
{
   I2CSTAT = 0;  // 스테터스 클리어
   SCL_OUT = 0;  // SCL, SDA 핀 하이 임피던스
   SDA_OUT = 0;
   SCL_DIR = 0;
   SDA_DIR = 0;
}
// 1 바이트 전송
void I2C_WR(void)
{
   unsigned char i;
   C_FLAG = 0x01;
   // 1바이트 전송
   for(i=0; i<8; i++){
       SCL_DIR = 1;         // SCL = "L"

       if (I2CDATA & 0x80){ SDA_DIR = 0;}  // SDA 개방
       else  SDA_DIR = 1;   // SDA = L
       HALF(2);             // 1/2 주기
       SCL_DIR = 0;         // SCL 개방

       HALF(2);             // 1/2 주기
       I2CDATA <<= 1;
       I2CDATA |= C_FLAG;
       C_FLAG = 0;
    }
   // 슬레이브 ACK 신호 응답 대기
     SCL_DIR = 1;     // SCL = "L"
     SDA_DIR = 0;     // SDA 개방
     HALF(2);         // 1/2 주기
     SCL_DIR = 0;     // SCL 개방
     while(!SCL_IN);  // SCL이 "H"일때 까지 대기
     C_FLAG = 0;
     if (SDA_IN) { C_FLAG = 1;}
     HALF(2);        // SDA=H 면 1/2 주기 지연
}
// 스타트 조건, 슬레이브 어드레스 전송
void I2C_ST(void)
{
   I2CDATA = I2CADR;  // 어드레스 복사
   SDA_DIR = 1;       // SDA = "L"
   HALF(1);           // 1/4 주기
   I2C_WR();          // 스타트 조건과 슬레이브 어드레스 송신
}
// I2C Repeat 스타트
void REPEAT(void)
{
   SCL_DIR = 1;     // SCL = "L"
   SDA_DIR = 0;     // SDA 개방
   HALF(2);         // 1/2 주기
   SCL_DIR = 0;     // SCL 개방
   HALF(1);         // 1/4 주기
   I2C_ST();        // 스타트 조건과 슬레이브 어드레스 송신
}
// 데이터 전송
void I2C_DO(void)
{
  unsigned char i;
   if(!(I2CADR & 0x01)) I2C_WR();  // 쓰기인경우
    // STOP 전에 ACK 응답이 없으면 c_flag=1
    // ACK 신호가 더 원할 경우 c_flag=0
   else{                  // 읽기
     I2CSTAT <<= 1;
     I2CSTAT |= C_FLAG;
     C_FLAG = 0;
     I2CDATA = 0;
     // 데이터 입력
     for (i = 0; i < 8 ; i++){
        SCL_DIR = 1;     // SCL = "L"
        HALF(2);         // 1/2 주기
        SCL_DIR = 0;     // SCL 개방
        HALF(2);         // 1/2 주기
        I2CDATA <<= 1;
        if (SDA_IN)(I2CDATA |= 0x01);   // "1"인 경우
       } // for
      // ACK 신호 전송
      SCL_DIR = 1;     // SCL = "L"
      if(I2CSTAT & 0x01){
         SDA_DIR = 0;  // SDA 개방
         I2CSTAT = 0;
        }
      else SDA_DIR = 1;  // SDA = "L"
      HALF(2);           // 1/2 주기
      SCL_DIR = 0;       // SCL 개방
      while(!SCL_IN);    // SCL="H"일때 까지 대기
      HALF(2);           // 1/2 주기
    }  // else
}
// STOP 조건 전송
void I2C_STP(void)
{
   SCL_DIR = 1;     // SCL = "L"
   SDA_DIR = 1;     // SDA = "L"
   HALF(2);         // 1/2 주기
   SCL_DIR = 0;     // SCL 개방
   HALF(2);         // 1/2 주기
   SDA_DIR = 0;     // SDA 개방
   HALF(2);         // 1/2 주기
}
// 바이트 리드
void EEREAD(void)
{
   I2CADR = WR24;          // 디바이스 어드레스, 라이트 셋
   I2C_ST();               // 스타트 조건과 어드레스 송신
   I2CDATA = (ADDR >> 8);  // I2CDATA = ADDRH 
   I2C_DO();               // 어드레스 상위 전송
   I2CDATA = ADDR;         // I2CDATA = ADDRL
   I2C_DO();               // 어드레스 하위 전송
  I2CADR = RD24;          // 디바이스 어드레스, 리드 셋
   REPEAT();               // 리피트 스타트 조건과 어드레스 송신
   C_FLAG = 0x01;          // NO ACK 신호 설정
   I2C_DO();
   I2C_STP();              // STOP 조건 송신
   EDATA = I2CDATA;        // EDATA에 저장
}
// 바이트 라이트
void EEWRITE(void)
{
   unsigned char temp;
   I2CADR = WR24;          // 디바이스 어드레스, 라이트 셋
   I2C_ST();               // 스타트 조건과 어드레스 송신
   I2CDATA = (ADDR>>8);  // I2CDATA = ADDRH
   I2C_DO();               // 어드레스 상위 전송
   I2CDATA = ADDR;         // I2CDATA = ADDRL
   I2C_DO();               // 어드레스 하위 전송
   I2CDATA  = EDATA;        // I2CDATA = EDATA
   I2C_DO();
   I2C_STP();              // STOP 조건 송신
   DELAY(50000);            // 5[ms] 지연
   // 베리파이
   temp = EDATA;           // 저장
   DELAY(50000);            // 5[ms] 지연
   EEREAD();               // 읽기
    if (temp != EDATA) ERROR();  // 같지 않으면 에러
    else OK();                   // 같으면 OK
}
// 16진 검사
unsigned char CHECK_HEX(unsigned hexa)
{
  if ((hexa < '0') | ((hexa > '9') & (hexa < 'A')) | (hexa > 'F')) return(0xff);
  else if (hexa < 0x40) return(hexa & 0x0f);
  else return((hexa & 0x0f)+0x09);
}
// EEROM 읽기
void E_READ(void)
{
  unsigned char temp2,i;
  unsigned long addr_temp;
  // 어드레스를 16진으로 변환
  addr_temp = 0;
  for (i = 2; i < 6; i++){
    temp2 = CHECK_HEX(BUFFER[i]);
    if(temp2 == 0xff) {
       NOT_HEX();
       return;
     }
    else {
      addr_temp |= temp2;
      addr_temp <<= 4;
    }
   }
   // 어드레스 저장
   ADDR = addr_temp >> 4;
   // EEROM 읽기
   EEREAD();
   CR_LF();
   PUT(ASCII[(EDATA >> 4) & 0x0f]);   // 데이터 상위
   PUT(ASCII[EDATA & 0x0f]);          // 데이터 하위
   CR_LF();
}
// EEROM 쓰기
void E_WRITE(void)
{
  unsigned char temp2,i;
  unsigned long addr_temp;
  // 어드레스를 16진으로 변환
  addr_temp = 0;
  for (i = 2; i < 6; i++){
    temp2 = CHECK_HEX(BUFFER[i]);
    if(temp2 == 0xff) {
       NOT_HEX();
       return;
     }
    else {
      addr_temp |= temp2;
      addr_temp <<= 4;
    }
   }
   // 어드레스 저장
   ADDR = addr_temp >> 4;
  // 데이터를 16진으로 변환
  addr_temp = 0;
 for (i = 7; i < 9; i++){
    temp2 = CHECK_HEX(BUFFER[i]);
    if(temp2 == 0xff) {
       NOT_HEX();
       return;
     }
    else {
      addr_temp |= temp2;
      addr_temp <<= 4;
    }
   }
   // 어드레스 저장
   EDATA = addr_temp >> 4;
   // EEROM 쓰기
   EEWRITE();
   CR_LF();
}
// 메인
void main(void)
{
   unsigned char temp,i;

   DDRC = 0xff;
   PORTC = 0xff;
  
   SERIAL();      // UART 초기 설정
   S_INIT();      // SPI 초기 설정
   // 캐리지 리턴 키가 입력될때 까지 루프
   do{
       i = 0;
     do{
         temp = GET();   // 수신
         PUT(temp);     // 송신
         BUFFER[i] = temp;
         i++;
         if (i == 16) i=0; // 버퍼 끝인 경우 초기 값 저장
       }while(!(temp == 0x0d));
      // 코맨드 해석
      temp = BUFFER[0];
      if (temp == 'R') E_READ();       // 'R'인 경우 EEROM 읽기
      else if (temp == 'W') E_WRITE(); // 'W'인 경우 EEROM 쓰기
      else NOT_COMMAND();              // 에러 송신
     }while(1);
}

 


profile
까까 2010.01.20 19:33
일반 IO 포트로 짠 I2C 통신 프로그램입니다. 하이퍼터미널 창에서 키값을 입력 받아서 EEPROM에 쓰거나 읽는 프로그램입니다.
profile
좋지 2010.02.08 20:29
감사합니다....
profile
노는거야 2010.03.18 17:15
좋은자료 감사합니다.
profile
향수 2010.04.28 10:03

감사합니다.

profile
blurlink 2010.04.28 17:43
감사합니다.
profile
지연1111 2010.05.17 13:00

감사합니다.

profile
미틴개발자 2010.06.18 10:31

전 왜 오류가 날까요.ㅠㅠ;
#define   SCL_DIR    DDRD_Bit0    <- 이부분 따로 정의를 해두신건가용.;?

profile
유학선 2010.10.07 19:59

잘보았습니다.

profile
연골막파열 2013.10.25 09:47
감사합니다
profile
시나브로69 2016.07.16 17:45

좋은 자료 감사합니다.

profile
페스코 2023.01.12 17:28
감사합니다.
search
List of Articles
번호 분류 제목 평점 포인트 판매자 등록일 구매수 조회 수
공지 공공의 목적으로 공유하고자 하는 소프트웨어는 '소프트웨어 자료실'에 업로드를 요청드립니다.
공지 구매후 평점 댓글을 남겨주시면 구매포인트의 20%를 돌려드립니다.
2652 Analog & Mixed-Signal 설계 RF 레벨 버짓 Syscalc4 5P 썸남썸남 2022-12-23 1 161
2651 전기전자 아무거나 간단한 RF 필터 설계 프로그램 5P 썸남썸남 2022-12-23 1 118
2650 강좌 & 팁 OP-amp의 특징과 설계시 주의사항 [3] 5P dmz1723 2019-06-24 15 362
2649 강좌 & 팁 PCB 비용 절감을위한 기본 지침 [4] 무료 아크마 2018-06-17 0 715
2648 강좌 & 팁 인쇄 회로 기판 (PCB)에 사용되는 개념과 용어 [6] 무료 아크마 2018-06-17 0 1192
2647 Analog & Mixed-Signal 설계 아날로그 설계기초 이론 자료 입니다. [13] 무료 또지 2018-03-05 0 1016
2646 전력전자 DC-DC Switching Converter IC Design 이론 자료 입니다. [8] 무료 또지 2018-03-03 0 440
2645 전기전자 아무거나 마이컴 초짜의 넋두리~ [12] 무료 소스리 2009-08-20 0 1403
2644 Digital 회로 설계 데이터 전송 인터페이스 LVDS Application and Data Handbook [2] 무료 아크마 2018-02-18 0 195
2643 자작품 & 회로도 모음 전자병법(바테리) 무료 아크마 2018-01-14 0 288
2642 강좌 & 팁 알티움을 유지보수하면 좋은 이유 (1) / Altium 17 Draftsman 무료 아크마 2018-01-06 0 271
2641 ECAD 아무거나 회로부품에 Simulation Model 연결하기 무료 아크마 2018-01-06 0 189
2640 ECAD 아무거나 Altium Designer V9 datasheet 무료 아크마 2018-01-06 0 132
2639 ECAD 아무거나 Altium을 활용한 PCB CAD 툴의 운용 방법 무료 아크마 2018-01-06 0 163
2638 ECAD 아무거나 Altium Xspice 한글 매뉴얼 무료 아크마 2018-01-06 0 226
2637 ECAD 아무거나 XSpice Simulation Model 생성관련 자료 무료 아크마 2018-01-06 0 86
2636 자작품 & 회로도 모음 모드 전환형 자동충전기 무료 아크마 2018-01-05 0 168
2635 자작품 & 회로도 모음 자동차 알터네이터 고장감지회로 [1] 무료 아크마 2018-01-05 0 269
2634 강좌 & 팁 VHDL 기초이론 [2] 5P 태양인이제마 2017-12-26 14 287
2633 Analog & Mixed-Signal 설계 바이패스 캐패시터의 선정방법과 사용법 [3] 무료 아크마 2017-10-05 0 540
  • 오랜 약속보다 당장의 거절이 낫다.
    - 덴마크 격언
  • * 납포인트 정보 *
  • 글 작성 : 3
  • 댓글 작성 : 1
저작권법에 위배되는 콘텐츠는 등록 불가하며, 저작물에 대한 권리는 저작자에게 있습니다.
Copyright 2006-2021 © hardwareis.com, All rights reserved.