해보기는 했어?

오늘 안됐다고 포기하지 말고 용기내서 내일 다시 해 보자.

MEGAWIN

MG82F6D Series TIM_T0T1_Mode 0

롬돌이 2022. 11. 23. 09:53
반응형

1. 프로그램 개요

P22Green 0 LED, P24 Red LED, P26Green 1 LED가 연결되어 있다.

Timer 0, Timer 1을 설정하고, T0CKO(P34), T1CKO(P35)에서 펄스가 나올 수 있도록 한다.

Timer 0 System Clock/192인 주파수를 입력클럭으로 사용하므로 62.5kHz의 주파수로 동작한다. Timer 0 16us 마다 1씩 증가하게 된다. Timer 0 인터럽트에서는 TH0의 값을 0 ~ FF까지 변화 시키므로 T0CKO에서는 약 244Hz의 구형펄스 주파수가 Duty가 변화 되는 모습을 보여준다.

Timer 1 System Clock/48인 주파수를 입력클럭으로 사용하므로 250kHz의 주파수로 동작한다. Timer 1 4us 마다 1씩 증가하게 된다. Timer 1 인터럽트에서는 TH1의 값을 0 ~ FF까지 변화 시키므로 T1CKO에서는 약 976Hz의 구형펄스 주파수가 Duty가 변화 되는 모습을 보여준다.

 

 

2. 회로도

                         

 

 

 

 

3. Code

main routine

 

void main()

{

InitSystem();                            // 시스템 초기화

LED_G_0=0;LED_G_1=0;LED_R=0;    // LED ALL ON

           DelayXms(1000);                       // Delay 1000ms

          LED_G_0=1;LED_G_1=1;LED_R=1;    // LED ALL OFF

                                                    

while(1)

{

                     DelayXms(100);              // Delay 100ms

LED_G_0=!LED_G_0;         // LED_G_0 toggle

}

}

⑵ 시스템 초기화 루틴

/***********************************************************************************

*Function:   void InitSystem(void)

*Description:           Initialize MCU

*Input:  

*Output:    

*************************************************************************************/

void InitSystem(void)

{

           InitPort();                             // 포트 초기화

           InitClock();                           // 클럭 초기화

                     

           InitTimer0_8bit_PWM(); // Timer 0 8-bit PWM 모드로 설정

           InitTimer1_8bit_PWM(); // Timer 1 8-bit PWM 모드로 설정

 

           InitInterrupt();                       // Initialize Interrupt

          

           INT_EnAll();                          // Enable global interrupt

}

- 포트 설정을 수행한다.

- Timer 0/18-bit PWM으로 설정한다.

- 인터럽트 초기화

- #define INT_EnAll()                       EA=1              // Global enable

 

Port 초기화

/***********************************************************************************

*Function:   void InitPort(void)

*Description:            Initialize IO Port

*Input:  

*Output:    

*************************************************************************************/

void InitPort(void)

{

           PORT_SetP2PushPull(BIT2|BIT4|BIT6);                              // Set P22,P24,P26 as Push-Pull,For LED.

è P22, P24, P26LED를 위한 Push-Pull 타입으로 설정

           PORT_SetP3QuasiBi(BIT0|BIT1|BIT3|BIT4|BIT5);               // Set P30,P31,P33,P34,P35 as Quasi-Bidirectional

è P30, P31, P33, P34, P35는 양방향 핀으로 설정한다. 이 중 P34, P35TCKO로 사용된다.

}

*** 사용된 매크로함수는 “API_Macro_MG82FG6D16.H”에서 찾아볼 수 있다.

\Megawin 8051\(EN)MG82F6D16_SampleCode_v1.20\MG82F6D16_GPIO_TIM_T0T1\code\include

 

 

 

⑷ 클럭 초기화 루틴 è 시스템 클럭 및 내부 클럭을 설정한다.

프로그램의 루틴 자체는 복잡하게 많이 설정해 두었으나 그 구조는 아래와 같다.

MCU_SYSCLK의 값은 11059200, 12000000, 22118400, 24000000, 29491200, 32000000, 44236800, 48000000로 설정이 가능하며, 각각 프로그램 상단에

#define        MCU_SYSCLK          12000000

와 같이 선언해주었다. 그리고, 바로

#define        MCU_CPUCLK          (MCU_SYSCLK)

