MEGAWIN

MG82F6D PCA PWM 16bit

롬돌이 2022. 11. 30. 10:17
반응형

1. 프로그램 개요

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

SYSTEM Clock24MHz, CPU Clock24MHz로 사용하고, PCA 클럭은 96MHz를 사용한다.

PCA 출력은 CH0(P22), CH1(P33), CH2(P24), CH3(P34), CH4(P26), CH5(P35)로 설정한다.

2개씩 묶어 3쌍을 비교 해 본다.

PWM 주파수는 96MHz/1000 = 96kHz로 설정한다.

P10은 입력으로 사용되며 PWM 출력을 제어한다. 1이면 Enable, 0이면 Disable 이다.

 

 

2. 회로도

         

 

3. Code

main routine

void main()

{

         u8 cnt,inx;                                // 변수 선언

         bit bOutFlag;                            // 변수 선언

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

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

         DelayXms(1000);                        // 1초 딜레이

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

 

         wDuty[0].W=PWM_MIN;               // PWM Duty100으로 설정

         wDuty[1].W=PWM_MIN;              // PWM Duty100으로 설정

         wDuty[2].W=PWM_MIN;              // PWM Duty100으로 설정

         bOutFlag=FALSE;                       // bOutFlag비트의 값을 FALSE로 설정

        

         while(1)

{

DelayXms(1);                    // 1ms 딜레이

cnt++;                           // cnt +1

if(cnt>=200)                             // cnt200이 넘으면(200ms 마다)

        {

                  cnt=0;

                 if(bOutFlag==TRUE)           // bOutFlagTRUE이면

                  {

inx++;                   // inx+1하고

                          if(inx>=8)               // inx8 이상이면

                           {

                                   inx=0;          // inx 0으로 초기화 시킨다.

                           }

                          switch(inx)              // inx 값에 따라

                           {

                                   case 0:         // inx = 0이면

                                            // Duty 100% All High       

                                            wDuty[0].W=PWM_MIN;      // PWM Duty100으로 설정

                                            wDuty[1].W=PWM_MIN;      // PWM Duty100으로 설정

                                            wDuty[2].W=PWM_MIN;      // PWM Duty100으로 설정

                                            break;

 

                                   case 1:

                                            // Duty 75%

                                            wDuty[0].W=PWM_1_4;       // PWM Duty75로 설정

                                            wDuty[1].W=PWM_1_4;      // PWM Duty75로 설정

                                            wDuty[2].W=PWM_1_4;      // PWM Duty75로 설정

                                            break;

 

                                   case 2:

                                            // Duty 50%

                                            wDuty[0].W=PWM_2_4;      // PWM Duty50으로 설정

                                            wDuty[1].W=PWM_2_4;       // PWM Duty50으로 설정

                                            wDuty[2].W=PWM_2_4;       // PWM Duty50으로 설정

                                            break;

 

                                   case 3:

                                            // Duty 25%

                                            wDuty[0].W=PWM_3_4;       // PWM Duty25로 설정

                                            wDuty[1].W=PWM_3_4;       // PWM Duty25 로 설정

                                            wDuty[2].W=PWM_3_4;       // PWM Duty25로 설정

                                            break;

                                                    

                                   case 4:

                                            // Duty 0%    All low

                                            wDuty[0].W=PWM_MAX;     // PWM Duty0로 설정

                                            wDuty[1].W=PWM_MAX;     // PWM Duty0로 설정

                                            wDuty[2].W=PWM_MAX;     // PWM Duty0로 설정

                                            break;

 

                                   case 5:

                                            // Duty 25%

                                            wDuty[0].W=PWM_3_4;       // PWM Duty25로 설정

                                            wDuty[1].W=PWM_3_4;       // PWM Duty25로 설정

                                            wDuty[2].W=PWM_3_4;       // PWM Duty25로 설정

                                            break;

 

                                   case 6:

                                            // Duty 50%

                                            wDuty[0].W=PWM_2_4;       // PWM Duty50으로 설정

                                            wDuty[1].W=PWM_2_4;       // PWM Duty50으로 설정

                                            wDuty[2].W=PWM_2_4;       // PWM Duty50으로 설정

                                            wDuty[3].W=PWM_2_4;       // PWM Duty50으로 설정

                                            break;

 

                                   case 7:

                                            // Duty 75%

                                            wDuty[0].W=PWM_1_4;       // PWM Duty75로 설정

                                            wDuty[1].W=PWM_1_4;       // PWM Duty75로 설정

                                            wDuty[2].W=PWM_1_4;       // PWM Duty75로 설정

                                            break;

                                                    

                          }

                           // Buffer mode ,CH0/CH1 is reload by CH1

                           PCA_CH1_SetValue(PCA_CH(wDuty[0].W),PCA_CL(wDuty[0].W));

                           // Buffer mode,CH2/CH3 is reload by CH3

                           PCA_CH3_SetValue(PCA_CH(wDuty[1].W),PCA_CL(wDuty[1].W));

                           // Buffer mode,CH4/CH5 is reload by CH5

                           PCA_CH5_SetValue(PCA_CH(wDuty[2].W),PCA_CL(wDuty[2].W));

                  }

        }

        if(P10==1)     // P10에 연결된 버튼이 안눌렸으면

        {

                  if(bOutFlag==FALSE) // bOutFlagFALSE일 때

                  {

                           bOutFlag=TRUE;       // bOutFalgTRUE로 만들고

                           // Enable PWM output, PWM 출력을 동작시킴

                           PCA_SetPWM0_EnOutput();                                     

                           PCA_SetPWM1_EnOutput();

                           PCA_SetPWM2_EnOutput();

                           PCA_SetPWM3_EnOutput();

                           PCA_SetPWM4_EnOutput();

                           PCA_SetPWM5_EnOutput();

                  }

        }

        else                                                         // P10에 연결된 버튼이 눌렸으면

        {

                  if(bOutFlag==TRUE)                             // bOutFlagTRUE 일 때

                  {

                           bOutFlag=FALSE;                       // bOutFlag FALSE로 만들고

                           // Disable PWM output               // PWM 출력을 Disable 시킨다.

                           PCA_SetPWM0_DisOutput();                                    

                           PCA_SetPWM1_DisOutput();

                           PCA_SetPWM2_DisOutput();

                           PCA_SetPWM3_DisOutput();

                           PCA_SetPWM4_DisOutput();

                           PCA_SetPWM5_DisOutput();

                  }

        }

    }

}

