zoukankan      html  css  js  c++  java
  • STM32 PWM输出

    PWM

    脉冲宽度调制

    由TIMx_ARR确定频率,由TIMx_CCRx确定占空比

    两种PWM模式

    • 1 TIMx_CNT<TIMx_CCRx 时为有效电平
    • 2 TIMx_CNT>TIMx_CCRx 时为有效电平

    PWM输出配置步骤

    使能时钟(定时器时钟和相关IO口时钟)

        RCC_APB1PeriphClockCmd();
        RCC_APB2PeriphClockCmd();
    

    IO口做为复用功能输出,初始化IO口

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;//选择对应的引脚
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出     
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化PC端口
    

    如果IO口要做重映射,还要使能AFIO时钟

        //未做重映射
    

    定时器初始化

    TIM_TimeBaseStructure.TIM_Period=arr;
    TIM_TimeBaseStructure.TIM_Prescaler=psc;
    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
    

    初始化输出比较参数

    TIM_OCInitTypeStructure.TIM_OCMode=TIM_OCMode_PWM2;
    TIM_OCInitTypeStructure.TIM_OCPolarity=TIM_OCPolarity_High;
        TIM_OCInitTypeStructure.TIM_OutputState=TIM_OutputState_Enable;
    TIM_OC2Init(TIM3,&TIM_OCInitTypeStructure);
    

    使能预装载寄存器

       TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);
    

    使能定时器

        TIM_Cmd(TIM3,ENABLE);
    

    在外部不断改变CCRx的值,调节占空比

        TIM_SetCompare2(TIM3,led0pwmval);
    

    配置示例

    void TIM3_PWM(u16 arr,u16 psc)
    {       TIM_OCInitTypeDef TIM_OCInitTypeStructure;
    	GPIO_InitTypeDef GPIO_InitStructure;
    	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能定时器时钟
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);//使能GPIOC和AFIO复用功能模块时钟
    	
    	
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;	//选择对应的引脚
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出     
            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
            GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化PC端口
            //GPIO_SetBits(GPIOC, GPIO_Pin_13 );	 // 关闭所有LED
    
    	TIM_TimeBaseStructure.TIM_Period=arr;
    	TIM_TimeBaseStructure.TIM_Prescaler=psc;
    	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
    	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
    	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
    	
    	
    	TIM_OCInitTypeStructure.TIM_OCMode=TIM_OCMode_PWM2;
    	TIM_OCInitTypeStructure.TIM_OCPolarity=TIM_OCPolarity_High;
            TIM_OCInitTypeStructure.TIM_OutputState=TIM_OutputState_Enable;
    	TIM_OC2Init(TIM3,&TIM_OCInitTypeStructure);
    	
    	TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);
    	TIM_Cmd(TIM3,ENABLE);
    }
    

    总示例 使用TIM3,PA7接LED

    
    #include "stm32f10x.h"
    //#include "led.h"
    
    void TIM3_PWM(u16 arr,u16 psc)
    {TIM_OCInitTypeDef TIM_OCInitTypeStructure;
    	GPIO_InitTypeDef GPIO_InitStructure;
    		TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能定时器时钟
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);//使能GPIOC和AFIO复用功能模块时钟
    	
    	
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;	//选择对应的引脚
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出     
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
          GPIO_Init(GPIOA, &GPIO_InitStructure);  //初始化PC端口
          //GPIO_SetBits(GPIOC, GPIO_Pin_13 );	 // 关闭所有LED
    
    	TIM_TimeBaseStructure.TIM_Period=arr;
    	TIM_TimeBaseStructure.TIM_Prescaler=psc;
    	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
    	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
    	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
    	
    	
    	TIM_OCInitTypeStructure.TIM_OCMode=TIM_OCMode_PWM2;
    	TIM_OCInitTypeStructure.TIM_OCPolarity=TIM_OCPolarity_High;
      TIM_OCInitTypeStructure.TIM_OutputState=TIM_OutputState_Enable;
    	TIM_OC2Init(TIM3,&TIM_OCInitTypeStructure);
    	
    	TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);
    	TIM_Cmd(TIM3,ENABLE);
    }
    void Delay(__IO u32 nCount); 
    
    int main(void)
    {
    u16 led0pwmval=0;
    u8 dir=1;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	
     //SystemInit();	// 配置系统时钟为72M 	
     //LED_GPIO_Config(); //LED 端口初始化 
    /*
      while (1)
      {
    		LED1( ON );			  // 亮
    		Delay(0x200000);
    		LED1( OFF );		  // 灭
    		Delay(0x200000);
    
    		LED2( ON );
    		Delay(0x200000);
    		LED2( OFF ); 	
      }*/
    	
    	TIM3_PWM(899,0);
    	while(1){
    		Delay(1000);
    		if (dir)led0pwmval+=1;
    		else led0pwmval-=1;
    		
    		if(led0pwmval>300)dir=0;
    		if(led0pwmval==0)dir=1;
    		TIM_SetCompare2(TIM3,led0pwmval);
    		
    	}
    	
    }
    
    void Delay(__IO u32 nCount)
    {
      for(; nCount != 0; nCount--);
    } 
    
    

    遇到的问题

    STM32F103C8T6数据手册里没有找到重映射表,故没有做重映射。
    而且STM32F103C8T6的重映射有点问题,虽然还没遇见,mark一下

    另一个问题是,对定时器配置的函数写在另一个c文件里,在头文件h里声明函数,然后c和main.c都包含h,这样搞下来总有一个main.c(34): warning: #223-D: function "TIM3_PWM_Init" declared implicitly
    故上面的示例里把配置函数和主函数写在了一起

  • 相关阅读:
    Java 递归、尾递归、非递归、栈 处理 三角数问题
    vmware虚拟机迁移导致的eth0消失问题
    c语言输入输出
    改动虚拟机镜像的rootpassword
    面试题之变态跳台阶
    努力是种病:放慢节奏,才能快速奔跑(转)
    做技术到底可以做到哪种地步-技术为什么越走越窄 (转)
    wpf 客户端【JDAgent桌面助手】开发详解(三) 瀑布流效果实现与UI虚拟化优化大数据显示
    我为什么写博客(转)
    入行必读:互联网行业薪酬等级!看看你值多少钱?(转)
  • 原文地址:https://www.cnblogs.com/uestcman/p/9048355.html
Copyright © 2011-2022 走看看