로 선언하여 System 클럭과 CPU 클럭을 동일하게 사용하기로 선언하였다. 물론 사용자의 선택에 따라 틀려질 수 있으므로 어플리케이션에 따라 선언하면 된다.

#if (MCU_SYSCLK==12000000)                        // System Clock12MHz로 선언되어 있으면

#if (MCU_CPUCLK==MCU_SYSCLK)                    // CPU ClockSystem Clock와 동일하면

         // SysClk=12MHz CpuClk=12MHz

         CLK_SetCKCON0(IHRCO_12MHz|CPUCLK_SYSCLK_DIV_1|SYSCLK_MCKDO_DIV_1);         // 이와 같이 설정하고

        

#else

         // SysClk=12MHz CpuClk=6MHz

         CLK_SetCKCON0(IHRCO_12MHz|CPUCLK_SYSCLK_DIV_2|SYSCLK_MCKDO_DIV_1);         // CPU clockSystem Clock와 같거나 1/2로 설정할

// 수 있다.

#endif

#endif

- CLK_SetCKCON0(IHRCO_12MHz|CPUCLK_SYSCLK_DIV_1|SYSCLK_MCKDO_DIV_1);

CKCON0 레지스터의 각 비트를 설정한다.

CKCON0.7 : AFS, Alternated Frequency Selection, 내부 클럭 IHRCO12MHz(AFS = 0), 또는 11.059MHz(AFS = 1)로 설정함

CKCON0.3 : CCKS, CPU Clock Select, 0:CPU CLOCK = System Clock, 1:CPU CLOCK = System Clock/2

CKCON0.0 ~ 2 : Programable System Clock Select. SYSCLK_MCKDO_DIV_1(System Clock = Master Clock Divider Output)

 

/***********************************************************************************

*Function:   void InitClock(void)

*Description: 

*                                  Initialize clock

*Input:  

*Output:    

*************************************************************************************/

void InitClock(void)

