2011년6월9일_AVR ATmega128 memory map(메모리맵), DK-128실습(Stopwatch)
ATmega128 메모리맵 |
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) |