본문 바로가기

[ATmega128] EEPROM 실패~몰겠당

반응형

void setTCCR0(void)

{

TCCR0 |= 1<<CS02;

TCCR0 &= ~(1<<CS01);

TCCR0 &= ~(1<<CS00);

}

   

<아트메가의 메모리 구성>

   

1)플레시 128kb

2)내장메모리(sram) 4kb

   

3)EEPROM 4KB - 지속적으로 데이터를 가지고 있기 위해서.(1Byte 단위로 쓰고 지우게 됨)

이번 포스팅의 핵은 EEPROM!!!

   

4kByte =1k x 2에 2승

= 2에 10승 x 2에 2승

= 2에 12승 바이트

= 4096 x 1Byte

   

[레지스터]

주소 레지스터 EEPROM

데이터 레지스터 EEDR

설정 레지스터 EECR( 출력이나 입력과 같은 것을 설정하는 곳)

   

예시>주소 10에다가 20이라는 값을 넣는 경우

   

주소 레지스터 EEPROM = 10;

데이터 레지스터 EEDR = 20;

설정 레지스터 EECR( 출력이나 입력과 같은 것을 설정하는 곳) = 절차에 따라 설정.

   

   

   

   

   

  • EERE (Read Enable)
    • EEAR에 지정된 주소의 1바이트를 읽어 EEDR에 저장
  • EEWE (Write Enable)
    • 쓰기 기능 동작, 시스템에 의한 클리어
  • EEMWE (Master Write Enable)
    • EEWE 동작 전 1 지정해야 함, 시스템에 의한 클리어
  • EERIE (Ready Interrupt Enable)
    • EEWE가 클리어 될때 인터럽트 발생 여부
    • SREG I 비트도 활성화 되어 있어야 함.
    • 인터럽트 사용시 비트 7번 활성화!!

         

         

      EEAR (Address Register)

         

         

         

         

         

      3. EEDR (Data Register)

         

  • 읽거나 쓰기 위한 데이터를 저장하는 레지스터

       

       

    화면 캡처: 2010-06-18, 오전 9:42

       

       

       

       

       

       

       

       

       

       

       

       

    주소 설정

    EEAR = 0x10

       

    쓸 데이터 설정

    EEDR = 20

    EECR = (1<<EEMWE)

       

       

    읽기시작

       

    쓰기 중인가?

    EECR EEWE 확인

       

    읽을 주소 설정

    EEPROM의 어떤주소

    EEAR = 0x10;

       

    읽기 명령

    ECCR EERE 를 on 시키기.

       

    EEDR레지스터에 넣어 주면 읽어주면 됨.

       

       

    #define PORTD (*(volatile unsigned int *)0x32//입출력설정

    #define DDRD (*(volatile unsigned int *)0x31//출력설정

    #define PIND (*(volatile unsigned int *)0x30)

       

    #define DDRC (*(volatile char*)0x34)

    #define PINC (*(volatile char*)0x33)

       

    #include <avr/interrupt.h>  //헤더파일을 끌어오므로 다른 정의는 일단생략.

    #include <avr/signal.h>

       

    #define TTCR0 (*(volatile char*)0x53//register setup

    #define TCNT0 (*(volatile char*)0x52//register setup

    #define TIMSK (*(volatile char*)0x57//register setup

    #define OCR0 (*(volatile char*)0x51)

       

    #define CPU_CLOCK 16000000

    #define TICKS_PER_SEC 1000

    #define PRESCALER 64

       

    volatile unsigned int g_elapsed_time;  //시간변수

       

    void initLED(void);

    void setTCCR0(void); //TCCR0  mode  분주기를 설정

    void initTCNT0(void); //TCCR0  실행횟수를 카운팅하는 함수. overflow  발생하면 다시 6으로 초기화.

    void setTIMSK(void); //TIMSK  인터럽트를 사용하겠다고 초기화 하는 함수

    void toggleLED(char * state); //LED 반전 시키는 함수

    void sleep(unsigned int elapsed_time);  //1초간 대기하는 함수

    void setOCR0(void);

    SIGNAL(SIG_OVERFLOW0);  //overflow  발생하면 시스템에서 알아서 함수를 호출헤더파일에 포함 

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

    unsigned char eeprom_read(unsigned int uiAddress);

       

       

       

       

       

    int main(void)

    {

      char state = 0;

      unsigned char ch = 0;

        

      DDRC = 0x00;

      PORTC = 0xff;

        

      DDRD = 0xff;

      PORTD = 0xff;

        

      initLED();  //LED 초기화 

        

      setTCCR0();  //TCCR0 초기화

        

      initTCNT0();  //TCNT0 초기화

        

      setTIMSK();  //TIMSK 설정

        

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

       

      for(unsigned int i =0; ; i++)

      {

        ch= PINC;

        if(ch==0b11111110)  //1 스위치를 누르면 EEPROM 데이터 기록

        {

          ch = 0;

          for(unsigned int i=0; i<10; i++)

            eeprom_write(i, ch++);

                

          ch = 9;

          for(unsigned int i=0; i <10; i++)

            eeprom_write(10+i, ch--);

                

        }

          

        ch=eeprom_read(i);  //eeprom i 주소에 들어있는 데이터를 읽어옴

        PORTD= ch;      //읽어온 데이터를 FND 출력.

        if(i==19) i=0;

          

        toggleLED(&state);  //LED 반전

        sleep(500);

      }

        return 1;   //종료

          

    }

       

       

       

       

       

       

       

    void initLED(void)

    {

     DDRD = 0xFF; //F PORT I/O setup

     PORTD = 0xFF; //PORTF setup

    }

       

    void setTCCR0(void)

    {

     TCCR0 |=1<<CS02;

     TCCR0 &=~(1<<CS01);

     TCCR0 &=~(1<<CS00);

    }

       

    void initTCNT0(void)

    {

     TCNT0 = 6

    }

       

    void setTIMSK(void)

    {

     TIMSK = 0b00000001;  //Timer Interrupt  사용하겠다는 초기화 값으로 설정

    }

       

       

       

    SIGNAL(SIG_OVERFLOW0)  

    {

     TCNT0 = 6//TCNT0 초기화

     g_elapsed_time++;

    }

       

    void toggleLED(char * state)

    {

     PORTD = ~PORTD;  //호출 되면 LED  반전 시킴  

    }

       

    void sleep(unsigned int elapsed_time)  //1초간 대기하는 함수 elapsed_time 값은 1000

    {

     g_elapsed_time = 0;      //sleep 함수 호출  마다 시간변수를 0으로 초기화 해주고 인자로 들어오는 (1000)까지 sleep 함수 내에 잡아둔다.

     while(g_elapsed_time<elapsed_time);  //시간변수가 1000까지 증가하는 시간은 1

       

    }

      void eeprom_write(unsigned int uiAddress, unsigned char ucData)

      {

        while(EECR&(1<<EEWE));    //쓰기 작업중이면 루프

          

        EEAR= uiAddress;  // 주소값 입력

        EEDR= ucData;  // 데이터 입력ㅅ

        EECR|= (1<<EEMWE);  //EEWE  준비해라

        EECR|= (1<<EEWE);  //쓰기 명령

        return;

          

      }

        

      unsigned char eeprom_read(unsigned int uiAddress)

      {

        while(EECR &(1<<EEWE));  //쓰기 작업 중이면 루프

          

        EEAR= uiAddress;  //읽을 주소값 입력

        EECR|= (1<<EERE);  //읽기 명령

          

        return EEDR;  //데이터 읽기

          

      }

       

반응형
-->