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; //데이터 읽기
}
'About 프로그래밍!!! > ATmega128' 카테고리의 다른 글
[ATmega128] PC내에서 통신하기.(단방향) (0) | 2010.07.19 |
---|---|
[ATmega128] ATmega128의 메모리 구조. (0) | 2010.07.19 |
[ATmeaga129] 99~0 (0) | 2010.06.17 |
[ATmega128]비교매치 카운터 (0) | 2010.06.17 |
[ATmega128]0~99까지 순차적으로 숫자를 1씩 증가하면서 FND에 표시 하기 (0) | 2010.06.15 |