BASIC4MCU | 8051/PIC | DT-516 강좌 | DT516-022.c 13비트 타이머 인터럽트를 사용한 9999 카운터
페이지 정보
작성자 키트 작성일2017-08-21 17:11 조회1,343회 댓글0건첨부파일
본문
//-------------------------------------------------------------
// 82G516 E/V BOARD ( DT-516 )
//-------------------------------------------------------------
// XTAL : 22.1184Hz
//-------------------------------------------------------------
// filename: DT516-022.c
// 13비트 타이머 인터럽트를 사용한 9999 카운터
//-------------------------------------------------------------
#include <REG_MPC82G516.H>
//
#define U_C unsigned char
#define U_I unsigned int
#define U_L unsigned long
//
#define I_C idata char
#define I_I idata int
#define I_L idata long
#define I_F idata float
#define IU_C idata unsigned char
#define IU_I idata unsigned int
#define IU_L idata unsigned long
//
#define X_C xdata char
#define X_I xdata int
#define X_L xdata long
#define X_F xdata float
#define XU_C xdata unsigned char
#define XU_I xdata unsigned int
#define XU_L xdata unsigned long
//
#define C_C code char
#define C_I code int
#define C_L code long
#define C_F code float
#define CU_C code unsigned char
#define CU_I code unsigned int
#define CU_L code unsigned long
//
#define FND_COM1 P40
#define FND_COM2 P41
#define FND_COM3 P42
#define FND_COM4 P43
#define FND_SEG P0
//
CU_C Seg_Data[]={
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E //0123456789AbcdEF
};
//
bit delay_flg=0;
U_C FND_CNT=0;
U_I delay_buf=0, counter=0;
//
void Timer_0_Interrupt(void) interrupt 1{ // 225Hz주기
P4=0xFF; // FND OFF
switch(FND_CNT){
case 0: P0=Seg_Data[counter/1000]; FND_COM1=0; break;
case 1: P0=Seg_Data[(counter/100)%10]; FND_COM2=0; break;
case 2: P0=Seg_Data[(counter/ 10)%10]; FND_COM3=0; break;
case 3: P0=Seg_Data[counter%10]; FND_COM4=0; break;
}
if(++FND_CNT>3)FND_CNT=0;
//
if(delay_buf){ if(--delay_buf==0)delay_flg=1; }
}
//
void delay_ms(U_I d){
delay_buf=(U_I)((float)d*0.225);
if(delay_buf==0)delay_buf=1;
TH0=0; delay_flg=0; while(!delay_flg);
}
//
void main(){
ET0=1; TR0=1; EA=1;
while(1){
for(counter=0;counter<10000;counter++)delay_ms(1000);
}
}
//-------------------------------------------------------------
설명이 없어서 해석이 어려운 분이 많으신가 봅니다.간단한 설명을 적어 놓겠습니다.
//----------------------
void main(){
ET0=1; TR0=1; EA=1;
while(1){
for(counter=0;counter<10000;counter++)delay_ms(1000);
}
}
counter 변수만 생각 해 보세요0부터 1초씩 9999까지 증가 합니다.
이정도는 이해가 가실겁니다.
//----------------------
타이머 인터럽트 주기는 225Hz이고
4개의 FND를 차례로 구동 하므로 225/4=56.25회/초
56회 정도의 반복 횟수면 깜박거림을 전혀 느낄 수 없습니다.
//----------------------
4개의 FND를 어떻게 한번씩 차례로 구동 하는지 보죠
U_C FND_CNT=0;
void Timer_0_Interrupt(void) interrupt 1{ // 225Hz주기
P4=0xFF; // FND OFF
switch(FND_CNT){
case 0: P0=Seg_Data[counter/1000]; FND_COM1=0; break;
case 1: P0=Seg_Data[(counter/100)%10]; FND_COM2=0; break;
case 2: P0=Seg_Data[(counter/ 10)%10]; FND_COM3=0; break;
case 3: P0=Seg_Data[counter%10]; FND_COM4=0; break;
}
if(++FND_CNT>3)FND_CNT=0;
//
if(delay_buf){ if(--delay_buf==0)delay_flg=1; }
}FND_CNT 변수는 인터럽트 함수를 실행 할 때마다 0~3 사이에서 1씩 증가 하고
각각의 숫자에 해당 하는 FND를 구동 하게 됩니다.
//----------------------
이번에는 FND 세그멘트와 콤몬 구동을 살펴보죠
void Timer_0_Interrupt(void) interrupt 1{ // 225Hz주기
P4=0xFF; // FND OFF 콤몬OFF
switch(FND_CNT){
case 0: P0=Seg_Data[counter/1000]; // 세그멘트 출력FND_COM1=0; // 콤몬 출력
break;
case 1: P0=Seg_Data[(counter/100)%10]; FND_COM2=0; break;
case 2: P0=Seg_Data[(counter/ 10)%10]; FND_COM3=0; break;
case 3: P0=Seg_Data[counter%10]; FND_COM4=0; break;
}
if(++FND_CNT>3)FND_CNT=0;
//
if(delay_buf){ if(--delay_buf==0)delay_flg=1; }
}
초기에 콤몬 OFF를 왜 시키느냐면아무리 짧은 시간이라도 시간적으로 보면
P0=Seg_Data[counter/1000]; // 세그멘트 출력 // 여기 부터
FND_COM1=0; // 콤몬 출력 // 이 출력이 나가기 전꺼지는
이전에 선택된 콤몬 자리에 방금 출력한 세그멘트 출력이 켜지게 됩니다.
다른 위치에 옆자리의 데이터가 출력 되는 것입니다.
나타나지 말아야할 옆자리의 데이터가 표시되는 것이므로
"고스트현상" 이라고 부르기도 합니다.
//----------------------
댓글 0
조회수 1,343등록된 댓글이 없습니다.