8051/PIC > 초보자를 위한 8051 시계키트 강좌 (2) - C소스분석

TODAY636 TOTAL608,637
사이트 이용안내
Login▼/회원가입
최신글보기 질문게시판 기술자료 동영상강좌

아두이노 센서 ATMEGA128 PWM LED 초음파 AVR 블루투스 LCD UART 모터 적외선


BASIC4MCU | 8051/PIC | 8051 | 초보자를 위한 8051 시계키트 강좌 (2) - C소스분석

페이지 정보

작성자 키트 작성일2017-09-12 10:09 조회499회 댓글0건

본문

/////////////////////////////////////////////////////////////
#include <sfr.h>                  
// 8051 의 SFR 이 정의된 파일
#include <os.h>                   
// 8051 의 인터럽트 번호 정의된 파일 
/////////////////////////////////////////////////////////////
// 7 Segment Pattern Data
#define Segpat0 0xC0              
// &B11000000       0   ****A***
#define Segpat1 0xF9              
// &B11111001       1   *      *
#define Segpat2 0xA4              
// &B10100100       2   F      B
#define Segpat3 0xB0              
// &B10110000       3   *      *
#define Segpat4 0x99              
// &B10011001       4   ****G***
#define Segpat5 0x92              
// &B10010010       5   *      *
#define Segpat6 0x82              
// &B10000010       6   E      C
#define Segpat7 0xD8              
// &B11011000       7   *      *
#define Segpat8 0x80              
// &B10000000       8   ****D***
#define Segpat9 0x98              
// &B10011000       9
#define Segpblk 0xFF              
// &B11111111      10 BLANK
/////////////////////////////////////////////////////////////
_sfrbit hour10   =  _p1^0;        
// 10시 표시 
_sfrbit led_am   =  _p1^1;        
// 오전 표시 LED
_sfrbit led_pm   =  _p1^2;        
// 오후 표시 LED
_sfrbit piezo    =  _p1^3;        
// 피에조 부져
_sfrbit sw_alarm =  _p1^4;        
// 알람 설정 
_sfrbit sw_save  =  _p1^5;        
// 알람 시각 저장 
_sfrbit sw_hour  =  _p1^6;        
// 시 조정
_sfrbit sw_min   =  _p1^7;        
// 분 조정 
_sfrbit led_low  =  _p0^7;        
// 
_sfrbit led_high =  _p2^7;        
//
_sfrbit led_alrm =  _p3^7;        
// 알람 표시 LED
/////////////////////////////////////////////////////////////
unsigned int  icount;           
unsigned char clock_cent;         
// 1/100 초 단위(0 ~ 99)
unsigned char clock_second;       
// 초 단위 변수 (0 ~ 59)
unsigned char clock_min;          
// 분 단위 변수 (0 ~ 59)
unsigned char clock_hour;         
// 시 단위 변수 (0 ~ 23)
unsigned char alarm_min;          
// 분 단위 변수 (0 ~ 59)
unsigned char alarm_hour;         
// 시 단위 변수 (0 ~ 23)
_bit beep;                        
//
_bit alarm;                       
// 알람 모드 
//---------------------------------------------------------------------------
unsigned char _code fnd_pattern[] = { Segpat0, Segpat1, Segpat2, Segpat3, \
         Segpat4, Segpat5, Segpat6, Segpat7, Segpat8, Segpat9, Segpblk };   
// Code Memory

void _interrupt IVN_TIMER0 time_base() {          
// Clock, Timer
/********************************************************************
* Timer 0 Interrupt                                                *
* 250uS 주기로 인터럽트가 발생합니다. icount 를 증가시키고         *
* beep 비트의 상태에 따라 피에보 부져를 동작시킵니다.              *
********************************************************************/

   icount++;

   if (icount > 39) {    
// 인터럽트가 발생할 때마다  
      icount = 0;
      clock_cent++;
   }

   if (beep == 1) {      
// BEEP 가 설정되어 있으면 피에조 부져를 
      if (piezo == 1) {  
// ON/OFF 합니다. 
         piezo = 0;
      } else {
         piezo = 1;
      }
   }
}

