예제 #1
0
파일: main.c 프로젝트: brucetsao/Nuvoton
/*---------------------------------------------------------------------------------------------------------*/
int32_t main(void)
{
    /* Init System, IP clock and multi-function I/O
       In the end of SYS_Init() will issue SYS_LockReg()
       to lock protected register. If user want to write
       protected register, please issue SYS_UnlockReg()
       to unlock protected register if necessary */

    /* Unlock protected registers */
    SYS_UnlockReg();

    /* Init System, IP clock and multi-function I/O */
    SYS_Init();

    /* Lock protected registers */
    SYS_LockReg();

    /* Init UART to 115200-8n1 for print message */
    UART0_Init();

    printf("\n\nCPU @ %dHz(PLL@ %dHz)\n", SystemCoreClock, PllClock);
    printf("PWM1 clock is from %s\n", (CLK->CLKSEL2 & CLK_CLKSEL2_PWM1SEL_Msk) ? "CPU" : "PLL");
    printf("+------------------------------------------------------------------------+\n");
    printf("|                          PWM Driver Sample Code                        |\n");
    printf("|                                                                        |\n");
    printf("+------------------------------------------------------------------------+\n");
    printf("  This sample code will use PWM1 channel 2 to capture the signal from PWM1 channel 0.\n");
    printf("  And the captured data is transferred by PDMA channel 0.\n");
    printf("  I/O configuration:\n");
    printf("    PWM1 channel 2(PC.11) <--> PWM1 channel 0(PC.6)\n\n");
    printf("Use PWM1 Channel 2(PC.11) to capture the PWM1 Channel 0(PC.6) Waveform\n");

    while(1)
    {
        printf("\n\nPress any key to start PWM Capture Test\n");
        getchar();

        /*--------------------------------------------------------------------------------------*/
        /* Set the PWM1 Channel 0 as PWM output function.                                       */
        /*--------------------------------------------------------------------------------------*/

        /* Assume PWM output frequency is 1500Hz and duty ratio is 30%, user can calculate PWM settings by follows.
           duty ratio = (CMR+1)/(CNR+1)
           cycle time = CNR+1
           High level = CMR+1
           PWM clock source frequency = PLL = 72000000
           (CNR+1) = PWM clock source frequency/prescaler/PWM output frequency
                   = 72000000/2/1500 = 24000
           (Note: CNR is 16 bits, so if calculated value is larger than 65536, user should increase prescale value.)
           CNR = 23999
           duty ratio = 30% ==> (CMR+1)/(CNR+1) = 30%
           CMR = 7199
           Prescale value is 1 : prescaler= 2
        */

        /*Set counter as down count*/
        PWM1->CTL1 = (PWM1->CTL1 & ~PWM_CTL1_CNTTYPE0_Msk) | 0x1;

        /*Set PWM Timer clock prescaler*/
        PWM_SET_PRESCALER(PWM1, 0, 1); // Divided by 2

        /*Set PWM Timer duty*/
        PWM_SET_CMR(PWM1, 0, 7199);

        /*Set PWM Timer period*/
        PWM_SET_CNR(PWM1, 0, 23999);

        /* Set waveform generation */
        PWM1->WGCTL0 = 0x00010000;
        PWM1->WGCTL1 = 0x00020000;

        /* Enable PWM Output path for PWM1 channel 0 */
        PWM1->POEN |= PWM_CH_0_MASK;

        /* Enable Timer for PWM1 channel 0 */
        PWM1->CNTEN |= PWM_CH_0_MASK;

        /*--------------------------------------------------------------------------------------*/
        /* Configure PDMA peripheral mode form PWM to memory                                    */
        /*--------------------------------------------------------------------------------------*/
        /* Open Channel 0 */
        PDMA->CHCTL |= 0x1;
        PDMA->DSCT[0].CTL &= ~(PDMA_DSCT_CTL_TXCNT_Msk | PDMA_DSCT_CTL_TXWIDTH_Msk);

        /* transfer width is half word(16 bit) and transfer count is 4 */
        PDMA->DSCT[0].CTL |= ((0x1 << PDMA_DSCT_CTL_TXWIDTH_Pos) | ((4 - 1) << PDMA_DSCT_CTL_TXCNT_Pos));

        /* Set source address as PWM capture channel PDMA register(no increment) and destination address as g_u32Count array(increment) */
        PDMA->DSCT[0].SA = (uint32_t)&PWM1->PDMACAP2_3;
        PDMA->DSCT[0].DA = (uint32_t)&g_u32Count[0];
        PDMA->DSCT[0].CTL &= ~(PDMA_DSCT_CTL_SAINC_Msk | PDMA_DSCT_CTL_DAINC_Msk);
        PDMA->DSCT[0].CTL |= ((0x3 << PDMA_DSCT_CTL_SAINC_Pos) | (0x2 << PDMA_DSCT_CTL_DAINC_Pos));

        /* Select PDMA request source as PWM RX(PWM1 channel 2 should be PWM1 pair 2) */
        PDMA->REQSEL0_3 = (PDMA->REQSEL0_3 & ~PDMA_REQSEL0_3_REQSRC0_Msk) | (0xF << PDMA_REQSEL0_3_REQSRC0_Pos);

        /* Select PDMA operation mode as basic mode */
        PDMA->DSCT[0].CTL = (PDMA->DSCT[0].CTL & ~PDMA_DSCT_CTL_OPMODE_Msk) | 0x1;

        /* Set PDMA as single request type for PWM */
        PDMA->DSCT[0].CTL = (PDMA->DSCT[0].CTL & ~(PDMA_DSCT_CTL_TXTYPE_Msk)) | (0x1 << PDMA_DSCT_CTL_TXTYPE_Pos);
        
        PDMA->INTEN |= (1 << 0);
        NVIC_EnableIRQ(PDMA_IRQn);

        /* Enable PDMA for PWM1 channel 2 capture function, and set capture order as falling first */
        PWM1->PDMACTL &= ~(PWM_PDMACTL_CHSEL2_3_Msk | PWM_PDMACTL_CAPORD2_3_Msk);
        
        /* Select capture mode as both rising and falling to do PDMA transfer */
        PWM1->PDMACTL |= (PWM_PDMACTL_CAPMOD2_3_Msk | PWM_PDMACTL_CHEN2_3_Msk);

        /*--------------------------------------------------------------------------------------*/
        /* Set the PWM1 channel 2 for capture function                                          */
        /*--------------------------------------------------------------------------------------*/

        /* If input minimum frequency is 1500Hz, user can calculate capture settings by follows.
           Capture clock source frequency = PLL = 72000000 in the sample code.
           (CNR+1) = Capture clock source frequency/prescaler/minimum input frequency
                   = 72000000/2/1500 = 24000
           (Note: CNR is 16 bits, so if calculated value is larger than 65536, user should increase prescale value.)
           CNR = 0xFFFF
           (Note: In capture mode, user should set CNR to 0xFFFF to increase capture frequency range.)
        */

        /*Set counter as down count*/
        PWM1->CTL1 = (PWM1->CTL1 & ~PWM_CTL1_CNTTYPE2_Msk) | (0x1 << PWM_CTL1_CNTTYPE2_Pos);

        /*Set PWM1 channel 2 Timer clock prescaler*/
        PWM_SET_PRESCALER(PWM1, 2, 1); // Divided by 2

        /*Set PWM1 channel 2 Timer period*/
        PWM_SET_CNR(PWM1, 2, 0xFFFF);

        /* Enable capture function */
        PWM1->CAPCTL |= PWM_CAPCTL_CAPEN2_Msk;

        /* Enable falling capture reload */
        PWM1->CAPCTL |= PWM_CAPCTL_FCRLDEN2_Msk;

        // Start
        PWM1->CNTEN |= PWM_CNTEN_CNTEN2_Msk;

        /* Wait until PWM1 channel 2 Timer start to count */
        while((PWM1->CNT[2]) == 0);

        /* Enable capture input path for PWM1 channel 2 */
        PWM1->CAPINEN |= PWM_CAPINEN_CAPINEN2_Msk;

        /* Capture the Input Waveform Data */
        //CalPeriodTime(PWM1, 2);
        CalPeriodTime();
        /*---------------------------------------------------------------------------------------------------------*/
        /* Stop PWM1 channel 0 (Recommended procedure method 1)                                                    */
        /* Set PWM Timer loaded value(Period) as 0. When PWM internal counter(CNT) reaches to 0, disable PWM Timer */
        /*---------------------------------------------------------------------------------------------------------*/

        /* Set PWM1 channel 0 loaded value as 0 */
        PWM1->PERIOD[0] = 0;

        /* Wait until PWM1 channel 0 Timer Stop */
        while((PWM1->CNT[0] & PWM_CNT_CNT_Msk) != 0);

        /* Disable Timer for PWM1 channel 0 */
        PWM1->CNTEN &= ~PWM_CNTEN_CNTEN0_Msk;

        /* Disable PWM Output path for PWM1 channel 0 */
        PWM1->POEN &= ~PWM_CH_0_MASK;

        /*---------------------------------------------------------------------------------------------------------*/
        /* Stop PWM1 channel 2 (Recommended procedure method 1)                                                    */
        /* Set PWM Timer loaded value(Period) as 0. When PWM internal counter(CNT) reaches to 0, disable PWM Timer */
        /*---------------------------------------------------------------------------------------------------------*/

        /* Disable PDMA NVIC */
        NVIC_DisableIRQ(PDMA_IRQn);

        /* Set loaded value as 0 for PWM1 channel 2 */
        PWM1->PERIOD[2] = 0;

        /* Wait until PWM1 channel 2 current counter reach to 0 */
        while((PWM1->CNT[2] & PWM_CNT_CNT_Msk) != 0);

        /* Disable Timer for PWM1 channel 2 */
        PWM1->CNTEN &= ~PWM_CNTEN_CNTEN2_Msk;

        /* Disable Capture Function and Capture Input path for  PWM1 channel 2*/
        PWM1->CAPCTL &= ~PWM_CAPCTL_CAPEN2_Msk;
        PWM1->CAPINEN &= ~PWM_CAPINEN_CAPINEN2_Msk;

        /* Clear Capture Interrupt flag for PWM1 channel 2 */
        PWM1->CAPIF = PWM_CAPIF_CFLIF2_Msk;

        PDMA->CHCTL = 0;
    }
}
예제 #2
0
파일: main.c 프로젝트: lsffrank/switch
/*---------------------------------------------------------------------------------------------------------*/
int32_t main (void)
{   
    uint8_t u8Item;
    int32_t i32Loop = 1;
    int32_t i32TestLoop = 1;
                                    
    /* Init System, IP clock and multi-function I/O */
    SYS_Init(); //In the end of SYS_Init() will issue SYS_LockReg() to lock protected register. If user want to write protected register, please issue SYS_UnlockReg() to unlock protected register.    

    /* Init UART0 for printf */
    UART0_Init();   
             
    printf("+------------------------------------------------------------------------+\n");
    printf("|                          PWM Driver Sample Code                        |\n");
    printf("|                                                                        |\n");
    printf("+------------------------------------------------------------------------+\n");                    
    printf("  This sample code will use PWMB channel 0 to drive Buzzer or use PWMB channel 2 to capture\n  the signal from PWMB channel 1.\n");
    printf("  I/O configuration:\n");
    printf("    PWM4(P2.4 PWMB channel 0) <--> Buzzer\n");
    printf("    PWM5(P2.5 PWMB channel 1) <--> PWM6(P2.6 PWMB channel 2)\n\n");
    
    while (i32Loop)
    {       
        printf("\n  Please Select Test Item\n");
        printf("    0 : Exit\n");          
        printf("    1 : PWM Timer Waveform Test.\n");
        printf("    2 : PWM Caputre Test\n");
          
        u8Item = getchar();
    
        switch (u8Item)
        {
            case '0':
            {
                i32Loop = 0;
                break;          
            }                      
            case '1':       
            {           
                uint8_t u8ItemOK;       
                
                printf("\nPWM Timer Waveform Test. Waveform output(P2.4 PWMB channel 0) to Buzzer\n");  
                /* P2.4 PWMB channel 0 generates PWM frequency Do - Si */
                    
                i32TestLoop = 1; 
                                
                printf("Select Test Item\n");  
                printf(" 1: Do (523Hz)Tenor C\n");
                printf(" 2: Re (587Hz)\n");
                printf(" 3: Mi (659Hz)\n");
                printf(" 4: Fa (698Hz)\n");
                printf(" 5: Sol(784Hz) \n");
                printf(" 6: La (880Hz)\n");
                printf(" 7: Si (988Hz)\n");
                printf(" 0: Exit\n");   
                                            
                while (i32TestLoop)
                {                   
                    u8ItemOK = 1;
                    u8Item = getchar();                         
                                          
                    switch (u8Item)
                    {
                        case '1':
                        case '2':
                        case '3':
                        case '4':
                        case '5':
                        case '6':
                        case '7':
                            g_u16Frequency = g_au16ScaleFreq[(u8Item-'1')];
                            break;  
                        case '0':
                            i32TestLoop = 0;
                            break;      
                        default:
                            u8ItemOK = 0;
                            break;                                                                                                                                                                                                                                  
                    }
                        
                    if (i32TestLoop && u8ItemOK)
                    {
                        g_u32Pulse = 0;
                        g_u8PWMCount = 1;                                                                              

                    /* Assume PWM output frequency is 523Hz and duty ratio is 60%, user can calculate PWM settings by follows.
                       duty ratio = (CMR+1)/(CNR+1)
                       cycle time = CNR+1
                       High level = CMR+1
                       PWM clock source frequency = __XTAL = 12000000
                       (CNR+1) = PWM clock source frequency/prescaler/clock source divider/PWM output frequency 
                               = 12000000/2/1/523 = 11472 
                       (Note: CNR is 16 bits, so if calculated value is larger than 65536, user should increase prescale value.)
                       CNR = 11471
                       duty ratio = 60% ==> (CMR+1)/(CNR+1) = 60% ==> CMR = (CNR+1)*0.6-1 = 11472*60/100-1
                       CMR = 6882
                       Prescale value is 1 : prescaler= 2
                       Clock divider is PWM_CSR_DIV1 : clock divider =1             
                    */                                                                 
                        /*Set Pwm mode*/
                        _PWM_SET_TIMER_AUTO_RELOAD_MODE(PWMB,PWM_CH0);  
                            
                        /*Set PWM Timer clock prescaler*/
                        _PWM_SET_TIMER_PRESCALE(PWMB,PWM_CH0, 1); // Divided by 2  
                                                 
                        /*Set PWM Timer clock divider select*/
                        _PWM_SET_TIMER_CLOCK_DIV(PWMB,PWM_CH0,PWM_CSR_DIV1); 
        
                        /*Set PWM Timer duty*/
                        PWMB->CMR0 = g_au16ScaleCmr[(u8Item-'1')];
                                            
                        /*Set PWM Timer period*/
                        PWMB->CNR0 = g_au16ScaleCnr[(u8Item-'1')];
                            
                        /* Enable PWM Output pin */
                        _PWM_ENABLE_PWM_OUT(PWMB, PWM_CH0); 

                        /* Enable Timer period Interrupt */
                        _PWM_ENABLE_TIMER_PERIOD_INT(PWMB, PWM_CH0);
                        
                        /* Enable PWMB NVIC */
                        NVIC_EnableIRQ((IRQn_Type)(PWMB_IRQn)); 
                                                            
                        /* Enable PWM Timer */
                        _PWM_ENABLE_TIMER(PWMB, PWM_CH0); 
                                
                        while (g_u8PWMCount);   
                                                            
                        /*--------------------------------------------------------------------------------------*/
                        /* Stop PWM Timer (Recommended procedure method 2)                                      */
                        /* Set PWM Timer counter as 0, When interrupt request happen, disable PWM Timer         */          
                        /* Set PWM Timer counter as 0 in Call back function                                     */                              
                        /*--------------------------------------------------------------------------------------*/                          

                        /* Disable PWMB NVIC */
                        NVIC_DisableIRQ((IRQn_Type)(PWMB_IRQn)); 

                        /* Wait until PWMB channel 0 Timer Stop */                         
                        while(PWMB->PDR0!=0);
                                                                                        
                        /* Disable the PWM Timer */
                        _PWM_DISABLE_TIMER(PWMB, PWM_CH0); 
                        
                        /* Disable PWM Output pin */
                        _PWM_DISABLE_PWM_OUT(PWMB, PWM_CH0);                         
                    }
                }   
                break;
            }  
            
            case '2':
            {
                printf("PWM Capture Test\n");
                printf("Use PWMB Channel 2(P2.6) to capture the PWMB Channel 1(P2.5) Waveform\n");       

                /*--------------------------------------------------------------------------------------*/
                /* Set the PWMB Channel 1 as PWM output function.                                               */
                /*--------------------------------------------------------------------------------------*/             

                /* Assume PWM output frequency is 250Hz and duty ratio is 30%, user can calculate PWM settings by follows.
                   duty ratio = (CMR+1)/(CNR+1)
                   cycle time = CNR+1
                   High level = CMR+1
                   PWM clock source frequency = __XTAL = 12000000
                   (CNR+1) = PWM clock source frequency/prescaler/clock source divider/PWM output frequency 
                           = 12000000/2/1/250 = 24000
                   (Note: CNR is 16 bits, so if calculated value is larger than 65536, user should increase prescale value.)
                   CNR = 23999
                   duty ratio = 30% ==> (CMR+1)/(CNR+1) = 30%
                   CMR = 7199
                   Prescale value is 1 : prescaler= 2
                   Clock divider is PWM_CSR_DIV1 : clock divider =1                  
                */                  
                /*Set Pwm mode*/
                _PWM_SET_TIMER_AUTO_RELOAD_MODE(PWMB,PWM_CH1);  
                    
                /*Set PWM Timer clock prescaler*/
                _PWM_SET_TIMER_PRESCALE(PWMB,PWM_CH1, 1); // Divided by 2  
                                         
                /*Set PWM Timer clock divider select*/
                _PWM_SET_TIMER_CLOCK_DIV(PWMB,PWM_CH1,PWM_CSR_DIV1); 

                /*Set PWM Timer duty*/
                PWMB->CMR1 = 7199;
                                    
                /*Set PWM Timer period*/
                PWMB->CNR1 = 23999;
                                                                                                                  
                /* Enable PWM Output path for PWMB channel 1 */
                _PWM_ENABLE_PWM_OUT(PWMB, PWM_CH1);
                                                        
                /* Enable Timer for PWMB channel 1 */ 
                _PWM_ENABLE_TIMER(PWMB, PWM_CH1);
                    
                /*--------------------------------------------------------------------------------------*/
                /* Set the PWMB channel 2  for capture function                                         */
                /*--------------------------------------------------------------------------------------*/                  
                
                /* If input minimum frequency is 250Hz, user can calculate capture settings by follows.
                   Capture clock source frequency = __XTAL = 12000000 in the sample code.
                   (CNR+1) = Capture clock source frequency/prescaler/clock source divider/minimum input frequency 
                           = 12000000/2/1/250 = 24000
                   (Note: CNR is 16 bits, so if calculated value is larger than 65536, user should increase prescale value.)
                   CNR = 0xFFFF
                   (Note: In capture mode, user should set CNR to 0xFFFF to increase capture frequency range.)  
                */                                
                /*Set Pwm mode*/
                _PWM_SET_TIMER_AUTO_RELOAD_MODE(PWMB,PWM_CH2);  
                    
                /*Set PWM Timer clock prescaler*/
                _PWM_SET_TIMER_PRESCALE(PWMB,PWM_CH2, 1); // Divided by 2  
                                         
                /*Set PWM Timer clock divider select*/
                _PWM_SET_TIMER_CLOCK_DIV(PWMB,PWM_CH2,PWM_CSR_DIV1); 
                                
                /*Set PWM Timer loaded value*/
                PWMB->CNR2 = 0xFFFF;
                                                    
                /* Enable capture falling edge interrupt for PWMB channel 2 */
                _PWM_ENABLE_CAP_FALLING_INT(PWMB, PWM_CH2);
                
                /* Enable PWMB NVIC interrupt */
                NVIC_EnableIRQ((IRQn_Type)(PWMB_IRQn)); 

                /* Enable Capture Function for PWMB channel 2 */
                _PWM_ENABLE_CAP_FUNC(PWMB, PWM_CH2);

                /* Enable Timer for PWMB channel 2  */
                _PWM_ENABLE_TIMER(PWMB, PWM_CH2);
                
                /* Wait until PWMB channel 2 Timer start to count */
                while(PWMB->PDR2==0);
                                                
                /* Enable capture input path for PWMB channel 2 */
                _PWM_ENABLE_CAP_IN(PWMB, PWM_CH2);
                                        
                /* Capture the Input Waveform Data */
                CalPeriodTime(PWMB, PWM_CH2);                           
                /*------------------------------------------------------------------------------------------------------*/
                /* Stop PWMB channel 1 (Recommended procedure method 1)                                                 */
                /* Set PWM Timer loaded value(CNR) as 0. When PWM internal counter(PDR) reaches to 0, disable PWM Timer */                  
                /*------------------------------------------------------------------------------------------------------*/                  
                                    
                /* Set PWMB channel 1 loaded value as 0 */
                PWMB->CNR1 =0;

                /* Wait until PWMB channel 1 Timer Stop */                         
                while(PWMB->PDR1!=0);
                        
                /* Disable Timer for PWMB channel 1 */    
                _PWM_DISABLE_TIMER(PWMB, PWM_CH1);
                             
                /* Disable PWM Output path for PWMB channel 1 */
                _PWM_DISABLE_PWM_OUT(PWMB, PWM_CH1);
                
                /*------------------------------------------------------------------------------------------------------*/
                /* Stop PWMB channel 2 (Recommended procedure method 1)                                                 */
                /* Set PWM Timer loaded value(CNR) as 0. When PWM internal counter(PDR) reaches to 0, disable PWM Timer */                
                /*------------------------------------------------------------------------------------------------------*/                              

                /* Disable PWMB NVIC */
                NVIC_DisableIRQ((IRQn_Type)(PWMB_IRQn)); 
                                        
                /* Set loaded value as 0 for PWMB channel 2 */
                PWMB->CNR2 =0;
                
                /* Wait until PWMB channel 2 current counter reach to 0 */
                while(PWMB->PDR2!=0);

                /* Disable Timer for PWMB channel 2 */  
                _PWM_DISABLE_TIMER(PWMB, PWM_CH2);
                
                /* Disable Capture Function for  PWMB channel 2*/
                _PWM_DISABLE_CAP_FUNC(PWMB, PWM_CH2);
                                    
                /* Clear Capture Interrupt flag for PWMB channel 2*/
                _PWM_CLR_CAP_INT_FLAG(PWMB, PWM_CH2);
                                                                               
                /* Disable Capture Input path for PWMB channel 2 */
                _PWM_DISABLE_CAP_IN(PWMB, PWM_CH2);
                                        
                break;          
            }    
        }           
    }       
    
    printf("PWM sample is complete.\n");

    /* Disable PWMB clock engine */
    SYSCLK->APBCLK&=(~(SYSCLK_APBCLK_PWM45_EN_Msk|SYSCLK_APBCLK_PWM67_EN_Msk));          
    return 0;  
}
예제 #3
0
/*---------------------------------------------------------------------------------------------------------*/
int32_t main(void)
{
    /* Unlock protected registers */
    SYS_UnlockReg();

    /* Init System, IP clock and multi-function I/O */
    SYS_Init();

    /* Lock protected registers */
    SYS_LockReg();

    /* Init UART0 for printf */
    UART0_Init();

    printf("+------------------------------------------------------------------------+\n");
    printf("|                          PWM Driver Sample Code                        |\n");
    printf("|                                                                        |\n");
    printf("+------------------------------------------------------------------------+\n");
    printf("  This sample code will use PWMB channel 2 to capture\n  the signal from PWMB channel 1.\n");
    printf("  I/O configuration:\n");
    printf("    PWM5(P2.5 PWMB channel 1) <--> PWM6(P2.6 PWMB channel 2)\n\n");
    printf("Use PWMB Channel 2(P2.6) to capture the PWMB Channel 1(P2.5) Waveform\n");

    while(1)
    {
        printf("Press any key to start PWM Capture Test\n");
        getchar();

        /*--------------------------------------------------------------------------------------*/
        /* Set the PWMB Channel 1 as PWM output function.                                               */
        /*--------------------------------------------------------------------------------------*/

        /* Assume PWM output frequency is 250Hz and duty ratio is 30%, user can calculate PWM settings by follows.
           duty ratio = (CMR+1)/(CNR+1)
           cycle time = CNR+1
           High level = CMR+1
           PWM clock source frequency = __HXT = 12000000
           (CNR+1) = PWM clock source frequency/prescaler/clock source divider/PWM output frequency
                   = 12000000/2/1/250 = 24000
           (Note: CNR is 16 bits, so if calculated value is larger than 65536, user should increase prescale value.)
           CNR = 23999
           duty ratio = 30% ==> (CMR+1)/(CNR+1) = 30%
           CMR = 7199
           Prescale value is 1 : prescaler= 2
           Clock divider is PWM_CSR_DIV1 : clock divider =1
        */

        /* set PWMB channel 1 output configuration */
        PWM_ConfigOutputChannel(PWMB, PWM_CH1, 250, 30);

        /* Enable PWM Output path for PWMB channel 1 */
        PWM_EnableOutput(PWMB, 0x2);

        /* Enable Timer for PWMB channel 1 */
        PWM_Start(PWMB, 0x2);

        /*--------------------------------------------------------------------------------------*/
        /* Set the PWMB channel 2  for capture function                                         */
        /*--------------------------------------------------------------------------------------*/

        /* If input minimum frequency is 250Hz, user can calculate capture settings by follows.
           Capture clock source frequency = __HXT = 12000000 in the sample code.
           (CNR+1) = Capture clock source frequency/prescaler/clock source divider/minimum input frequency
                   = 12000000/2/1/250 = 24000
           (Note: CNR is 16 bits, so if calculated value is larger than 65536, user should increase prescale value.)
           CNR = 0xFFFF
           (Note: In capture mode, user should set CNR to 0xFFFF to increase capture frequency range.)
        */

        /* set PWMB channel 2 capture configuration */
        PWM_ConfigCaptureChannel(PWMB, PWM_CH2, 166, 0);

        /* Enable capture falling edge interrupt for PWMB channel 2 */
        PWM_EnableCaptureInt(PWMB, PWM_CH2, PWM_CAPTURE_INT_FALLING_LATCH);

        /* Enable PWMB NVIC interrupt */
        NVIC_EnableIRQ((IRQn_Type)(PWMB_IRQn));

        /* Enable Timer for PWMB channel 2  */
        PWM_Start(PWMB, 0x4);

        /* Enable Capture Function for PWMB channel 2 */
        PWM_EnableCapture(PWMB, 0x4);

        /* Wait until PWMB channel 2 Timer start to count */
        while(PWMB->PDR2 == 0);

        /* Capture the Input Waveform Data */
        CalPeriodTime(PWMB, PWM_CH2);
        /*------------------------------------------------------------------------------------------------------*/
        /* Stop PWMB channel 1 (Recommended procedure method 1)                                                 */
        /* Set PWM Timer loaded value(CNR) as 0. When PWM internal counter(PDR) reaches to 0, disable PWM Timer */
        /*------------------------------------------------------------------------------------------------------*/

        /* Set PWMB channel 1 loaded value as 0 */
        PWM_Stop(PWMB, 0x2);

        /* Wait until PWMB channel 1 Timer Stop */
        while(PWMB->PDR1 != 0);

        /* Disable Timer for PWMB channel 1 */
        PWM_ForceStop(PWMB, 0x2);

        /* Disable PWM Output path for PWMB channel 1 */
        PWM_DisableOutput(PWMB, 0x2);

        /*------------------------------------------------------------------------------------------------------*/
        /* Stop PWMB channel 2 (Recommended procedure method 1)                                                 */
        /* Set PWM Timer loaded value(CNR) as 0. When PWM internal counter(PDR) reaches to 0, disable PWM Timer */
        /*------------------------------------------------------------------------------------------------------*/

        /* Disable PWMB NVIC */
        NVIC_DisableIRQ((IRQn_Type)(PWMB_IRQn));

        /* Set loaded value as 0 for PWMB channel 2 */
        PWM_Stop(PWMB, 0x4);

        /* Wait until PWMB channel 2 current counter reach to 0 */
        while(PWMB->PDR2 != 0);

        /* Disable Timer for PWMB channel 2 */
        PWM_ForceStop(PWMB, 0x4);

        /* Disable Capture Function and Capture Input path for  PWMB channel 2*/
        PWM_DisableCapture(PWMB, 0x4);

        /* Clear Capture Interrupt flag for PWMB channel 2*/
        PWM_ClearCaptureIntFlag(PWMB, PWM_CH2, PWM_CAPTURE_INT_FALLING_LATCH);
    }
}
예제 #4
0
/*---------------------------------------------------------------------------------------------------------*/
int32_t main(void)
{
    /* Unlock protected registers */
    SYS_UnlockReg();

    /* Init System, IP clock and multi-function I/O */
    SYS_Init();

    /* Lock protected registers */
    SYS_LockReg();

    /* Init UART0 for printf */
    UART0_Init();

    printf("+------------------------------------------------------------------------+\n");
    printf("|                          PWM Driver Sample Code                        |\n");
    printf("|                                                                        |\n");
    printf("+------------------------------------------------------------------------+\n");
    printf("  This sample code will use PWM0 channel 0 to capture\n  the signal from PWM1 channel 0.\n");
    printf("  I/O configuration:\n");
    printf("    PWM0_CH0(PA.12 PWM0 channel 0) <--> PWM1_CH0(PA.2 PWM1 channel 0)\n\n");
    printf("Use PWM0 Channel 0(PA.12) to capture the PWM1 Channel 0(PA.2) Waveform\n");

    while(1)
    {
        printf("Press any key to start PWM Capture Test\n");
        getchar();

        /*--------------------------------------------------------------------------------------*/
        /* Set the PWM1 Channel 0 as PWM output function.                                       */
        /*--------------------------------------------------------------------------------------*/

        /* Assume PWM output frequency is 250Hz and duty ratio is 30%, user can calculate PWM settings by follows.
           duty ratio = (CMR+1)/(CNR+1)
           cycle time = CNR+1
           High level = CMR+1
           PWM clock source frequency = __HXT = 12000000
           (CNR+1) = PWM clock source frequency/prescaler/clock source divider/PWM output frequency
                   = 12000000/2/1/250 = 24000
           (Note: CNR is 16 bits, so if calculated value is larger than 65536, user should increase prescale value.)
           CNR = 23999
           duty ratio = 30% ==> (CMR+1)/(CNR+1) = 30%
           CMR = 7199
           Prescale value is 1 : prescaler= 2
           Clock divider is PWM_CSR_DIV1 : clock divider =1
        */

        /* set PWM1 channel 0 output configuration */
        PWM_ConfigOutputChannel(PWM1, 0, 250, 30);

        /* Enable PWM Output path for PWM1 channel 0 */
        PWM_EnableOutput(PWM1, PWM_CH_0_MASK);

        /* Enable Timer for PWM1 channel 0 */
        PWM_Start(PWM1, PWM_CH_0_MASK);

        /*--------------------------------------------------------------------------------------*/
        /* Set the PWM0 channel 0 for capture function                                          */
        /*--------------------------------------------------------------------------------------*/

        /* If input minimum frequency is 250Hz, user can calculate capture settings by follows.
           Capture clock source frequency = __HXT = 12000000 in the sample code.
           (CNR+1) = Capture clock source frequency/prescaler/clock source divider/minimum input frequency
                   = 12000000/2/1/250 = 24000
           (Note: CNR is 16 bits, so if calculated value is larger than 65536, user should increase prescale value.)
           CNR = 0xFFFF
           (Note: In capture mode, user should set CNR to 0xFFFF to increase capture frequency range.)
        */

        /* set PWM0 channel 0 capture configuration */
        PWM_ConfigCaptureChannel(PWM0, 0, 166, 0);

        /* Enable capture falling edge interrupt for PWM0 channel 0 */
        //PWM_EnableCaptureInt(PWM0, 0, PWM_CAPTURE_INT_FALLING_LATCH);

        /* Enable PWM0 NVIC interrupt */
        //NVIC_EnableIRQ(PWM0_IRQn);

        /* Enable Timer for PWM0 channel 0 */
        PWM_Start(PWM0, PWM_CH_0_MASK);

        /* Enable Capture Function for PWM0 channel 0 */
        PWM_EnableCapture(PWM0, PWM_CH_0_MASK);

        /* Enable falling capture reload */
        PWM0->CAPCTL |= PWM_CAPCTL_FCRLDEN0_Msk;

        /* Wait until PWM0 channel 0 Timer start to count */
        while((PWM0->CNT[0]) == 0);

        /* Capture the Input Waveform Data */
        CalPeriodTime(PWM0, 0);
        /*---------------------------------------------------------------------------------------------------------*/
        /* Stop PWM1 channel 0 (Recommended procedure method 1)                                                    */
        /* Set PWM Timer loaded value(Period) as 0. When PWM internal counter(CNT) reaches to 0, disable PWM Timer */
        /*---------------------------------------------------------------------------------------------------------*/

        /* Set PWM1 channel 0 loaded value as 0 */
        PWM_Stop(PWM1, PWM_CH_0_MASK);

        /* Wait until PWM1 channel 0 Timer Stop */
        while((PWM1->CNT[0] & PWM_CNT_CNT_Msk) != 0);

        /* Disable Timer for PWM1 channel 0 */
        PWM_ForceStop(PWM1, PWM_CH_0_MASK);

        /* Disable PWM Output path for PWM1 channel 0 */
        PWM_DisableOutput(PWM1, PWM_CH_0_MASK);

        /*---------------------------------------------------------------------------------------------------------*/
        /* Stop PWM0 channel 0 (Recommended procedure method 1)                                                    */
        /* Set PWM Timer loaded value(Period) as 0. When PWM internal counter(CNT) reaches to 0, disable PWM Timer */
        /*---------------------------------------------------------------------------------------------------------*/

        /* Disable PWM0 NVIC */
        //NVIC_DisableIRQ(PWM0_IRQn);

        /* Set loaded value as 0 for PWM0 channel 0 */
        PWM_Stop(PWM0, PWM_CH_0_MASK);

        /* Wait until PWM0 channel 0 current counter reach to 0 */
        while((PWM0->CNT[0] & PWM_CNT_CNT_Msk) != 0);

        /* Disable Timer for PWM0 channel 0 */
        PWM_ForceStop(PWM0, PWM_CH_0_MASK);

        /* Disable Capture Function and Capture Input path for  PWM0 channel 0 */
        PWM_DisableCapture(PWM0, PWM_CH_0_MASK);

        /* Clear Capture Interrupt flag for PWM0 channel 0 */
        PWM_ClearCaptureIntFlag(PWM0, 0, PWM_CAPTURE_INT_FALLING_LATCH);
    }
}