해보기는 했어?

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

MEGAWIN

MG82F6D Series PCA COPM Buf

롬돌이 2022. 12. 21. 11:02
반응형

1. 프로그램 개요

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

PWM match 모드에서의 비교 출력은 고속 출력 모드와 비슷하다. 그러나 고정된 16비트 비교기 대신에 PCA0 PWM 비교기 들을 사용한다. 어플리케이션에 좀 더 유연하게 사용될 수 있다. 예를 들어 PCA0 비교기에 대해 8비트 PWM이 사용되면 출력 토글 주파수는 고속 출력 모드보다 더 높을 수 있다.

 

어플리케이션에서 PWM 시그널의 어떤 위상 제어가 필요하다면, PCA0모듈들을 버퍼된 비교 모드로 설정할 필요가 있다. PCA0 모듈들의 한 짝(n=0&1, 2&3, 4&5)PWM 시그널의 한 사이클의 두 엣지의 시간 딜레이로 프로그램 될 수 있다. 이것은 파형의 시작과 끝을 지정할 수 있다는 것을 의미한다. 이것은 2~3개의 PWM 시그널이 서로간 위상 변이가 설정되어야 할 때 유용하다.

 

2. 회로도

3. Code

main routine

void main()

{

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

           LED_G_1=0;                                                  // LED_G_1 ON

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

           LED_G_1=1;                                                  // LED_G_1 OFF

           C0Duty=0x00;                                               // C0Duty 0x00으로 초기화

           C2Duty=0x00;                                               // C2Duty 0x00으로 초기화

           while(1)

           {

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

                     LED_G_1=!LED_G_1;                              // LED_G_1 토글

                     C0Duty=C0Duty+0x10;                          // C0Duty0x10을 더한다.

                     C2Duty=C2Duty+0x20;                          // C2Duty0x20을 더한다.

                     PCA_CH0_SetValue_H(C0Duty);                 // CH0의 상위 바이트 값 수정

                     PCA_CH2_SetValue_H(C2Duty);                 // CH2의 상위 바이트 값 수정

}

}

 

 

 

 

⑵ 시스템 초기화 루틴

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

*Function:   void InitSystem(void)

*Description:           Initialize MCU

*Input:  

*Output:    

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

void InitSystem(void)

{

           InitClock();

           InitPort();

           InitPCA();

}

- 클럭 초기화(시스템 클럭 12MHz)

- 포트 설정 수행한다.

- PCA 초기화

 

 

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

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

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

}

 

 

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 type로 설정한다.

}

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

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

PCA COPM Buffer 모드 초기화

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

*Function:   void InitPCA_COPM_Buffer(void)

*Description:           Initialize PCA for COPM Buffer

*Input:  

*Output:    

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

void InitPCA(void)

{

           PCA_SetCLOCK_SYSCLK();                                                                              // PCA clock: SysClk = 12MHz

          

           PCA_CH0_SetMode_COPM();                                                                           // set CH0 for COPM mode

           PCA_CH1_SetMode_COPM();                                                                           // set CH1 for COPM mode

           PCA_CH2_SetMode_COPM();                                                                           // set CH2 for COPM mode

           PCA_CH3_SetMode_COPM();                                                                           // set CH3 for COPM mode

 

           PCA_CH0_SetPWM_8Bit();     

           PCA_CH1_SetPWM_8Bit();     

           PCA_CH2_SetPWM_8Bit();     

           PCA_CH3_SetPWM_8Bit();     

 

           PCA_CH01_SetPWM_EnBufferMode();

           PCA_CH23_SetPWM_EnBufferMode();

 

           PCA_SetCounter(0);

           PCA_SetCounterReload(0);

 

           PCA_CH0_SetValue_L(0x40);

           PCA_CH0_SetValue_H(0x40);

           PCA_CH1_SetValue_L(0x40);

           PCA_CH1_SetValue_H(0x40);

 

           PCA_CH2_SetValue_L(0x20);

           PCA_CH2_SetValue_H(0x20);

           PCA_CH3_SetValue_L(0x20);

           PCA_CH3_SetValue_H(0x20);

 

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

 

           PCA_SetPWM0_EnOutput();                                                                             // enable CEX0 PWM0 output

           PCA_SetPWM2_EnOutput();                                                                             // enable CEX2 PWM2 output

          

           PCA_EnPCACounter();                                                                                               // Enable PCA counter

}

 

- PCA 클럭 설정

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

CMOD 레지스터의 CPS2, CPS0 비트를 셋 시켜 SYSTEM CLOCKPCA의 클럭으로 설정한다.

 

- CH0~3 까지 COPM 모드로 설정

#define PCA_CH0_SetMode_COPM()                                           CCAPM0=ECOM0|PWM0|TOG0          

