해보기는 했어?

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

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

 

반응형

'MEGAWIN' 카테고리의 다른 글

MG82F6D Series UART0 TX RX INT  (0) 2022.12.02
MG82F6D Series RTC Timer  (0) 2022.12.01
MG82F6D Series PCA Timer 16bit  (0) 2022.11.29
MG82F6D Series BOD  (0) 2022.11.28
MG82F6D Series INT nINTx Wake UP  (0) 2022.11.25