임베디드

AVR실습 외부 EEPROM쓰기

꿀꿀이냐옹이 2009. 7. 8. 16:33
반응형
[조건]
이전에 내부 EEPROM을 사용한 과제내용으로
TWI (l2C)직렬 통신을 이용한 외부 EEPROM을
사용하여 구동한 소스

<코드>

#include<avr/io.h>

#include<avr/signal.h>

#include<avr/interrupt.h>

#include<avr/eeprom.h>

 

#define CPU_CLOCK     16000000      //클럭

#define TICKS_PER_SEC 1000            //

#define PRESCALER     64               //프리스케일러

#define AT24C16_ADDR  0xA0          //외부EEPROM 디바이스주소

 

volatile unsigned int g_elapsed_time;

volatile unsigned int j=0;

 

void initLED(void);    

void setTCCR0(void);    

void initTCNT0(void);   

void setTIMSK(void);

void sleep(unsigned int sec);

void toggleLED(char a,char b);

void eeprom_write(unsigned int uiAddress, unsigned char ucData);    

unsigned char eeprom_read(unsigned int uiAddress);

SIGNAL(SIG_OVERFLOW0);             // timer0의 오버플로우함수,매크로

 

volatile unsigned int tic_time;    // 시간 변수

volatile unsigned int time=0;

 

 

int main(void)

{

           DDRC = 0x00;                   // key

           PORTC = 0xFF;

 

           unsigned char ch=0;

          

           initLED();        // LED초기화

           setTCCR0();     // TCCR0 설정

           initTCNT0();    // TCNT0 초기화

           setTIMSK();    // TIMSK 설정

           sei();            // 인터럽트 활성화

 

           TWBR = 12;

    TWSR = (0<<TWPS1)|(0<<TWPS0);

 

 

           for(;;)

           {   

                     ch = ~PINC;

                     PORTF = eeprom_read(j);

 

                     if(ch!=0)

                     {

                                toggleLED(ch,PORTF);

                                eeprom_write(j,PORTF); 

                                sleep(300);

                     } 

           }

 

 return 1;  

}

 

SIGNAL(SIG_OVERFLOW0) //시그날

{

           g_elapsed_time++;

 

           TCNT0 = 256 - (CPU_CLOCK / TICKS_PER_SEC / PRESCALER);

}

void sleep(unsigned int elapsed_time) //딜레이

{

           g_elapsed_time=0;

           while(elapsed_time>g_elapsed_time);

}

void toggleLED(char a,char b)  //토글

{

           PORTF = (a^b);

}

void initLED(void)  // LED 초기화

{

           DDRF=0xFF;

           PORTF=0xFF;

}

 

 

void setTCCR0(void)   //프리스케일러 값

{

           TCCR0=(1<<CS02) | (0<<CS01) | (0<<CS00);

}

void initTCNT0(void)  //타이머 초기화

{

           TCNT0 = 256 - (CPU_CLOCK / TICKS_PER_SEC / 64);

 

}

void setTIMSK(void)  // 인트럽트

{

           TIMSK = (0 << OCIE0) | (1<<TOIE0);

}

 

void eeprom_write(unsigned int uiAddress, unsigned char ucData)

{

 //시작 조건을 만들어준다.

          TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);

          while(!(TWCR&(1<<TWINT)));


//
슬레이브 디바이스 주소와 위치주소 상위 3비트를 포함하여전송

          TWDR = AT24C16_ADDR|((uiAddress>>7)&0x000E);

          TWCR = (1<<TWINT)|(1<<TWEN);

          while(!(TWCR&(1<<TWINT)));


//AT24C16
에 쓸 하위 8비트 주소를 전송한다.

          TWDR = uiAddress&0x00FF;

          TWCR = (1<<TWINT)|(1<<TWEN);

          while(!(TWCR&(1<<TWINT)));


//
슬레이브에 실제 데이터를 전송한다.

          TWDR = ucData;

          TWCR = (1<<TWINT)|(1<<TWEN);

          while(!(TWCR&(1<<TWINT)));


//
종료 조건을 만들어 준다.

          TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);

          sleep(10);

}

 

unsigned char eeprom_read(unsigned int uiAddress)

{

//시작 조건을 만들어준다.

          TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);

          while(!(TWCR&(1<<TWINT)));

   

//슬레이브 디바이스 주소와 위치주소 상위 3비트를 포함하여전송

          TWDR = AT24C16_ADDR|((uiAddress>>7)&0x000E);

          TWCR = (1<<TWINT)|(1<<TWEN);

          while(!(TWCR&(1<<TWINT)));

   

//AT24C16에 읽을 위치의 하위 8비트 주소를 전송한다.

          TWDR = uiAddress&0x00FF;

          TWCR = (1<<TWINT)|(1<<TWEN);

          while(!(TWCR&(1<<TWINT)));

          

//시작 조건을 만들어준다.

         TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);

         while(!(TWCR&(1<<TWINT)));

          

//슬레이브 주소와 읽기 조건을 전송한다

         TWDR = AT24C16_ADDR|((uiAddress>>7)&0x000E)|0x0001;

         TWCR = (1<<TWINT)|(1<<TWEN);

         while(!(TWCR&(1<<TWINT)));

   

//AT24C16으로 부터 데이터를 읽는다.

        TWCR = (1<<TWINT)|(1<<TWEN);

        while(!(TWCR&(1<<TWINT)));

  

//종료 조건을 만들어 준다.

       TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);

       return TWDR;

}

반응형