实例演示
以CW32L083VxTx的通用定时器GTIM1为例,实现PWM输出例程:GTIM1的CH3通道(PB08)输出周期为500uS,占空比递增递减循环改变的PWM信号。
1.配置不同的系统时钟。 void RCC_Configuration(void) { /* 0. HSI使能并校准 */ RCC_HSI_Enable(RCC_HSIOSC_DIV6); /* 1. 设置HCLK和PCLK的分频系数 */ RCC_HCLKPRS_Config(RCC_HCLK_DIV1); RCC_PCLKPRS_Config(RCC_PCLK_DIV1); /* 2. 使能PLL,通过HSI倍频到48MHz */ RCC_PLL_Enable(RCC_PLLSOURCE_HSI, 8000000, 6); // PLL输出频率48MHz RCC_PLL_OUT(); ///< 当使用的时钟源HCLK大于24M,小于等于48MHz:设置FLASH 读等待周期为2 cycle ///< 当使用的时钟源HCLK大于48M,小于等于72MHz:设置FLASH 读等待周期为3 cycle __RCC_FLASH_CLK_ENABLE(); FLASH_SetLatency(FLASH_Latency_2); /* 3. 时钟切换到PLL */ RCC_SysClk_Switch(RCC_SYSCLKSRC_PLL); RCC_SystemCoreClockUpdate(48000000); } 2.配置GPIO口 void GPIO_Configuration(void) { /* PB08作为GTIM1的CH3 PWM 输出 */ __RCC_GPIOB_CLK_ENABLE(); PB08_AFx_GTIM1CH3(); PB08_DIGTAL_ENABLE(); PB08_DIR_OUTPUT(); PB08_PUSHPULL_ENABLE(); }
3.配置中断使能 void NVIC_Configuration(void) { __disable_irq(); NVIC_EnableIRQ(GTIM1_IRQn); __enable_irq(); }
4.配置GTIM为PWM输出功能 void PWM_OutputConfig(void) { GTIM_InitTypeDef GTIM_InitStruct = {0}; __RCC_GTIM1_CLK_ENABLE(); GTIM_InitStruct.Mode = GTIM_MODE_TIME; /*!< GTIM的模式选择。*/ GTIM_InitStruct.OneShotMode = GTIM_COUNT_CONTINUE; /*!< GTIM的单次/连续计数模式选择。*/ GTIM_InitStruct.Prescaler = GTIM_PRESCALER_DIV16; /*!< GTIM的预分频系数。*/ // DCLK = PCLK / 16 = 48MHz/16 = 3MHz GTIM_InitStruct.ReloadValue = Period * 3 - 1; /*!< GTIM的重载值。*/ //ARR设置为1499 GTIM_InitStruct.ToggleOutState = DISABLE; GTIM_TimeBaseInit(CW_GTIM1, >IM_InitStruct); //GTIM的基础参数初始化 GTIM_OCInit(CW_GTIM1, GTIM_CHANNEL3, GTIM_OC_OUTPUT_PWM_HIGH); //比较输出功能初始化 GTIM_SetCompare3(CW_GTIM1, PosWidth); GTIM_ITConfig(CW_GTIM1, GTIM_IT_OV, ENABLE); GTIM_Cmd(CW_GTIM1, ENABLE);// GTIM使能 } 5.GTIM标志清零函数 void GTIM_ClearITPendingBit(GTIM_TypeDef *GTIMx, uint32_t GTIM_IT) { GTIMx->ICR = ~GTIM_IT; }
6.GTIM 比较值设置函数 void GTIM_SetCompare3(GTIM_TypeDef *GTIMx, uint32_t Value) { GTIMx->CCR3 = 0x0000FFFF & Value; } 7.GTIM中断处理函数 void GTIM1_IRQHandler(void) { /* USER CODE BEGIN */ // 中断每500us进入一次,每50ms改变一次PosWidth static uint16_t TimeCnt = 0; GTIM_ClearITPendingBit(CW_GTIM1, GTIM_IT_OV); if (TimeCnt++ >= 100) // 50ms { TimeCnt = 0; if (Dir) { PosWidth += 15; // 5us } else { PosWidth -= 15; } if (PosWidth >= Period * 3) { Dir = 0; } if (0 == PosWidth) { Dir = 1; } GTIM_SetCompare3(CW_GTIM1, PosWidth); } /* USER CODE END */ } 8.主函数 uint32_t Period = 500; // 周期,单位us uint32_t PosWidth = 0; // 正脉宽,单位us uint8_t Dir = 1; // 计数方向 1增加,0 减少
int32_t main(void) { /*系统时钟配置 */ RCC_Configuration(); /* GPIO配置*/ GPIO_Configuration(); PWM_OutputConfig(); /* NVIC配置*/ NVIC_Configuration(); while(1) { /* 中断服务程序见GTIM1_IRQHandler() */ }
9.实验演示 系统时钟由HSI提供,通过PLL倍频到48MHz。GTIM1经16分频后,以3MHz的频率计数,ARR设置为1499,GTIM1的溢出周期为500us。GTIM1每500us进入一次中断,每50ms改变一次CH3的CCR寄存器的值,即改变PWM的正脉宽,步长为5us,先递增到ARR,然后递减到0,如此反复。通过示波器图像显示,PB08处的信号波的占空比随时间进行周期性变化。截取2个波形如下:
|