당근보드(ATmega32)를 이용한 시계 만들기 - 타이머 이용.

글 내용

  당근보드 자체에는 DS1307이라는 RTC (Real Time Clock)이 있어서 이를 I2C 통신을 이용해 시간을 얻을 수 있습니다. 하지만 아직 I2C 를 공부하지 않았기 때문에..;; 타이머로 동작을 시켜 볼 것입니다.

어떤분께서 ATmega128과 8MHz 클럭을 이용해 1초를 만드는 방법을 올려놓은것을 보았습니다.
전 ATmega32와 16Mhz를 쓰니깐 그분이 만든 1초는 저에겐 0.5초이니 두배 뻥튀기 하면 1초가되는것을 생각하여 만들게 되었습니다... 그러고보니 제가 타이머를 건드린것은 없군요.ㅡㅡ;;
하지만 ATmega128과 ATmega32, 또는 그외의 AVR칩들은 각각 TCCR0로 설정한 클럭 분주비가 다를수 있다고 합니다. 실제로 128은 TCCR0=0x06; 이면 분주비가 256이지만, 32에서는 0x04로 설정해야 분주비가 256이 됩니다.
이는 반드시 데이터시트를 참조하시기 바랍니다.

시계는 잘 갑니다만 오차가 있을수도 있습니다... 아직 오차 테스트는 해보지 않았습니다...ㅡㅡ;
암튼 소스 나갑니다~

#include <avr/io.h>
#include <avr/interrupt.h>
#include <carroty/delay.h>
#include <carroty/fnd.h>

int count = 0; //인터럽트 횟수를 카운트
int sec = 0, min = 0, hour = 0;

unsigned char number_array[16]= { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, };
unsigned char fnd_sel_array[4]= { 0,0,0,0,};
int n1000, n100, n10, n;

void display_fnd(unsigned char number, unsigned char fnd_select) {
  PORTB= number;
  PORTC= fnd_select;
}

void adc2fnd(unsigned int value1,unsigned int value2) {
 n1000=(value1-(value1/100*100))/10;
 n100=value1-(value1/10*10);
 n10=(value2-(value2/100*100))/10;
 n=value2-(value2/10*10);

 for(int g=0;g<10;g++){
  display_fnd(number_array[n1000], fnd_sel_array[0]); delay_ms(3);
  display_fnd(0x11111111, fnd_sel_array[0]);    delay_us(10);
  display_fnd(number_array[n100], fnd_sel_array[1]);  delay_ms(3);
  display_fnd(0x11111111, fnd_sel_array[1]);    delay_us(10);
  display_fnd(number_array[n10], fnd_sel_array[2]); delay_ms(3);
  display_fnd(0x11111111, fnd_sel_array[2]);    delay_us(10);
  display_fnd(number_array[n], fnd_sel_array[3]);  delay_ms(3);
  display_fnd(0x11111111, fnd_sel_array[3]);    delay_us(10);
 }
}

SIGNAL(SIG_OVERFLOW0)
{
 TCNT0 = 206; //TCNT0 초기화
 count ++;
 if ( count < 625 ) PORTA=0xF0;
 else PORTA=0x30;

 if ( count == 1250 )
 { //드디어 1초가 됨
  count = 0;
  sec++; //1초 증가
  if ( sec == 60 ){ sec = 0; min++;}//60초 되면 0으로, 뭐 여기에 분을 추가하시던 알아서...
  if ( min == 60 ){ min = 0; hour++;}
 }
}

int main()
{
 DDRB= 0xFF;
 DDRC= 0xF0;
 DDRD= 0x00;
 number_array[0]=  NUMBER_0;  //각 배열값에 FND에 표시될 수를 입력.
 number_array[1]=  NUMBER_1;
 number_array[2]=  NUMBER_2;
 number_array[3]=  NUMBER_3;
 number_array[4]=  NUMBER_4;
 number_array[5]=  NUMBER_5;
 number_array[6]=  NUMBER_6;
 number_array[7]=  NUMBER_7;
 number_array[8]=  NUMBER_8;
 number_array[9]=  NUMBER_9;

 fnd_sel_array[0]= FND_SEL_1;
 fnd_sel_array[1]= FND_SEL_2;
 fnd_sel_array[2]= FND_SEL_3;
 fnd_sel_array[3]= FND_SEL_4;

 DDRA=0xFF;
 PORTA=0xF0;
 TIMSK = 0x01; // interrupt enable
 TCCR0 = 0x04; // prescale : 256
 TCNT0 = 206;   // initial value of TCNT0 : 50
 sei();    // global interrupt on.
 while(1){
  adc2fnd(hour,min);
  if((PIND&0x08)==0) min++;  //버튼 누를시 1분 증가.
  if((PIND&0x04)==0) hour++;//버튼 누를시 1시간 증가
  if((PIND&0x10)==0) sec=0; // 버튼 누를시 초가 0으로 셋팅
  if(min==60) min=0;
  if(hour==24) hour=0;
 }
 return 1;
}





그럼 실제로 동작하는 모습을 보시겠습니다~~


  1. user picture
    근데 시간은 잘 맞습니까??ㅋㅋ

티스토리 툴바