{

#if (MCU_SYSCLK==11059200)

#if (MCU_CPUCLK==MCU_SYSCLK)

         // SysClk=11.0592MHz CpuClk=11.0592MHz

         CLK_SetCKCON0(IHRCO_110592MHz|CPUCLK_SYSCLK_DIV_1|SYSCLK_MCKDO_DIV_1);

        

#else

         // SysClk=11.0592MHz CpuClk=5.5296MHz

         CLK_SetCKCON0(IHRCO_110592MHz|CPUCLK_SYSCLK_DIV_2|SYSCLK_MCKDO_DIV_1);

#endif

#endif

 

#if (MCU_SYSCLK==12000000)

#if (MCU_CPUCLK==MCU_SYSCLK)

         // SysClk=12MHz CpuClk=12MHz

         CLK_SetCKCON0(IHRCO_12MHz|CPUCLK_SYSCLK_DIV_1|SYSCLK_MCKDO_DIV_1);

        

#else

         // SysClk=12MHz CpuClk=6MHz

         CLK_SetCKCON0(IHRCO_12MHz|CPUCLK_SYSCLK_DIV_2|SYSCLK_MCKDO_DIV_1);

#endif

#endif

 

#if (MCU_SYSCLK==22118400)

#if (MCU_CPUCLK==MCU_SYSCLK)

         // SysClk=22.1184MHz CpuClk=22.1184MHz

         CLK_SetCKCON0(IHRCO_110592MHz|CPUCLK_SYSCLK_DIV_1|SYSCLK_MCKDO_DIV_1|ENABLE_CKM|CKM_OSCIN_DIV_2);

         DelayXus(100);

         // IHRCO, MCK=CKMIx4, OSCin=IHRCO

         CLK_SetCKCON2(ENABLE_IHRCO|MCK_CKMI_X4|OSCIn_IHRCO);

#else

         // SysClk=22.1184MHz CpuClk=11.0592MHz

         CLK_SetCKCON0(IHRCO_110592MHz|CPUCLK_SYSCLK_DIV_2|SYSCLK_MCKDO_DIV_1|ENABLE_CKM|CKM_OSCIN_DIV_2);

         DelayXus(100);

         // IHRCO, MCK=CKMIx4, OSCin=IHRCO

         CLK_SetCKCON2(ENABLE_IHRCO|MCK_CKMI_X4|OSCIn_IHRCO);

#endif

#endif

 

#if (MCU_SYSCLK==24000000)

#if (MCU_CPUCLK==MCU_SYSCLK)

         // SysClk=24MHz CpuClk=24MHz

         CLK_SetCKCON0(IHRCO_12MHz|CPUCLK_SYSCLK_DIV_1|SYSCLK_MCKDO_DIV_1|ENABLE_CKM|CKM_OSCIN_DIV_2);

         DelayXus(100);

         // IHRCO, MCK=CKMIx4, OSCin=IHRCO

         CLK_SetCKCON2(ENABLE_IHRCO|MCK_CKMI_X4|OSCIn_IHRCO);

#else

         // SysClk=24MHz CpuClk=12MHz

         CLK_SetCKCON0(IHRCO_12MHz|CPUCLK_SYSCLK_DIV_2|SYSCLK_MCKDO_DIV_1|ENABLE_CKM|CKM_OSCIN_DIV_2);

         DelayXus(100);

         // IHRCO, MCK=CKMIx4, OSCin=IHRCO

         CLK_SetCKCON2(ENABLE_IHRCO|MCK_CKMI_X4|OSCIn_IHRCO);

#endif

#endif

 

#if (MCU_SYSCLK==29491200)

#if (MCU_CPUCLK==MCU_SYSCLK)

         // Cpuclk high speed

         CLK_SetCpuCLK_HighSpeed();

         // SysClk=29.491200MHz CpuClk=29.491200MHz

         CLK_SetCKCON0(IHRCO_110592MHz|CPUCLK_SYSCLK_DIV_1|SYSCLK_MCKDO_DIV_1|ENABLE_CKM|CKM_OSCIN_DIV_2);

         DelayXus(100);

         // IHRCO, MCK=CKMIx5.33, OSCin=IHRCO

         CLK_SetCKCON2(ENABLE_IHRCO|MCK_CKMI_X533|OSCIn_IHRCO);

#else

         // SysClk=29.491200MHz CpuClk=14.7456MHz

         CLK_SetCKCON0(IHRCO_110592MHz|CPUCLK_SYSCLK_DIV_2|SYSCLK_MCKDO_DIV_1|ENABLE_CKM|CKM_OSCIN_DIV_2);

         DelayXus(100);

         // IHRCO, MCK=CKMIx5.33, OSCin=IHRCO

         CLK_SetCKCON2(ENABLE_IHRCO|MCK_CKMI_X533|OSCIn_IHRCO);

#endif

#endif

 

#if (MCU_SYSCLK==32000000)

#if (MCU_CPUCLK==MCU_SYSCLK)

         // Cpuclk high speed

         CLK_SetCpuCLK_HighSpeed();

         // SysClk=32MHz CpuClk=32MHz

         CLK_SetCKCON0(IHRCO_12MHz|CPUCLK_SYSCLK_DIV_1|SYSCLK_MCKDO_DIV_1|ENABLE_CKM|CKM_OSCIN_DIV_2);

         DelayXus(100);

         // IHRCO, MCK=CKMIx5.33, OSCin=IHRCO

         CLK_SetCKCON2(ENABLE_IHRCO|MCK_CKMI_X533|OSCIn_IHRCO);

#else

         // SysClk=32MHz CpuClk=16MHz

         CLK_SetCKCON0(IHRCO_12MHz|CPUCLK_SYSCLK_DIV_2|SYSCLK_MCKDO_DIV_1|ENABLE_CKM|CKM_OSCIN_DIV_2);

         DelayXus(100);

         // IHRCO, MCK=CKMIx5.33, OSCin=IHRCO

         CLK_SetCKCON2(ENABLE_IHRCO|MCK_CKMI_X533|OSCIn_IHRCO);

#endif

#endif

 

#if (MCU_SYSCLK==44236800)

         // SysClk=44.2368MHz CpuClk=22.1184MHz

         CLK_SetCKCON0(IHRCO_110592MHz|CPUCLK_SYSCLK_DIV_1|SYSCLK_MCKDO_DIV_1|ENABLE_CKM|CKM_OSCIN_DIV_2);

         DelayXus(100);

         // IHRCO, MCK=CKMIx8, OSCin=IHRCO

         CLK_SetCKCON2(ENABLE_IHRCO|MCK_CKMI_X8|OSCIn_IHRCO);

#endif

 

#if (MCU_SYSCLK==48000000)

         // SysClk=48MHz CpuClk=24MHz

         CLK_SetCKCON0(IHRCO_12MHz|CPUCLK_SYSCLK_DIV_2|SYSCLK_MCKDO_DIV_1|ENABLE_CKM|CKM_OSCIN_DIV_2);

         DelayXus(100);

         // IHRCO, MCK=CKMIx8, OSCin=IHRCO

         CLK_SetCKCON2(ENABLE_IHRCO|MCK_CKMI_X8|OSCIn_IHRCO);

#endif

 

         // P60 Output MCK/4

         //CLK_P60OC_MCKDiv4();

}

 