void delay() {
/********************************************************************
* for 문을 이용한 간단한 딜레이 루틴입니다.                        *
********************************************************************/

unsigned int i;
       for (i = 0; i < 20000; i++) ;
}

void clock_run() {
/********************************************************************
* 시간을 카운트 합니다.                                            *
********************************************************************/

//
   if (clock_cent > 99) {
      clock_cent = 0;
      clock_second++;
   }
//
   if (clock_second > 59) {
      clock_second = 0;
      clock_min++;
   }
//
   if (clock_min > 59) {
      clock_min = 0;
      clock_hour++;
   }
//
   if (clock_hour > 23) {
      clock_hour = 0;
   }
}

void fnd_display(unsigned char hour, unsigned char min, bit a) {
/********************************************************************
* FND 에 시간을 표시 합니다.                                       *
* 비트 변수 a 는 시 분 사이의 LED 의 점멸 상태를 선택합니다.       *
* a = 0: Low, High LED 를 끕니다.                                  *
* a = 1: Low, High LED 를 점멸합니다.                              *
********************************************************************/

unsigned char t, v;
//
   t = min % 10
   t = fnd_pattern[t];
//
   if (alarm == 1) {
      t = t & 0x7F;
   }
  _p3 = t;
//
   t = min / 10;
   t = fnd_pattern[t];
//
   if (a == 0) {
      if ((clock_cent < 50) || (clock_second > 30)) {   
// High LED Blink
         t = t & 0x7F;
      }
   }
  _p2 = t;
//
   if (hour < 12) {
      led_am = 0; led_pm = 1;     
// AM Led 점등
      v = hour;
   } else { 
      led_am = 1; led_pm = 0;     
// PM Led 점등
      v = hour - 12;
   }
//
   if (v == 0) {                  
// 0 시는 12 시로 교정하여 표시 
      v = 12;
   }
// 
   t = v % 10;
   t = fnd_pattern[t]; 
//
   if (a == 0) {
      if ((clock_cent < 50) || (clock_second <= 30)) {   
// Low LED Blink
         t = t & 0x7F;
      }
   }
  _p0 = t;
//
   t = v / 10;
//
   if (t == 1) {
      hour10 = 0;
   } else {
      hour10 = 1;
   }
//
}

void alarm_proc() {
/********************************************************************
* 알람 시각을 설정합니다.                                          *
* Hour, MIn 스위치를 사용하여 알람 시각을 설정합니다.              *
* SAVE 키를 누르면 알람 시각이 저장 됩니다.                        *
* Alarm 키를 누르면 알람 모드가 해제 됩니다.                       *
********************************************************************/

   fnd_display(alarm_hour, alarm_min, 1);
   delay();

   while(1) {

      fnd_display(alarm_hour, alarm_min, 1);
      if (sw_hour == 0) {
         alarm_hour++;
         if (alarm_hour > 23) {
            alarm_hour = 0;
         }
         delay();
      }
      if (sw_min == 0) {
         alarm_min++;
         if (alarm_min > 59) {
            alarm_min = 0;
         }
         delay();
      }
      if (sw_save == 0) {      
// Save 키 검사
         alarm = 1;            
// 알람 모드 설정
         break;
      }
      if (sw_alarm == 0) {     
// Alarm 키 검사
         alarm = 0;            
// 알람 모드 해제
         break
      }
   }
   delay();
}
   
