1. 회로
- PORTC : 데이터 처리용
- PORTE(4~7) : 데이터 제어용
- PORTD.7 : LED
2. 프로그램 설계
- UART를 통해 데이터를 받아옵니다.
- 데이터 값을 타이머가 1초씩 지나갈때마다 인터럽트가 발생하게 되며, 발생할때 마다 1씩 감소시킵니다.
- FND 4자리 중 앞 2자리는 분, 뒤 2자리는 초를 나타내며 실제 시간과 같이 0초가 되면 59초로 변경합니다.
[FND 필요 기능]
외부 소통 함수(disp_some) | 초기 화면 |
각종 예외 발생 상황 보여주기 | |
각 센서 값 출력 |
[Timer2 필요 기능]
입력받은 숫자를 시간에 맞게 동작하도록 데이터 처리 |
0초가 끝나면 59초로 이동 |
타이머 종료시 종료 문구 | |
종료에 따른 새로운 동작을 위한 플래그 변경 |
3. 동작 방식
3.1 FND 동작 방식
FND는 세그먼트 방식의 숫자 표시 소자로서 7개의 세그먼트로 숫자를 표기합니다.
3.2.1 FND 동작 방식
FND는 세그먼트 방식의 숫자 표시 소자로서 7개의 세그먼트로 숫자를 표기합니다.
- 하나당 7개의 핀이 필요
- 4자리 FND를 사용하면 총 28개의 핀이 필요하지만 FND를 제어하여 시간을 빠르게 각 자리를 옮기며 데이터를 출력하면 4자리 모두 표현 가능한 것처럼 보일 수 있습니다.
- 숫자를 표시하기 위한 데이터 값은 0~9까지만 사용하므로 아래와 같습니다.
- FND는 타이머 표시를 위한 출력용으로 타이머를 설정하면 해당 타이머가 0까지 동작하는 것을 보여줍니다.
- 패킷으로 사용자의 입력을 받은 후 데이터를 처리하여 타이머가 동작했을 때 0까지 움직이며 동작 중 특정 시나리오의 위험 상황(화재)나 강제 종료하지 않는 한 다른 센서는 읽지 않으며 패킷이 들어오면 무시를 합니다.
3.2 Timer 동작 방식
- 타이머는 MUC 내부 클럭을 입력으로 사용하여 이를 분주해서 클럭소스로 사용합니다.
- 2개의 8비트 타이머인 T0와 T2, 16비트 타이머인 T1과 T3가 있습니다.
- FND및 각 종 센서의 시간을 처리하기 위하여 CTC모드를 지원하는 8비트의 T2를 사용하였습니다.
- CTC 동작의 경우 값을 카운트해가며 OCR값과 일치하게 되면 토글이 되며 다시 0부터 카운트를 반복하는 모드입니다.
- 아트메가는 14.7456MHz로 8분주를 하여 OCR값이 100이면 50us이므로 1초는 20000번을 반복하여 만들 수 있습니다. 이를 통해 매초 마다 시간을 감소 시키는 타이머를 만들었습니다.
- 타이머 인터럽트는 내부 클럭을 사용하여 기존 인터럽트와 개별적으로 동작이 가능합니다.
4. 프로그램 ( timer.c )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
#include "header.h"
#include "timer.h"
#include "lcd.h"
/*
* Uart를 통한 사용자 입력
* 원래는 문자열 -> 숫자 변환
*/
int userTimeInput;
/*
* CTC count값
*/
int timerCnt; // CTC 방식
/* FND 처리 */
/*
* Segment 1개의 숫자 표현을 위한 데이터셋
*/
unsigned char num_data[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xd8, 0x80, 0x90}; // 7-segment의 숫자 0~9까지 표현
/*
* FND 자리 변경
*/
unsigned int Port_fnd[] = {0x1f, 0x2f, 0x4f, 0x8f}; // PORTE.4 5 6 7 전환
void fnd_disp()
{
/*
* PORTE 0123 다른 용도 사용하기 위해 &사용 B -> C test
*/
PORTE = Port_fnd[3]; PORTC = num_data[userTimeInput/1000%10]; _delay_us(1000); PORTC=0xff;
PORTE = Port_fnd[2]; PORTC = num_data[userTimeInput/100%10]; _delay_us(1000); PORTC=0xff;
PORTE = Port_fnd[1]; PORTC = num_data[userTimeInput/10%10]; _delay_us(1000); PORTC=0xff;
PORTE = Port_fnd[0]; PORTC = num_data[userTimeInput/1%10]; _delay_us(1000); PORTC=0xff;
}
ISR(TIMER2_COMP_vect)
{
timerCnt++;
if(timerCnt == 20000) // 1초
{
timerCnt = 0;
userTimeInput--;
if(userTimeInput == 0)
{
// To Change LED ON
PORTD |= 0x80;
PORTE = 0x00;
disp_some("Timer is Done","",3000);
}
if(userTimeInput%100 == 99){
userTimeInput -= 40;
}
}
}
void init_timer_Timer2(void)
{
TCCR2 = 0x00; // 초기화
TCCR2 |= (1 << WGM21) | (1 << COM20); // CTC 모드
OCR2 = 100; // 카운터 비교 값 50us
TCCR2 |= 1 << CS21; // 8분주
TIMSK = 1<<OCIE2; // 출력비교 인터럽트 허가
}
void var_Init(){
timerCnt = 0;
lsCnt = 0;
}
void init_Timer(void)
{
var_Init();
init_timer_Timer2();
}
|
cs |
5. 결과
'C (Atmega128)' 카테고리의 다른 글
5. 불꽃 감지 센서 및 모터 개발 (0) | 2022.02.27 |
---|---|
4. 조도 센서 (KY-018) (0) | 2022.02.27 |
3. Light Sensor (LM35) (0) | 2022.02.27 |
1. LCD (0) | 2022.02.26 |
스마트 홈 프로젝트 - 0 (0) | 2022.02.26 |