2011년6월9일_AVR ATmega128 memory map(메모리맵), DK-128실습(Stopwatch)

 

 

ATmega128 메모리맵

 

 DSCN3347 DSCN3348 DSCN3349

 

 

 

 

DK-128실습 Stopwatch

 

(도식과 설명을 추가할까?)

 

   1:  /**********************************************************************
   2:  R2
   3:      <StopWatch 실습>
   4:  
   5:  
   6:      1분 내의 시간을 잴 수 있는 스톱와치 프로그램을 구현하시오.
   7:      (초/밀리초 = 00:00)
   8:  
   9:      1번 스위치를 누르면 리셋됨 
  10:  
  11:  
  12:  
  13:      밀리초 값은 FND, 초 값은 LED에 표시함.
  14:  
  15:      
  16:      작성자: 김수만
  17:      작성일자: 2011년 6월 9일
  18:      
  19:  **********************************************************************/
  20:  #include "./../../ATmega128.h"
  21:   
  22:   
  23:  //포트 정의
  24:  #define DDR_LED            DDRF
  25:  #define PORT_LED        PORTF
  26:  #define DDR_FND            DDRE
  27:  #define PORT_FND        PORTE
  28:  #define    DDR_KEY            DDRC
  29:  #define    PIN_KEY            PINC
  30:  #define    PORT_KEY        PORTC
  31:  //타이머관련
  32:  #define    CPU_CLOCK        16000000        // CPU clock = 16Mhz
  33:  #define TICKS_PER_SEC    1000            // Ticks per sec = 1,000
  34:  #define    PRESCALER        64                // Prescaler = 64
  35:                                          // 클럭의 배수(크기,오버헤드)
  36:  volatile unsigned int g_elapsed_time = 0;    // 시간 변수
  37:  volatile unsigned char gKey = 0;
  38:   
  39:  //ISR
  40:  void __vector_15 (void) __attribute__ ((signal, used, externally_visible));     
  41:  void init_TC0(void);
  42:  void init_port(void);
  43:  void sleep(unsigned int elapsed_time);
  44:  unsigned char hex_to_dec(unsigned char);
  45:   
  46:   
  47:  //프로그램 시작
  48:  int main(void)
  49:  {
  50:      unsigned char cSec = 0;
  51:      unsigned char c10mSec = 0;
  52:      unsigned char cFlag = 0;
  53:   
  54:      init_port();
  55:      init_TC0();
  56:      sei();                // 인터럽트 활성화
  57:      
  58:      while(1)
  59:      {
  60:          while(0 == cFlag)
  61:          {
  62:              //시작키
  63:              if(0 != (gKey & 0x02))
  64:              {
  65:                  cSec = 0;
  66:                  c10mSec = 0;
  67:                  cFlag = 1;
  68:                  
  69:                  while(0x00 != gKey);        //체터링제거
  70:                  sleep(100);
  71:              }
  72:          }
  73:   
  74:          PORT_FND = hex_to_dec(c10mSec);        //FND에 10ms단위 표시
  75:          PORT_LED = ~cSec;                    //LED에   1s단위 표시
  76:          
  77:          c10mSec++;                            //10ms증가
  78:          
  79:          if(100 <= c10mSec)        //990ms를 넘어 1000ms가 되면 
  80:          {
  81:              cSec++;                //1초 카운트
  82:              c10mSec = 0;        //10ms단위 변수 초기화
  83:              
  84:              if(60 <= cSec)        //59초를 넘어 60초가 되면
  85:              {
  86:                  cSec = 0;        //1s 단위 변수 초기화
  87:              }
  88:          }
  89:          
  90:          //리셋키
  91:          if(0 != (gKey & 0x01))
  92:          {
  93:              c10mSec = 0;
  94:              cSec = 0;
  95:              cFlag = 0;
  96:              
  97:              PORT_LED = ~cSec;
  98:              PORT_FND = hex_to_dec(c10mSec);        //FND에 10ms단위 표시
  99:              
 100:              while(0x00 != gKey);        //체터링제거
 101:              sleep(100);
 102:          }
 103:          
 104:          //일시정지/계속
 105:          if(0 != (gKey & 0x02))
 106:          {
 107:              sleep(50);
 108:              while(0x00 != gKey);        //체터링제거
 109:              sleep(100);
 110:              
 111:              while(0x00 == gKey);
 112:              
 113:              if(0 != (gKey & 0x01))
 114:              {
 115:                  c10mSec = 0;
 116:                  cSec = 0;
 117:                  cFlag = 0;
 118:                  
 119:                  PORT_LED = ~cSec;
 120:                  PORT_FND = hex_to_dec(c10mSec);        //FND에 10ms단위 표시
 121:              }
 122:   
 123:              sleep(50);
 124:              while(0x00 != gKey);        //체터링제거
 125:              sleep(100);
 126:          }
 127:          
 128:          sleep(10);        // 1/100초 대기 상기 본 프로그램 수행시간에 따라 지연시간이 달라짐.
 129:      }
 130:      
 131:      return 0;
 132:  }
 133:   
 134:  /*******************************************************
 135:      타이머/카운터0 비교매치 인터럽트 서비스 루틴
 136:  *******************************************************/
 137:  void __vector_15(void)
 138:  {
 139:      ++g_elapsed_time;        // 시간변수 1증가    
 140:      gKey = ~PIN_KEY;
 141:  }
 142:   
 143:  //포트초기화
 144:  void init_port(void)
 145:  {
 146:      DDR_LED = 0xFF;        //모두 출력
 147:      PORT_LED = 0xFF;    //포트 초기화
 148:      DDR_KEY = 0x00;        //모두 입력
 149:      PORT_KEY = 0xFF;    //모두 풀업처리
 150:      DDR_FND = 0xFF;        //모두 출력
 151:      PORT_FND = 0x00;    // "00"출력
 152:      
 153:      return ;
 154:  }
 155:   
 156:  void init_TC0(void)
 157:  {
 158:      TCCR0 = (1 << WGM01) | (1 << CS02);        //CTC Mode, prescanler = 1/64
 159:      //TCCR0 = 0x44;
 160:   
 161:      //8bit Timer0 = 16,000,000 / 1000 / 64
 162:      //            = 250
 163:      OCR0 = CPU_CLOCK / TICKS_PER_SEC / PRESCALER;
 164:   
 165:      TIMSK = (1 << OCIE0);        //타이머0 비교 매치 인터럽트 활성
 166:      
 167:      return ;
 168:  }
 169:   
 170:  //1초 대기
 171:  void sleep(unsigned int elapsed_time)
 172:  {
 173:      g_elapsed_time = 0;                            //시간 변수 초기화
 174:      while(elapsed_time > g_elapsed_time);        //참이 될 때까지 대기.
 175:      
 176:      return ;
 177:  }
 178:   
 179:   
 180:  //16진수를 10진수로 바꾸는 함수 (100미만의 값만 취급한다.)
 181:  unsigned char hex_to_dec(unsigned char cNum)
 182:  {
 183:      unsigned char temp;
 184:      
 185:      //실제 16진수가 아닌 10진수를 16진수로 취급하여,
 186:      //10의 자리 잘라내 곱하기 16 + 1의 자리.
 187:      temp = (cNum / 10) * 16 + (cNum % 10);
 188:      
 189:      return temp;
 190:  }
 191:   
 192:      

 

 

 

 

 

 

 

참조 (Reference)

 

 

DSCN3347 DSCN3348 DSCN3349 DSCN3350