/*---------------------------------------------------------------------------------------------------------*/ 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; } }
/*---------------------------------------------------------------------------------------------------------*/ 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; }
/*---------------------------------------------------------------------------------------------------------*/ 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); } }
/*---------------------------------------------------------------------------------------------------------*/ 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); } }