Timer 0 설정

/***********************************************************************************

*Function:   void InitTimer0_8bit_PWM(void)

*Description:   Initialize Timer0 for 8bit PWM

*Input:  

*Output:    

*************************************************************************************/

void InitTimer0_8bit_PWM(void)

{

           TM_SetT0Mode_0_8BIT_PWM();                                                              // TIMER0 Mode: 8bit PWM

           TM_SetT0Clock_SYSCLKDiv192();                                                // TIMER0 Clock source:SYSCLK/192

           TM_SetT0Gate_Disable();

           TM_SetT0LowByte(0);                                                                           // Set TL0 value

           TM_SetT0HighByte(0);                                                                // Set TH0 value

           TM_SetT0CKO_P34();                                                                            // set T0CKO to P34

           TM_EnT0CKO();                                                                                              // Enable T0CKO output

           TM_EnableT0();                                                                                              // Enable T0

}

- Timer 0 8Bit PWM모드로 설정

#define TM_SetT0Mode_0_8BIT_PWM()                                        TMOD=(TMOD&(~(T0M0|T0M1)))

TMOD 레지스터의 T0M1, T0M0을 모두 0으로 저장하면 8-bit PWM generator 모드로 설정됨

 

 

- Timer 0용 클럭 설정

#define TM_SetT0Clock_SYSCLKDiv192()                          AUXR3=(AUXR3|(T0XL));AUXR2=(AUXR2|(T0X12));TMOD=(TMOD&(~T0C_T))

AUXR3 T0XL, AUXR2T0X12, TMODT0C/T의 조합으로 타이머의 클럭을 선택한다.

T0XL = 1, T0X12 = 1, T0C/T = 0이므로 SYSCLK/192Timer 0 클럭으로 사용한다. (62.5kHz, 16us 마다 1증가한다.)

 

- Gate 기능을 OFF 시킴

#define TM_SetT0Gate_Disable()                                                TMOD=TMOD&(~T0GATE)

 

- Timer 0 Low count register의 값을 0으로 저장

#define TM_SetT0LowByte(x)                               TL0=x

 

- Timer 0 High count register의 값을 0으로 저장

#define TM_SetT0HighByte(x)                               TH0=x

 

- T0CKO P34에 설정함

#define TM_SetT0CKO_P34()                      AUXR3=AUXR3&(~(T0PS0|T0PS1))

T0CKO P34, P44, P22, P26으로 설정할 수 있으나 본 예제에서는 P34로 설정한다.

 

- T0CKO Enable

#define TM_EnT0CKO()                                        AUXR2=AUXR2|(T0CKOE)

 

- Timer 0 동작

#define TM_EnableT0()                              TR0=1

TCONTR0 비트를 셋(1, High) 시킴으로서 Timer 0을 시작시킨다.

 

 

 

 

Timer 1 설정

/***********************************************************************************

*Function:   void InitTimer1_8bit_PWM(void)

*Description:   Initialize Timer1 for 8bit PWM

*Input:  

*Output:    

*************************************************************************************/

void InitTimer1_8bit_PWM(void)

{

           TM_SetT1Mode_0_8BIT_PWM();                                                              // TIMER1 Mode: 8bit PWM

           TM_SetT1Clock_SYSCLKDiv48();                                                 // TIMER1 Clock source:SYSCLK/48

           TM_SetT1Gate_Disable();

           TM_SetT1LowByte(0);                                                                           // Set TL1 value

           TM_SetT1HighByte(0);                                                                // Set TH1 value

           TM_SetT1CKO_P35();                                                                            // set T1CKO to P35

           TM_EnT1CKO();                                                                                              // Enable T1CKO output

           TM_EnableT1();                                                                                              // Enable T1

}

- Timer 1 8Bit PWM모드로 설정

