BASIC4MCU | 질문게시판 | 답변 : avr 128.h 코딩 질문 입니다.
페이지 정보
작성자 master 작성일2020-06-18 10:28 조회4,586회 댓글1건
https://www.basic4mcu.com/bbs/board.php?bo_table=gac&wr_id=12904
본문
// MCU BASIC: https://www.basic4mcu.com// DateTime : 2020-06-18 오전 10:31:35// by Ok-Hyun Park//수지정,외부인터럽트0 서브루틴,외부인터럽트1 서비스 루틴,타이머/카운터0 오버플로우 서비스 루틴을 수정하여시간,분,초를 표시 및 세팅할 수 있도록 프로그램을 작성하고 시간을 12시간으로 지정 하는 코딩 입니다.//#include <mega128.h>#include <delay.h>//bit flag=1;char sec=0,min=0,h=0,loc=0,cnt=0;//void time_display(void){생략~~}//interrupt[EXT_INT0]void external_int0(void){If(loc==2){ if(++h>12)h=0; }if(loc==0){ if(++sec>59)sec=0; }if(loc==1){ if(++min>59)min=0; }flag=1;}//interrupt[EXT_INT1]void external_int1(void){if(++loc>2)loc=0;}//interrupt[TIM0_OVF]void timer_int0(void){ // 16.384ms x 61=0.999424secif(++cnt==61){ cnt=0;if(++sec>=60){ sec=0;if(++min>=60){ min=0; if(++h>=12)h=0; }}}flag=1;}//void main(void){//DDRD=0x00; // PD0,PD1 입력 설정(SW1,SW2)LCD_init();TCCR0=0x07; TIMSK=0x01; // 일반모드,프리스케일=CK/1024 // TOIE0=1;EICRA=0xAA; // 외부 인터럽트0,1 하강 에지EIMSK=0x03; // 외부 인터럽트0,1 인에이블SREG=0x80;while(1){if(flag){ flag=0;time_display();}}}//원래 시간을 제외하고 분,초는 작성 되어 있는 코딩이고,노란 부분은 제가 시간을 포함 시켰는데 이렇게하면 될까요?loc부분은 원래 loc=(loc+1)%2; 로 되어 있었는데0은 초,1은 분,2는 시간으로 해놓고 loc이 3을 넘어가는 순간 0으로 바꿔서 반복하는 코딩으로 바꿨는데이게 맞는지 틀린지 확인 할 방법이 없어서 여기에 질문 올립니다!
인터럽트 안에서 시간이 많이 소요되는 코드를 실행하면 오차가 누적됩니다.
time_display();를 메인함수로 빼서 오차가 덜 발생하도록 변경 했습니다.
질문소스에서는 TCNT0를 릴로드 하지 않고 있어서 누적오차는 발생하지 않지만
16.384ms x 61=0.999424sec
기본적으로 큰 오차를 가지도록 설계되어 있으므로
보다 더 정확한 시간을 위해서는 프리스케일러를 변경하고 TCNT0 릴로드 해야합니다.
시계처럼 정확한 시간을 발생시키려면 오버플로우 인터럽트가 아닌 CTC 비교매치 인터럽트를 사용해야 합니다.
댓글 1
조회수 4,586hhhhhddddd님의 댓글
hhhhhddddd 작성일감사합니다. 어려웠는데 잘 설명해주셔서 이해 했습니다 !!