⑵ 시스템 초기화 루틴

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

*Function:   void InitSystem(void)

*Description:           Initialize MCU

*Input:  

*Output:    

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

void InitSystem(void)

{

           InitClock();                // 클럭 설정

           InitPort();                  // 포트 초기화 설정

           InitPCA_PWM()           // PCA PWM 모드 설정

}

- 클럭을 설정한다. 시스템 클럭과 MCU 클럭을 24MHz로 설정한다.

- 포트 입/출력을 설정한다.

- PCA PWM 모드를 설정한다.

 

 

Port 초기화

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

*Function:   void InitPort(void)

*Description:            Initialize IO Port

*Input:  

*Output:    

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

void InitPort(void)

{

           PORT_SetP2PushPull(BIT2|BIT4|BIT6);        // Set P22(CEX0),P24(CEX2),P26(CEX4) as push-pull for PWM output

           PORT_SetP3PushPull(BIT3|BIT4|BIT5);        // Set P33(CEX1),P34(CEX3),P35(CEX5) as push-pull for PWM output

 

           P10=1;

           P11=1;

           PORT_SetP1OpenDrainPu(BIT0|BIT1);          // Set P10 as open-drain with pull-high

}

- P22, P24, P26Push-Pull로 설정해서 PWM 출력을 준비한다.

- P33, P34, P35Push-Pull로 설정해서 PWM 출력을 준비한다.

- P10, P11Pull-Up을 포함함 Open-Drain으로 설정하고 키 입력 포트로 사용한다.

원 소스 예제에는 P10을 사용했으나 앞선 예제에서 P10을 아날로그 입력 포트로 사용하고, P11을 키 입력으로 사용하였기에 P11을 사용하기 위해 추가하였다.

 

 

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

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

 

 

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

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

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

#define        MCU_SYSCLK          24000000

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

#define        MCU_CPUCLK          (MCU_SYSCLK)

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

#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

 

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

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

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

CKCON0.6 : ENCKM, X8 클럭 멀티플라이어를 동작시킴