#define TM_SetT1Mode_0_8BIT_PWM()                                        TMOD=(TMOD&(~(T1M0|T1M1)))

TMOD 레지스터의 T0M1, T0M0을 모두 0으로 저장하면 8-bit PWM generator 모드로 설정됨

 

 

- Timer 1용 클럭 설정

#define TM_SetT1Clock_SYSCLKDiv48()                                      AUXR2=(AUXR2|(T1X12));TMOD=(TMOD|(T1C_T))

AUXR2T1X12, TMODT1C/T의 조합으로 타이머의 클럭을 선택한다.

T1X12 = 1, T0C/T = 1이므로 SYSCLK/48Timer 1 클럭으로 사용한다. (250kHz, 4us 마다 1증가한다.)

 

- Gate 기능을 OFF 시킴

#define TM_SetT1Gate_Disable()                                                TMOD=TMOD&(~T1GATE)

 

- Timer 1 Low count register의 값을 0으로 저장

#define TM_SetT1LowByte(x)                               TL1=x

 

- Timer 1 High count register의 값을 0으로 저장

#define TM_SetT1HighByte(x)                               TH1=x

 

- T1CKO P35에 설정함

#define TM_SetT1CKO_P35()                      SFRPI=1;AUXR4=AUXR4&(~(T1PS0|T1PS1));SFRPI=0

T1CKOP35, P45, P26에 지정할 수 있으며 본 예제에서는 P35에 연결한다.

 

 

- T1CKO Enable

#define TM_EnT1CKO()                                        AUXR2=AUXR2|(T1CKOE)

 

- Timer 0 동작

#define TM_EnableT1()                              TR1=1

TCONTR1 비트를 셋(1, High) 시킴으로서 Timer 1을 시작시킨다.

 

 

⑺ 인터럽트

 

/***********************************************************************************

*Function:   void InitInterrupt(void)

*Description:   Initialize Interrupt

*Input:  

*Output:    

*************************************************************************************/

void InitInterrupt(void)

{

           INT_EnTIMER0();                   // Timer 0 인터럽트 Enable

           INT_EnTIMER1();                   // Timer 1 인터럽트 Enable

          

}

 

- Timer 0 인터럽트 Enable

#define INT_EnTIMER0()                  ET0=1

인터럽트 설정 레지스터인 IE(Interrupt Enable Register)ET0를 셋 시킨다.

 

- Timer 1 인터럽트 Enable

#define INT_EnTIMER1()                  ET1=1

인터럽트 설정 레지스터인 IE(Interrupt Enable Register)ET1를 셋 시킨다.

 

⑻ 글로벌 인터럽트 Enable

#define INT_EnAll()                         EA=1              // Global enable

IE 레지스터의 7번 비트인 EA 비트를 셋 시켜준다.

이 비트를 셋 시키기 전에 모든 다른 인터럽트 설정을 마치도록 한다.

 

 

 

4. 프로그램 실행

*** Keil compiler가 인스톨되어 있어야함 ***

해당 Example 폴더를 찾아가 KeilPrj폴더를 Open 한다.

\Megawin 8051\(EN)MG82F6D16_SampleCode_v1.20\ MG82F6D16_TIM_T0T1_Mode0

 

해당 폴더의 Keil project 파일을 더블 클릭하여 실행시킨다.(MG82F6D16_DEMO.uvproj)

 

Rebuild 아이콘을 클릭하여 프로젝트를 컴파일 한다.

 

Demo BoardUSB Connector를 연결하여 전원을 인가하고, 전원 스위치를 ON시키고, OCD ICE를 연결한 상태에서 위 이미지의 Start/Stop Debug Session(Ctrl+F5) 버튼을 눌러 컴파일된 프로젝트의 디버그 데이터를 다운로드 시킨다.(컴파일 시 에러가 발생하지 않아야함)

 

 

다운로드 후 Run(F5) 버튼을 클릭하면 프로그램이 동작한다.

 

 

5. 동작 영상

반응형

'MEGAWIN' 카테고리의 다른 글

MG82F6D Series INT nINTx Wake UP  (0) 2022.11.25
MG82F6D Series CMP  (0) 2022.11.24
MG82F6D Series TIM_T2_Mode2_Capture  (0) 2022.11.22
MG82F6D Series WDT Reset  (0) 2022.11.17
MG82F6D Series WDT Int.  (0) 2022.11.17