4월15일 ATmega(StopWatch)

2010. 4. 15. 11:072010년/4월


<StopWatch 실습>


1분 내의 시간을 잴 수 있는 스톱와치 프로그램을 구현하시오.
(초/밀리초 = 00:00)

1번 스위치를 누르면 일시정지, 다시 누르면 재개.
2번 스위치를 누르면 리셋됨

밀리초 값은 FND, 초 값은 LED에 표시함.

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

#define CPU_CLOCK   16000000 //CPU clock=16000000Hz
#define TICKS_PER_SEC 1000  //Ticks per sec =1000
#define PRESCALER  128   //클럭의  배수

volatile unsigned int  g_elapsed_time;//시간변수
 
void intiLED(void);      //LED초기화
void setTCCR0(void);     //TCCR0설정
void initTCNT0(void);     //TCNT0초기화
void setTIMSK(void);     //TIMSK 설정
       
void sleep(unsigned int elapsed_time); //1    초  대기
SIGNAL(SIG_OVERFLOW0);     //timer0의 오버플로우  함수

int main(void)
{
 unsigned int inum=0;
 unsigned int znum=1;
 unsigned int a=0;
 volatile  double b=1;
 
 intiLED();
 setTCCR0();
 initTCNT0();
 setTIMSK();
 SREG=0x80;
 
 while(1)
 { 
   a=PINC;
   if(a==0xFE)
   {
    b=b*-1;
    sleep(400); 
   }
   if(a==0xFD)
   {
     PORTF=0xFF;
     PORTE=0x00;
     inum=0;
     znum=1;
   }
   if(b==1)
   {
    PORTE=inum;
    inum=inum+0x01;
    if((inum&0x0A)==0x0A)
    {
     inum=inum+6;
    }
    if(inum>0x99)
    {
     inum=0x00;
     PORTF=~znum;
     znum++;
    }
  
    if(znum==60)
    {
     znum=1;
    }
    sleep(10); 
    
   }
   
 }

 return  0;
}
void intiLED(void)
{
 DDRE=0xFF;
 PORTE=0xFF;
 DDRF=0xFF;
 PORTF=0xFF;

}
void setTCCR0(void)
{
 TCCR0=(TCCR0|(1<<2));
 TCCR0=(TCCR0|(1<<0));
 TCCR0=(TCCR0&(~(1<<1)));
 
}
void initTCNT0(void)
{
 TCNT0 =256-(CPU_CLOCK/TICKS_PER_SEC/PRESCALER);
}     
void setTIMSK(void
{
 TIMSK=(TIMSK)|(1<<0);
}    

void sleep(unsigned int elapsed_time)
{
 g_elapsed_time=0;
 while(g_elapsed_time<elapsed_time);
 
}
SIGNAL(SIG_OVERFLOW0)
{
 initTCNT0();
 
 g_elapsed_time++;
}