////////////////////////////////
void main() {
/********************************************************************
* CPU가 리셋되면 main()함수가 처음으로 실행됩니다.                 *
* Timer 0를 초기화하고 변수 값을 클리어 합니다.                    *
********************************************************************/

  _tmod = 0x02;           
// Timer0 Mode 2 (Auto Reload Mode)
  _th0 = 0x06;            
// 12MHz 크리스탈에서 250 uSec 인터럽트 주기 
  _tr0 = 1;               
// Timer 0 동작시작 
  _et0 = 1;           
// 타이머  인터럽트 가능상태 설정   
  _ea = 1;           
// 글로벌 인터럽트 가능상태 설정

   icount = 0;
   clock_cent = 0;
   clock_second = 0;
   clock_min = 0;
   clock_hour = 0;
   alarm_min = 0;
   alarm_hour = 0;
   alarm = 0;

   while(1) {
      clock_run();
      fnd_display(clock_hour, clock_min, 0);

      if ((alarm == 1) && (alarm_hour == clock_hour) && (alarm_min == clock_min)) {
         beep = 1; }       
// 알람 모드일때 알람 시간이되면 BEEP 비트를 설정합니다.
      else {
         beep = 0;
      }

      if (sw_min == 0) {   
// 분 조정 스위치가 눌려졌는지 확인합니다.
         clock_second = 0;
         clock_min++;
         if (clock_min > 59) {
            clock_min = 0;
         }   
         delay();
      }

      if (sw_hour == 0) {  
// 시 조정 스위치가 눌려졌는지 확인합니다.
         clock_hour++;
         if (clock_hour > 23) {
            clock_hour = 0;
         }   
         delay();
      }

      if (sw_alarm == 0) { 
// 알람 설정 스위치가 눌려졌는지 확인합니다. 
          alarm_proc();
      }
   }
}

//---------------------------------------------------------
//---------------------------------------------------------
//고수가 보면 짧은 소스겠지만
//초보자에게는 아주 기~~~~~ㄴ 소스입니다.
//기능 위주로 내용을 요약해서 다시 표시 해보겠습니다.
//---------------------------------------------------------
//---------------------------------------------------------
void _interrupt IVN_TIMER0 time_base() { 
// 250uS 주기 인터럽트
   clock_cent++;   
// 10 mSec 카운트
   piezo = ~piezo; 
// BEEP 가 설정되어 있으면 피에조 부져를 반전 2KHz
}

void delay() { } 
// for 문을 이용한 간단한 딜레이 루틴

void clock_run() { 
// 시간 카운트
   clock_second++; 
// clock_cent > 99 면 1초 카운트 증가
   clock_min++;    
// clock_second > 59 면 1분 카운트 증가
   clock_hour++;   
// clock_min > 59 면 1시간 카운트 증가
}

void fnd_display(unsigned char hour, unsigned char min, bit a) { } 
//FND 시간 표시 

void alarm_proc() { } 
// 알람 시각 설정
   
void main() {
   Timer 0을 초기화하고 변수 값을 클리어
   글로벌 인터럽트 허용
   while(1) {
      clock_run();   
//시간계산
      fnd_display(); 
// fnd 표시
      알람 시간이면 BEEP 비트를 설정

      clock_min++;  
// 분 조정 스위치가 눌려졌으면
      clock_hour++; 
// 시 조정 스위치가 눌려졌으면
      alarm_proc();  
// 알람설정 스위치가 눌려졌으면
   }
}


전체적으로 소스가 짧아져서 큰 기능 이해 하는데 도움이 될겁니다.

다음 시간에는 함수별로 소스를 분석 해 보겠습니다.

사람마다 코딩에 사용되는 기법이 다릅니다.
분석 하면서 제가 자주 쓰는 표현으로 바꿔 보겠습니다.

위 소스 원본 코드는
학생들이 이해 하기 쉽도록 배려가 되어 있는 코드입니다.
사실...어렵게 짜는 것과 쉽게 짜는 것, 둘 다 어렵습니다.
저는 그 중간의 어정쩡한 실력이라고나 할까요;;;

댓글 0

조회수 499

등록된 댓글이 없습니다.

8051/PICHOME > 8051/PIC > 전체 목록

게시물 검색

2019년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2018년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
Privacy Policy
MCU BASIC ⓒ 2017
모바일버전으로보기