CKCON0.5~4 : OSCin12MHz이므로 01을 입력한다.

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();

}

 

 

PCA PWM 초기화 루틴

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

*Function:   void InitPCA_PWM(void)

*Description:   Initialize PCA for PWM

*Input:  

*Output: 

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

void InitPCA_PWM(void)

{

           PCA_SetCLOCK_CKMIX16();             // 96MHz(Note:Before use CKMIX16/96MHz,need enable CKM(ENCKM=1) at first)

           PCA_CH0_SetMode_PWM();

           PCA_CH1_SetMode_PWM();

           PCA_CH2_SetMode_PWM();

           PCA_CH3_SetMode_PWM();

           PCA_CH4_SetMode_PWM();

           PCA_CH5_SetMode_PWM();

 

           PCA_CH0_SetPWM_16Bit();

           PCA_CH1_SetPWM_16Bit();

           PCA_CH2_SetPWM_16Bit();

           PCA_CH3_SetPWM_16Bit();

           PCA_CH4_SetPWM_16Bit();

           PCA_CH5_SetPWM_16Bit();

           PCA_CH01_SetPWM_EnBufferMode();                                                     // CH0,CH1 Enable buffer mode

           PCA_CH23_SetPWM_EnBufferMode();                                                     // CH2,CH3 Enable buffer mode

           PCA_CH45_SetPWM_EnBufferMode();                                                     // CH4,CH5 Enable buffer mode

 

           // Set PWM duty

           PCA_CH0_SetValue(PCA_CH(PWM_MIN),PCA_CL(PWM_MIN));

           PCA_CH1_SetValue(PCA_CH(PWM_MIN),PCA_CL(PWM_MIN));

           PCA_CH2_SetValue(PCA_CH(PWM_MIN),PCA_CL(PWM_MIN));

           PCA_CH3_SetValue(PCA_CH(PWM_MIN),PCA_CL(PWM_MIN));       

           PCA_CH4_SetValue(PCA_CH(PWM_MIN),PCA_CL(PWM_MIN));

           PCA_CH5_SetValue(PCA_CH(PWM_MIN),PCA_CL(PWM_MIN));

          

           // Set counter

           PCA_SetCounter(PCA_C-PCA_RELOAD);

           PCA_SetCounterReload(PCA_C-PCA_RELOAD);

 

           // Disable PWM Output

           PCA_SetPWM0_DisOutput();                                            

           PCA_SetPWM1_DisOutput();

           PCA_SetPWM2_DisOutput();

           PCA_SetPWM3_DisOutput();

           PCA_SetPWM4_DisOutput();

           PCA_SetPWM5_DisOutput();

 

           PCA_SetCEX0CEX2CEX4_P22P24P26();                                       // Set CEX0:P22,CEX2:P24,CEX4:P26

 

           PCA_CF_DisInterrupt();                                                                          // Disable CF interrupt

 

           PCA_EnPCACounter();                                                                                    // Eanble PCA counter

}

- PCA clock CKMIX16의 출력으로 설정한다.

#define PCA_SetCLOCK_CKMIX16()                                  CMOD=(CMOD&(~(CPS2|CPS1|CPS0)))|(CPS2)

96MHz를 사용하기 위해서는 CKM을 먼저 Enable 시켜두어야 한다.(ENCKM=1)

 

- PWM 모드 설정

#define PCA_CHn_SetMode_PWM()                                            CCAPM0=ECOM0|PWM0      

CCAPMn 레지스터의 ECOMn을 셋 시켜서 디지털 컴패래터 기능을 Enable 시키고, PWMn을 셋 시켜서 PWM 기능을 Enable 시키고, CEXn핀이 PWM 출력 핀으로 사용되도록 한다.

 

- PWM16비트로 설정함

#define PCA_CHn_SetPWM_16Bit()                                              PCAPWM0=PCAPWM0|((P0RS0|P0RS1))

PCAPWMn(PWM 모드 보조 레지스터)PnRS1, PnRS0를 이용하여 8, 10,12, 16 비트의 길이를 조절할 수 있다.

16 비트이므로 PnRS1, PnRS0를 모두 셋 시킨다.

 

- Buffer Mode 설정

#define PCA_CH01_SetPWM_EnBufferMode()                                         CMOD=CMOD|BME0

