IT_etc/dk-128 (ATmega128)

[dk-128] 내부 EEPROM 사용하기 (타이머 카운터 사용)

JJun ™ 2009. 7. 6. 19:13

==================================================================================================

 

[요구사항]
1. LED와 KEY를 사용한다.
2. 각 LED는 이웃한 각 KEY버튼과 짝이 된다.
3. 각 KEY를 누르면 LED가 토글된다.
4. 현재의 상태를 매번 EEPROM에 기억 시킨다.
5. DK-128의 전원을 껐다가 켰을 때, 이전의 LED 상태를 그대로 표시해야 한다.

 

==================================================================================================

 

[보드 세팅]

 

 

==================================================================================================

 

[소스 코드]

 

#include<avr/io.h>
#include<avr/signal.h>
#include<avr/interrupt.h>

 

#define CPU_CLOCK         16000000
#define TICKS_PER_SEC   1000
#define PRESCALER         64
#define on_OFF_INPUT     DDRF
#define on_OFF_OUTPUT  PORTF

 

volatile unsigned int g_elapsed_time;

void initLED(void);
void setTCCR0(void);
void initTCNT0(void);
void setTIMSK(void);
void sleep(unsigned int elapsed_time);
void eeprom_write(unsigned int uiAddress, unsigned char ucData); // EEPROM 쓰기
unsigned char eeprom_read(unsigned int uiAddress);  // EEPROM 읽기

 

SIGNAL(SIG_OVERFLOW0)
{
     g_elapsed_time++;
     TCNT0 = 256 - (CPU_CLOCK / TICKS_PER_SEC / PRESCALER);
}

 

int main(void)
{
     char state = 0xFF, ch = 0; // state : 이전 상태, ch : 버튼 입력 값
     unsigned int i = 0; // 저장 주소
   
     initLED();
     setTCCR0();
     initTCNT0();
     setTIMSK();
     sei();
 
     while(1)
     {
          ch = PINC;
          if(ch < 0xFF)
          {
               sleep(500);
               state = ~(state ^ ch);  // 상태 결정 (일정 비트를 바꾸고 싶을 때는 XOR 연산을 사용한다.)
               eeprom_write(i, state); // 내부 EEPROM에 쓴다.
          }
  
          state = eeprom_read(i); // 내부 EEPROM 데이터를 읽어온다.
          ON_OFF_OUTPUT = state;  // LED 출력
     }
     

     return 1;
}


void initLED(void)
{
     ON_OFF_INPUT = 0xFF;
     ON_OFF_OUTPUT = 0xFF;
}

 

void setTCCR0(void)
{
     TCCR0 = (1 << CS02) | (0 << CS01) | (0 << CS00);
}

 

void initTCNT0(void)
{
     TCNT0 = 256 - (CPU_CLOCK / TICKS_PER_SEC / PRESCALER);
}

 

void setTIMSK(void)
{
     TIMSK = (0 << OCIE0) | (1 << TOIE0);
}

 

void sleep(unsigned int elapsed_time)
{
     g_elapsed_time = 0;

     while(elapsed_time > g_elapsed_time);
}

 

void eeprom_write(unsigned int uiAddress, unsigned char ucData) // EEPROM 쓰기
{
     while(EECR & (1 << EEWE)) ; // 이번에 쓰기가 완료되기를 기다린다.
 
     EEAR = uiAddress; // 주소 레지스터 설정
     EEDR = ucData; // 데이터 레지스터 설정
 
     EECR |= (1 << EEMWE); // EEMWE를 1로 설정
     EECR |= (1 << EEWE); // EEWE를 1로 설정
 
     return;
}

 

unsigned char eeprom_read(unsigned int uiAddress) // EEPROM 읽기
{
     while(EECR & (1 << EEWE)) ; // 이번에 쓰기가 완료되기를 기다린다.
 
     EEAR = uiAddress; // 주소 레지스터를 설정
 
     EECR |= (1 << EERE); // EERE를 설정하여 읽기를 시작한다. 

 
     return EEDR; // 데이터 레지스터에서 데이터를 읽는다.
}

==================================================================================================

6장 내부 EEPROM 쓰기v2.pptx.pptx
0.45MB
8장 EEPROM.pdf.pdf
0.17MB
6장 내부 EEPROM 쓰기.pptx.pptx
0.44MB