반응형

ISR(TIMER0_OVF_vect){ <== 요거는 타이머0의 오버플로우 인터럽트지요.

타이머는 동작에 기준이 되는 클럭을 MCU 클럭에서 받아오거나 외부 발진을 받을수 있도록 되어 있는데..

메인 클럭을 받을 경우를 예를 들어보죠.

클럭이 16메가라고 하면 주기는 1/f 이므로 1/16M = 62.5nS죠.

그냥 클럭을 카운터에 넣으면 1카운트는 62.5nS가 되는데...

타이머0의 경우 8비트 카운터이므로 0부터 255까지 풀로 돌려도 256 * 62.5nS = 16uS밖에 않됩니다.

이건 너무 고속이라.. 프리스케일러(분주기)를 통해 시간을 늘입니다.

분주비를 1024로 설정하면.. 62.5nS * 1024가 1 카운트가 되겠죠.

그러면 62,5nS * 1024 = 64uS가 1카운트고,,

이것을 8비트로 카운팅을 하면 최대 16.384mS가 만들어집니다.

저같은 경우는 타이머0는 보통 1mS 타이머로 많이 쓰는데..

1mS를 만들려면.. 분주비는 1024로 하고.. 1000uS(1mS) / 64uS = 15.625번이므로

TCNT0 = 250; // 256번 - X = 15.6이니.. 반올림해서 X = 250번.

이렇게 하시고 인터럽트를 인에이블해주시면 되겠고요..

1mS 타이머를 쓰는 이유는 그게 프로그램에서 기준시간을 만들기 좋기 때문인데요.

예를 들어 조건이 만족해서 "부져가 울리면 300mS 동안 울고 꺼져라..."

이런 펑션일때.. 300mS란 시간은..

1. 타이머 인터럽트에 매인터럽트마다 하나씩 증가하는 변수(T0COUNT라고 하면..)를 하나 넣어두고..

2. 조건이 만족햇을때.. X = T0COUNT + 300;로 끝날시간을 기억시켜두고

3. IF(T0COUNT > X) 면 부저를 꺼라..

이런식으로 프로그램할때 편하지요.

질문 내용대로 1분이란 시간이 필요하시면 클럭과 분주비를 잘 조합하시면 될수도 있겠지만..

고속 클럭에서 1분 정도로 큰 값은 구현하기가 어렵기 때문에.. 작은값(1mS)로 하고..

매 인터럽트에서 인터럽트를 몇번 돌았는지 판단을 해서 1분을 구현하는것이 일반적입니다..

ISR(TIMER0_OVF_vect) {
TCNT0 = 250; // 1mS
IF(++T0CNT > 60000) { // 매 1mS마다 돌아오므로, 1분은 60000개.
T0CNT = 0;
변수1분 = TRUE;
}
}

반응형

+ Recent posts