×

STM32F103C8T6------定时器PWM模式

zxjy辉 zxjy辉 发表于2022-10-14 09:46:27 浏览283 评论0

抢沙发发表评论

金华双龙国家重点风景.jpeg

实现过程:明确所需要的资源(定时器、需要输出PWM所对应的引脚);明确功能(对应的引脚是否复用,对应的定时器的模式设置)

  1. PWM的实现方式

    1. 软件模拟(阻塞方式),cpu不断的运行减一循环或者是加一循环

      1. for(i=0;i<144;i++){
        }
    2. 软件模拟(非阻塞方式),利用各种系统(FreeRTOS、UCOS等等)进行延时(挂起)或则是在定时器的中断服务程序中实现

    3. 利用定时器,stm32定时器具有PWM输出功能(不是在定时器中拉高拉低电平)

  2. 定时器的pwm

    1. 只有高级定时器和通用定时器具有pwm(高级定时器支持7个通道,通用定时器支持4个通道),基本定时器没有(stm32f103c8t6只有4个定时器,没有基本定时器(只有定时功能);通用定时器:只没有互补输出功能;高级定时器:具有所有的功能)

    2. 通常情况下6、7是基本定时器,1、8是高级定时器,2~5是通用定时器

  3. 实现步骤

    1. 初始化定时器(周期之类的,对应的结构体是:TIM_TimeBaseInitTypeDef

    2. 设定定时器的模式 对应的结构体是:TIM_OCInitTypeDef

    3. 在调用对应通道的库函数TIM_SetCompare3(通道3)就可以修改对应的比较值,输出一定的PWM波形

  4. 代码

    1. //目的:在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所设定的重载周期
          }
      
      }


  5. 作用

    1. 节省cpu开销且实现部分的代码简单


#好好学习!

群贤毕至

访客