IT_etc/dk-128 (ATmega128)

[스크랩] 6. 외부 EEPROM

JJun ™ 2009. 8. 25. 15:56

 < 외부 메모리에 저장되어 있는 것을 읽어 LED를 차례로 켜기 >

 

 

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

 

#define TWI_FREQ 400000
#define AT24C16_ADDR 0xA0
#define CPU_CLOCK 16000000                              //CPU clock = 16,000,000Hz
#define TICKS_PER_SEC 1000                              //Ticks per sec = 1,000
#define PRESCALER 64                                       //Prescaler = 64

 

volatile unsigned int start_time;                        //시간 변수

void initLED(void);                                         //LED 초기화
void setTCCR0(void);                                      //TCCR0 설정
void initTCNT0(void);                                      //TCNT0 초기화
void setTIMSK(void);                                      //TIMSK 설정
void sleep(unsigned int end_time);                    //1초 대기
void eeprom_write(unsigned int uiAddress, unsigned char ucData);

unsigned char eeprom_read(unsigned int uiAddress);

 

SIGNAL(SIG_OVERFLOW0)                      //timer0의 오버플로우 함수
{
          start_time++;
          TCNT0=256-(CPU_CLOCK/TICKS_PER_SEC/PRESCALER);
}

 

int main(void)
{
          char state[8]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};
          char ch;
          int i=0;
          DDRC=0x00;
          PORTC=0xFF;
 
          DDRE=0xFF;
          PORTE=0xFF;
 
          initLED();                                         //LED초기화
          setTCCR0();                                      //TCCR0설정
          initTCNT0();                                     //TCNT0초기화
          setTIMSK();                                      //TIMSK설정
          sei();                                               //인터럽트 활성화
 
          TWBR=(CPU_CLOCK/TWI_FREQ-16)/2;
          TWSR=(0<<TWPS1)|(0<<TWPS0);


          for(i=0;i<8;i++) 
          {
                    //start조건을 만들어 준다
                    TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
                    while(!(TWCR&(1<<TWINT)));
  
                    //슬레이브 디바이스 주소와 위치 주소 상위 3비트를 포함 전송
                    TWDR=AT24C16_ADDR | ((i>>7)&0x000E);
                    TWCR=(1<<TWINT)|(1<<TWEN);
                    while(!(TWCR&(1<<TWINT)));
  
                    //AT24C16에 쓸 위치의 하위 8비트 주소를 전송
                    TWDR=i&0x00FF;
                    TWCR=(1<<TWINT)|(1<<TWEN);
                    while(!(TWCR&(1<<TWINT)));
  
                    //슬레이브에 실제 데이터를 전송
                    TWDR=state[i];
                    TWCR=(1<<TWINT)|(1<<TWEN);
                    while(!(TWCR&(1<<TWINT)));
  
                    //STOP조건을 만들어 준다.
                    TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
  
                    sleep(10);
          } 
 
          for(i=0;i<8;i++) 
          {
                    //start조건 작성
                    TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
                    while(!(TWCR&(1<<TWINT)));
  
                    //슬레이브 디바이스 주소와 위치 주소 상위 3비트 포함 전송
                    TWDR=AT24C16_ADDR | ((i>>7)&0x000E);
                    TWCR=(1<<TWINT)|(1<<TWEN);
                    while(!(TWCR&(1<<TWINT)));
  
                    //AT24C16에 읽을 위치의 하위 8비트 주소를 전송
                    TWDR=i&0x00FF;
                    TWCR=(1<<TWINT)|(1<<TWEN);
                    while(!(TWCR&(1<<TWINT)));
  
                    TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
                    while(!(TWCR&(1<<TWINT)));
  
                    //슬레이브 주소와 읽기 조건을 전송
                    TWDR=AT24C16_ADDR|((i>>7)&0x000E)|0x0001;
                    TWCR=(1<<TWINT)|(1<<TWEN);
                    while(!(TWCR&(1<<TWINT)));
  
                    //AT24C16으로부터 데이터를 읽는다
                    TWCR=(1<<TWINT)|(1<<TWEN);
                    while(!(TWCR&(1<<TWINT)));
                    ch = TWDR;
  
                    //stop조건을 작성
                    TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN);

                    sleep(500);

                    PORTF=ch;
          }
          return 1;
}

 

void initLED(void)                                          //LED초기화
{
          DDRF=0xFF;
          PORTF=0xFF;
}

 

void setTCCR0(void)                                        //Prescaler(배수)설정 : 64
{
          TCCR0=(1<<CS02)|(0<<CS01)|(0<<CS00);
}

 

void initTCNT0(void)                                        //timer 시작값 초기화 : 시작값 6
{
          TCNT0=256-(CPU_CLOCK/TICKS_PER_SEC/PRESCALER);
}

 

void setTIMSK(void)                                        //timer/count0 오버플로우 인터럽트 활성화
{
          TIMSK=(1<<OCIE0)|(1<<TOIE0);
}

 

void sleep(unsigned int end_time)                      //딜레이 start_time는 오버플로우 함수에서 증가
{
          start_time=0;
          while(end_time>start_time);                   //1000 > start_time
}

 

출처 : 단 한번의 선택이라도 후회없이 하자!!
글쓴이 : 꼬리치는늑대 원글보기
메모 :