// 标志的PWM配置流程 static void pwm_simple_test(void) { // 3个配置PWM的结构体 // Structure of PWM configuration stc_bt_pwm_config_t stcPwmConfig; // structure to select the PWM interrupt stc_pwm_int_sel_t stcPwmIntSel; // structure to set the PWM interrupt callback function stc_pwm_int_cb_t stcPwmIntCallback; // PWM的周期与占空比 // 这里PWM配置PwmPres1Div4, 从PCLK = 80MHZ四分频为20MHZ; // PWM clock = 20MHZ(0.05us), cycle = (1+pwm_cycle)*(Pwm clock cycle) // PWM clock = 20MHZ(0.05us), duty = (1+pwm_duty)*(PWM clock cycle) uint32_t pwm_cycle = 999; // (1+999) * 0.05us = 50us = 20kHZ uint32_t pwm_duty = 99; // (1+99) * 0.05us = 5us // Set Basetimer IO port, 将P40引脚设为TIOA0_0功能; PwmInitOutput(); // Set requested I/O mode // 将定时器配置为I/O mode 0(I/O mode 0: Standard 16-bit timer mode); Bt_ConfigIOMode(&USER_BT, BtIoMode0); // 将定时器配置为16-bit PWM功能; Bt_SelTimerMode(&USER_BT, BtPwmMode); // Initialize PWM timer stcPwmConfig.enPres = PwmPres1Div4; // PWM clock = 20MHz @ PCLK = 80MHz stcPwmConfig.enMode = PwmContinuous; // pwm continuous, 连续不间断模式; stcPwmConfig.enExtTrig = PwmExtTrigDisable; //关闭外部trigger; stcPwmConfig.enOutputMask = PwmOutputNormal; //输出掩码配置 stcPwmConfig.enOutputPolarity = PwmPolarityLow; //优先级配置 stcPwmConfig.enRestartEn = PwmRestartEnable; //PWM复位使能(可以被复位,重新输出PWM) Bt_Pwm_Init(&USER_BT, &stcPwmConfig); // Set cycle and duty value // 这里PWM配置PwmPres1Div4, 从PCLK = 80MHZ四分频为20MHZ; // PWM clock = 20MHZ(0.05us), cycle = (1+pwm_cycle)*0.05us // PWM clock = 20MHZ(0.05us), duty = (1+pwm_duty)*0.05us Bt_Pwm_WriteCycleVal(&USER_BT, pwm_cycle); // Cycle = (1+m)*PWM clock cycle = 50us Bt_Pwm_WriteDutyVal(&USER_BT, pwm_duty); // Duty = (1+m)*PWM clock cycle = 5us // Enable Interrupt // 指定三个中断函数; stcPwmIntSel.bPwmTrigInt = 1; stcPwmIntSel.bPwmDutyMatchInt = 1; stcPwmIntSel.bPwmUnderflowInt = 1; stcPwmIntCallback.pfnPwmTrigIntCallback = PwmTrigIntHandler; stcPwmIntCallback.pfnPwmDutyMatchIntCallback = PwmDutyMatchIntHandler; stcPwmIntCallback.pfnPwmUnderflowIntCallback = PwmUnderflowIntHandler; Bt_Pwm_EnableInt(&USER_BT, &stcPwmIntSel, &stcPwmIntCallback); // Enable count operatoin // 计数使能 Bt_Pwm_EnableCount(&USER_BT); // Start triggered by software // 软件给出trigger信号,此时计时器才会开始计数; Bt_Pwm_EnableSwTrig(&USER_BT); }
/** ****************************************************************************** ** \brief Main function of PDL ** ** \return uint32_t return value, if needed ******************************************************************************/ int32_t main(void) { uint8_t u8Counter; stc_dstc_config_t stcDstcConfig; stc_bt_pwm_config_t stcPwmConfig; stc_pwm_irq_en_t stcPwmIrqEn; boolean_t bCompareError = FALSE; PDL_ZERO_STRUCT(stcDstcConfig); PDL_ZERO_STRUCT(stcPwmConfig); PDL_ZERO_STRUCT(stcPwmIrqEn); // Fill Source Data for (u8Counter = 0; u8Counter < DSTC_MAXDATA; u8Counter++) { // "Random" data au32SourceData[u8Counter] = ((u8Counter << 8u) ^ 0x12345678u) + u8Counter; } // Initialize BT interrupts stcPwmIrqEn.bPwmUnderflowIrq = TRUE; // Set requested BT I/O mode Bt_ConfigIOMode(&BT0, BtIoMode0); // Initialize BT as PWM timer stcPwmConfig.enPres = PwmPres1Div4; stcPwmConfig.enMode = PwmOneshot; stcPwmConfig.enExtTrig = PwmExtTrigDisable; stcPwmConfig.enOutputMask = PwmOutputNormal; stcPwmConfig.enOutputPolarity = PwmPolarityLow; stcPwmConfig.enRestartEn = PwmRestartDisable; stcPwmConfig.pstcPwmIrqEn = &stcPwmIrqEn; stcPwmConfig.bTouchNvic = TRUE; Bt_Pwm_Init(&BT0, &stcPwmConfig); Bt_Pwm_WriteCycleVal(&BT0, 55655u); // just some values ... Bt_Pwm_WriteDutyVal(&BT0, 33u); // Enable BT count operatoin Bt_Pwm_EnableCount(&BT0); // Init Descriptor set for DES0, DES1, DES2, DES3, DES4, DES6 // DES0 stcDstcExample.DES0.DV = 1u; stcDstcExample.DES0.ST = 0u; stcDstcExample.DES0.MODE = 0u; // Mode 0 stcDstcExample.DES0.ORL = 0u; // No reload from DES4, DES5, DES6. The descriptor only includes DES0, DES1, DES2, DES3. stcDstcExample.DES0.TW = 2u; // 32 Bit stcDstcExample.DES0.SAC = 1u; // The address is increased by TW¡Á1 at every transfer with InnerReload. stcDstcExample.DES0.DAC = 0u; // The address is increased by TW¡Á1 at every transfer without InnerReload. stcDstcExample.DES0.CHRS = 0x10u; // An interrupt flag has been set when IRM =1 and ORM = 1 stcDstcExample.DES0.DMSET = 0u; // Set BT0 mask bit stcDstcExample.DES0.ACK = 1u; // Send acknowledge to BT0 stcDstcExample.DES0.CHLK = 0u; stcDstcExample.DES0.PCHK = DSTC_PCHK_CALC(stcDstcExample.u32DES0); // DES1 stcDstcExample.DES1_mode0.ORM = 1u; stcDstcExample.DES1_mode0.IIN = DSTC_MAXDATA; // DES2 stcDstcExample.DES2 = (uint32_t)&au32SourceData[0]; // DES3 stcDstcExample.DES3 = (uint32_t)&au32DestinationData[0]; // Configure DSTC stcDstcConfig.u32Destp = (uint32_t)&stcDstcExample; stcDstcConfig.bSwInterruptEnable = FALSE; stcDstcConfig.bErInterruptEnable = TRUE; stcDstcConfig.bReadSkipBufferDisable = FALSE; stcDstcConfig.bErrorStopEnable = TRUE; stcDstcConfig.enSwTransferPriority = Priority1_31; stcDstcConfig.pfnErrorCallback = &Main_DstcErrorCallback; stcDstcConfig.pfnDstcBt0Irq0Callback = &Main_DstcBt0Callback; stcDstcConfig.bTouchNvic = TRUE; Dstc_Init(&stcDstcConfig); Dstc_SetCommand(CmdErclr); Dstc_SetCommand(CmdRbclr); Dstc_SetHwdesp(DSTC_IRQ_NUMBER_BT0_IRQ0, 0u); // BT0, DES Offset 0 Dstc_SetDreqenbBit(DSTC_IRQ_NUMBER_BT0_IRQ0); // Switch BT0 to DSTC // Start BT triggered by software Bt_Pwm_EnableSwTrig(&BT0); while(FALSE == bDtscEndNotify) {} if (TRUE == bDstcErrorFlasg) { // Error handling } else { for (u8Counter = 0; u8Counter < DSTC_MAXDATA; u8Counter++) { // Check destination data if (au32SourceData[u8Counter] != au32DestinationData[u8Counter]) { bCompareError = TRUE; break; } } } if (TRUE == bCompareError) { // Error handling here ... __NOP(); } while(1) {} }