#define PCA_CH1_SetMode_COPM()                                           CCAPM1=ECOM1|PWM1|TOG1          

#define PCA_CH2_SetMode_COPM()                                           CCAPM2=ECOM2|PWM2|TOG2          

#define PCA_CH3_SetMode_COPM()                                           CCAPM3=ECOM3|PWM3|TOG3          

CCAPMn 레지스터의 ECOMn, PWMn, TOGn 비트를 셋 시킨다.

ECOMn : 디지털 비교기 기능을 동작시킴

PWMn : PWM 기능을 동작시키고, CEXn 핀을 PWM 출력 핀으로 사용하도록 설정

TOGn : PCA0 카운터의 값과 해당 모듈의 비교/캡쳐 레지스터의 값이 동일하면 CEXn 핀이 토글되도록 함

 

- CH0~3까지 8bit PWM 채널로 설정

#define PCA_CH0_SetPWM_8Bit()                                                PCAPWM0=PCAPWM0&(~(P0RS0|P0RS1))

#define PCA_CH1_SetPWM_8Bit()                                                PCAPWM1=PCAPWM1&(~(P1RS0|P1RS1))

#define PCA_CH2_SetPWM_8Bit()                                                PCAPWM2=PCAPWM0&(~(P2RS0|P2RS1))

#define PCA_CH3_SetPWM_8Bit()                                                PCAPWM3=PCAPWM0&(~(P3RS0|P3RS1))

PCAPWMn 레지스터의 PnRS1, PnRS0 비트를 모두 클리어 시켜 “8 bit PWMn”으로 설정한다.

오버플로우는 CL 카운트가 0xFF에서 0x00으로 될 때 발생한다.

 

- 01, 23을 각각 PWM 버퍼모드로 설정

#define PCA_CH01_SetPWM_EnBufferMode()                                         CMOD=CMOD|BME0

#define PCA_CH23_SetPWM_EnBufferMode()                                         CMOD=CMOD|BME2

CMOD레지스터의 BME0, BME2 비트를 셋 시켜 버퍼 모드로 설정한다.

 

- PCA0 카운터 값을 0x00으로 설정하고, 리로드 될 값도 0x00으로 설정한다.

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

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

 

- PCA0 모듈n의 캡쳐 레지스터 값 정의

#define PCA_CH0_SetValue_L(x)                                                 CCAP0L=x                        // 0

#define PCA_CH0_SetValue_H(x)                                                CCAP0H=x                                      // 0

PCA_CH0_SetValue_L(0x40);

PCA_CH0_SetValue_H(0x40);

PCA_CH1_SetValue_L(0x40);

PCA_CH1_SetValue_H(0x40);

 

PCA_CH2_SetValue_L(0x20);

PCA_CH2_SetValue_H(0x20);

PCA_CH3_SetValue_L(0x20);

PCA_CH3_SetValue_H(0x20);

 

- P22, P24, P26CEX0, CEX2, CEX4로 설정

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

 

- PWM0, PWM2 출력 연결

#define PCA_SetPWM0_EnOutput()                                             PAOE=PAOE|(POE0)

#define PCA_SetPWM2_EnOutput()                                             PAOE=PAOE|(POE2)

CEX0, CEX2의 핀을 연결시킴

 

- PCA counter 동작 시작

#define          PCA_EnPCACounter()                                           CR=1

 

 

 

* 프로그램의 동작은 CH0CCAP0L의 값과 CL의 값이 같을 때(match) CEX0High가 되고, CH1CCAP1L의 값과 CL의 값이 같을 때(match) CEX0Low가 된다. 각각 CCAP0HCCAP1H CLOverflow일 때 각각 CCAP0LCCAP1L에 재적재 된다.

** 이 내용은 데이터 시트 상에 자세히 설명되어 있지는 않음.

*** MG82F6D16 데이터시트의 Figure 16-13. PCA0 Buffered COPM Mode 다이어그램은 수정이 되어야 할 것으로 보임

 

 

 

 

 

 

4. 프로그램 실행

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

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

\Megawin 8051\(EN)MG82F6D16_SampleCode_v1.20\ MG82F6D16_I2C_Slave_Int\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/kMWbi-zJXqU

 

 

* 영상의 파형 설명(파란색 CEX0, 노란색 CEX2)

CH0 Set Value : 0x20

CH1 Set Value : 0x60

 

 

 

 

 

 

 

반응형

'MEGAWIN' 카테고리의 다른 글

MG82F6D SPI Flash-2  (0) 2022.12.22
MG82F6D SPI Flash-1  (0) 2022.12.22
MG82F6D Series PCA Capture Buf  (0) 2022.12.20
MG82F6D Series INT KBI Wake UP  (0) 2022.12.19
MG82F6D Series IAP Sample  (0) 2022.12.16