
实现过程:明确所需要的资源(定时器、需要输出PWM所对应的引脚);明确功能(对应的引脚是否复用,对应的定时器的模式设置)
PWM的实现方式
软件模拟(阻塞方式),cpu不断的运行减一循环或者是加一循环
for(i=0;i<144;i++){ }软件模拟(非阻塞方式),利用各种系统(FreeRTOS、UCOS等等)进行延时(挂起)或则是在定时器的中断服务程序中实现
利用定时器,stm32定时器具有PWM输出功能(不是在定时器中拉高拉低电平)
定时器的pwm
只有高级定时器和通用定时器具有pwm(高级定时器支持7个通道,通用定时器支持4个通道),基本定时器没有(stm32f103c8t6只有4个定时器,没有基本定时器(只有定时功能);通用定时器:只没有互补输出功能;高级定时器:具有所有的功能)
通常情况下6、7是基本定时器,1、8是高级定时器,2~5是通用定时器
实现步骤
初始化定时器(周期之类的,对应的结构体是:TIM_TimeBaseInitTypeDef
设定定时器的模式 对应的结构体是:TIM_OCInitTypeDef
在调用对应通道的库函数TIM_SetCompare3(通道3)就可以修改对应的比较值,输出一定的PWM波形
代码
//目的:在PB0上输出PWM ///PB0引脚初始化 void PWM_GPIO_Init(){ GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); //开启GPIOB的时钟 RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO, ENABLE ); //开启GPIOB的复用时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init( GPIOB, &GPIO_InitStructure ); } ///定时器3初始化 void TIM3_Init(){ TIM_TimeBaseInitTypeDef TIM3_BaseInitStructure; RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3, ENABLE ); //开启定时器3的时钟 TIM3_BaseInitStructure.TIM_Period = 899; //周期设置为899(也就是900个)也就是重载值 TIM3_BaseInitStructure.TIM_Prescaler = 0; //预分频:不分频 TIM3_BaseInitStructure.TIM_ClockDivision =0; //时钟分割:不分割,这个用于外部触发输入或则是输入捕获 TIM3_BaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数 TIM_TimeBaseInit( TIM3, &TIM3_BaseInitStructure ); } ///定时器3模式初始化 void TIM3_Mod_Init(){ TIM_OCInitTypeDef TIM3_OCInitStructure; TIM3_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择pwm2模式 TIM3_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //使能比较输出 TIM3_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //设置比较输出极性为高 TIM_OC3Init( TIM3, &TIM3_OCInitStructure ); //初始化TIM3_CH3:tim3的通道3 TIM_OC3PreloadConfig( TIM3, ENABLE ); //在更新到来的时候,重载 即TIM3_CCR3的预装载值在更新事件到来时才能被传送至当前寄存器中 TIM_Cmd( TIM3, ENABLE ); //开启定时器3(使能) } ///硬件初始化 void PWM_Hard_Init(){ PWM_GPIO_Init(); //PB0引脚初始化 TIM3_Init(); //定时器3初始化 TIM3_Mod_Init(); //定时器3模式初始化 } ///使得PB0产生呼吸灯的效果 void PWM_Breathing_Light(){ u16 led0pwmval=849; u8 dir=1; while( 1 ){ delay_ms(2); //这个控制着增减的速度,也就是呼吸的速度 if(dir)led0pwmval++; //第一次的时候849进行++,变成了850 else led0pwmval--; if(led0pwmval==300)dir=1; if(led0pwmval==850)dir=0; TIM_SetCompare3(TIM3,led0pwmval); //设置比较值,大小从0到899,这个899也就是TIM3所设定的重载周期 } }作用
节省cpu开销且实现部分的代码简单
#好好学习!