#define PCA_CH23_SetPWM_EnBufferMode()                                         CMOD=CMOD|BME2

#define PCA_CH45_SetPWM_EnBufferMode()                                         CMOD=CMOD|BME4

BME0, 2, 4를 셋 시켜서 CH0, CH1, CH2, CH3, CH4, CH5 모두 버퍼 모드로 동작하도록 한다.

PWM의 듀티를 변화 시키기 위해서는 CCAPnH, CCAPnL 두 개의 레지스터 데이터를 바꿔야 하는데 8bit MCU는 한 번에 한 바이트만 라이팅이 가능하다. 만약 버퍼 모드를 사용하지 않으면 먼저 라이팅한 한 바이트 때문에 잠시 듀티가 원하지 않는 값을 가질 수 있다.

그래서 버퍼모드를 사용해서 그런 에러를 방지한다.

n=1, 3, 5인 레지스터는 버퍼로 사용되고 리로드 시그널이 발생하면 n=0, 2, 4 레지스터에 저장한다. 그리고 이 레지스터가 실제 듀티를 계산하는데 사용된다.

- Duty 설정

#define PCA_CHn_SetValue(x,y)

           AUXR2=AUXR2|(CnPLK);

if((x==0)&&(y==0)){PCAPWMn=PCAPWMn|0x03;}

else{CCAPnL=y;CCAP0H=x;PCAPWMn=PCAPWMn&(~0x03);};

AUXR2=AUXR2&(~C0PLK)               // 0 0,1

C0PLK를 셋 시켜 주어 PWM/COMP의 버퍼 자동 업데이트가 되지 않도록 한다.

입력된 데이터의 두 값이 모두 0이면 9비트로 레지스터를 확장시켜서, PWM 모드에서 CCAPnH9비트 레지스터로 바꾼다.

입력된 데이터의 두 값이 모두 0이면 9비트로 레지스터를 확장시켜서, PWM 모드에서 CCAPnL9비트 레지스터로 바꾼다.

CCAPnL, CCAPnH에 각각의 값들을 저장하고, 9비트째 데이터는 클리어시킨다.

설정 값 저장 후 다시 버퍼 자동 업데이트가 되도록 해당 비트를 클리어 시킨다.

 

- PCA 카운터 초기값 및 리로드될 값 저장

#define PCA_SetCounter(x)                                            CH=HIBYTE(x);CL=LOBYTE(x)

#define PCA_SetCounterReload(x)                                  CHRL=HIBYTE(x);CLRL=LOBYTE(x)

PCA 카운터에 초기 값을 저장하고, 리로드 될 값들도 저장한다.

 

- Disable PCA Output

#define PCA_SetPWMn_DisOutput()                                            PAOE=PAOE&(~POEn)

#define PCA_SetPWM4_DisOutput()                                            SFRPI=4;AUXR7=AUXR7&(~POE4);SFRPI=0

#define PCA_SetPWM5_DisOutput()                                            SFRPI=4;AUXR7=AUXR7&(~POE5);SFRPI=0

PAOE레지스터의 POEn AUXR7 레지스터의 POE4, POE5PWM파형이 해당 출력 핀으로 연결되는 것을 보조적으로 제어한다.

기본 Enable이므로 필요 없을 때에는 Disable 시켜준다.

 

- P22, P24, P26 CEX0, CEX2, CEX4로 설정

#define PCA_SetCEX0CEX2CEX4_P22P24P26()                 SFRPI=2;AUXR5=AUXR5&(~C0PS0);SFRPI=0

 

 

- CF 비트에 의한 인터럽트가 발생하지 않도록 함.

#define PCA_CF_DisInterrupt()                                         CMOD=CMOD&(~(ECF))

PCA 타이머는 단순 카운트만 되도록 하고, 인터럽트는 발생하지 않도록 한다.

 

- PCA 카운터 동작 시작

#define          PCA_EnPCACounter()                                           CR=1

준비가 다 되면 PCA 카운터를 시작시킨다.

 

4. 프로그램 실행

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

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

\Megawin 8051\(EN)MG82F6D16_SampleCode_v1.20\ MG82F6D16_PCA_PWM_16bit\KeilPrj

 

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

 

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

 

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

 

 

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

5. 동작 영상

 

https://youtu.be/5i_Gw9fFDMQ

 

반응형