MG82F6D Series RTC Timer
1. 프로그램 개요
P22는 Green 0 LED, P24는 Red LED, P26은 Green 1 LED가 연결되어 있다.
IC 내부에 내장된 RTC를 테스트 한다.
2. 회로도
3. Code
⑴ main routine
void main()
{
InitSystem(); // 시스템 초기화
LED_G_0=0;LED_G_1=0;LED_R=0; // LED ALL ON
DelayXms(1000); // 1초 딜레이
LED_G_0=1;LED_G_1=1;LED_R=1; // LED ALL OFF
while(1)
{
DelayXms(100); // 100ms 딜레이
LED_G_0=!LED_G_0; // LED_G_0 토글
}
}
⑵ 시스템 초기화 루틴
/***********************************************************************************
*Function: void InitSystem(void)
*Description: Initialize MCU
*Input:
*Output:
*************************************************************************************/
void InitSystem(void)
{
InitPort(); // 포트 설정
InitRTC(); // RTC 설정
InitInterrupt(); // Initialize Interrupt
INT_EnAll(); // Enable global interrupt
}
- 포트 설정을 수행한다.
- 시스템 클럭은 default로 IHRCO 12MHz로 설정된다.
- RTC 설정
- 인터럽트 동작 설정
- 인터럽트 전체 동작 설정
⑶ Port 초기화
/***********************************************************************************
*Function: void InitPort(void)
*Description: Initialize IO Port
*Input:
*Output:
*************************************************************************************/
void InitPort(void)
{
EnP44P45GPIO();
è P44, P45를 GPIO로 사용하도록 설정함
PORT_SetP2PushPull(BIT2|BIT4|BIT6); // Set P22,P24,P26 as Push-Pull,For LED.
è P22, P24, P26은 LED 구동을 위하여 Push-Pull type로 설정한다.
PORT_SetP4OpenDrainPu(BIT4|BIT5);
è P44, P45는 Pull-Up을 가진 Open Drain 모드로 설정한다.
}
*** 사용된 매크로함수는 “API_Macro_MG82FG6D16.H”에서 찾아볼 수 있다.
\Megawin 8051\(EN)MG82F6D16_SampleCode_v1.20\MG82F6D16_RTC_Timer\code\include
⑷ RTC 초기화 루틴
/***********************************************************************************
*Function: void InitRTC(void)
*Description: Initialize RTC
* RTC Clock source: ILRCO 32KHz
* RTC Clock prescale: 32
* RTC Reload Value: (64-10)=54
* RTC Overflow freq: 32K/32/10 ~= 100Hz
*Input:
*Output:
*************************************************************************************/
void InitRTC(void)
{
RTC_SetClock_ILRCO(); // RTC Clock source: ILRCO 32KHz
RTC_SetClock_Div_32(); // RTC Clock prescale: 32
RTC_SetReload(64-10); // RTC Reload Value: (64-10)=54
RTC_SetCounter(64-10);
RTC_EnRTCO_OutP45(); // Enable RTC output on P45
RTC_ClearRTCF(); // clear RTCF
RTC_Enable(); // Enable RTC
}
- RTC 클럭을 ILRCO로 설정
#define RTC_SetClock_ILRCO()
ISPCR=0x80;IFADRH=0x0;IFADRL=CKCON4_P;IFMT=ISP_READ_P;SCMD=0x46;SCMD=0xB9;_nop_();
IFD=(IFD&(0x1F))|(RCSS0_P);IFADRH=0x0;IFADRL=CKCON4_P;IFMT=ISP_WRITE_P;SCMD=0x46;SCMD=0xB9;_nop_();
IFMT=0;ISPCR=0x0
Page P에 있는 CKCON4의 Bit7~5를 이용해서 다양한 클럭 소스원 중 ILRCO로 설정하돌록 한다.
- RTC Clock의 Prescale를 32로 설정한다. RTCCS.3~0을 1010으로 설정
#define RTC_SetClock_Div_32()
RTCTM=(RTCTM&(0x3F))|(BIT7);
ISPCR=0x80;IFADRH=0x0;IFADRL=CKCON4_P;IFMT=ISP_READ_P;SCMD=0x46;SCMD=0xB9;_nop_();
IFD=(IFD&(0xFC))|(BIT1);IFADRH=0x0;IFADRL=CKCON4_P;IFMT=ISP_WRITE_P;SCMD=0x46;SCMD=0xB9; _nop_();
IFMT=0;ISPCR=0x0
RTCM의 7번비트와 6번 비트가 RTCCS.1, RTCCS.0이다. 따라서 RTCTM의 7, 6번 비트를 클리어 시키고, 7번 비트를 셋 시킨다.
Page P의 CKCON4레지스터의 값을 읽고, RTCCS.3, RTCCS.2인 1번, 0번 비트를 클리어 시키고, RTCCS.3을 셋 시킨다.
그렇게 되면 Prescale을 32로 설정할 수 있다.
- 재적재 값 및 RTC 카운트 값 저장
#define RTC_SetReload(x) RTCCR=(RTCCR&(0xC0))|(x)
#define RTC_SetCounter(x) RTCTM=(RTCTM&(0xC0))|(x)
RTC 카운트는 최대 64회이다. 앞선 클럭 설정에서 32kHz의 ILRCO로 설정되었고 Prescaler는 32로 설정되어 RTC 카운트에 입력되는 클럭은 1kHz 즉 1ms주기가 된다.
재적재 값과 카운트 값을 (64-10)으로 한 것은 10m 마다 Overflow를 만들어주기 위해서이다.
- RTCKO 포트 지정
#define RTC_EnRTCO_OutP45() RTCCR=RTCCR|RTCO
RTCKO로 P45를 사용한다.
Overflow 마다 P45의 논리가 토글 된다.(LED 시그널과 동일한 신호 발생)
- RTC 플래그 클리어
#define RTC_ClearRTCF() PCON1=RTCF
플래그를 클리어 시켜 초기 동작을 확실시 시킨다.
- RTC 카운터의 동작을 시작한다.
#define RTC_Enable() RTCCR=RTCCR|RTCE
⑹ 인터럽트 초기화
/***********************************************************************************
*Function: void InitInterrupt(void)
*Description: Initialize Interrupt
*Input:
*Output:
*************************************************************************************/
void InitInterrupt(void)
{
INT_EnSF_RTC(); // Enable RTC interrupt, must enble SF interrupt
INT_EnSF(); // Enable SF interrupt
}
- RTCF 인터럽트 활성화
#define INT_EnSF_RTC() SFIE=SFIE|RTCFIE
SFIE(시스템 플래그 인터럽트 인에이블 레지스터)의 RTCFIE를 셋 시켜서 RTCF 인터럽트를 활성화 시킨다. RTCF는 CPU가 idle 또는 Power down 모드일 경우 wake up 시킬 수 있다.
- 확장 인터럽트 인에이블
#define INT_EnSF() EIE1=EIE1|ESF
EIE1(확장된 인터럽트 인에이블 1 레지스터)의 ESF를 셋 시켜서 다양한 시스템 플래그들에 대한 인터럽트를 준비한다.
⑺ Enable Global Interrupt
#define INT_EnAll() EA=1 // Global enable
사용자가 설정한 시스템 인터럽트를 Enable 시킨다.
⑻ 인터럽트 루틴
/***********************************************************************************
*Function: void INT_SF(void)
*Description: SF(system flag)Interrupt handler
RTC,WDTF,BOD0F,BOD1F
*Input:
*Output:
*************************************************************************************/
void INT_SF(void) interrupt INT_VECTOR_SF // SF 시스템 플래그에 대한 인터럽트 서비스 루틴
{
if((PCON1&WDTF)!=0) // 와치도그 타이머 인터러트 시
{
PCON1=WDTF; // 와치도그 플래그클리어
}
if((PCON1&BOF0)!=0) // BOD 0 인터럽트
{
PCON1=BOF0; // BOD 0 인터럽트 플래그 클리어
}
if((PCON1&BOF1)!=0) // BOD 1 인터럽트
{
PCON1=BOF1; // BOD 1 인터럽트 플래그 클리어
}
if((PCON1&RTCF)!=0) // RTC 인터럽트
{
PCON1=RTCF; // RTC 인터럽트 플래그 클리어
LED_R=!LED_R; // LED_R 토글
}
}
4. 프로그램 실행
*** Keil compiler가 인스톨되어 있어야함 ***
해당 Example 폴더를 찾아가 KeilPrj폴더를 Open 한다.
\Megawin 8051\(EN)MG82F6D16_SampleCode_v1.20\ MG82F6D16_RTC_Timer\KeilPrj
해당 폴더의 Keil project 파일을 더블 클릭하여 실행시킨다.(MG82F6D16_DEMO.uvproj)
Rebuild 아이콘을 클릭하여 프로젝트를 컴파일 한다.
Demo Board에 USB Connector를 연결하여 전원을 인가하고, 전원 스위치를 ON시키고, OCD ICE를 연결한 상태에서 위 이미지의 Start/Stop Debug Session(Ctrl+F5) 버튼을 눌러 컴파일된 프로젝트의 디버그 데이터를 다운로드 시킨다.(컴파일 시 에러가 발생하지 않아야함)
다운로드 후 Run(F5) 버튼을 클릭하면 프로그램이 동작한다.
5. 동작 영상