• 精准控制PWM脉冲的频率和数量


      在一些项目中,我们经常要控制PWM脉冲的频率和数量,比如步进电机的控制等,下面分享一个程序是关于这方面的,程序的思想就是通过STM32的定时器来输出PWM波,并开启定时器中断,在中断里面计数脉冲的数量,一旦脉冲数量达到了目标值,就关闭定时器,实现精确控制脉冲的数量。

      下面是程序分析:

      定时器4配置

      

    #include"stm32f10x.h"
    #include"pwm.h"
    /*¶¨Ê±Æ÷4Êä³ö4·²»Í¬Õ¼¿Õ±ÈÂö³å
    Ó²¼þÁ¬½ÓÈçÏÂ
    CH1--PB6
    CH2--PB7
    CH3--PB8
    CH4--PB9
    */
    void PWM_Init(u16 arr,u16 psc)
    {
    u16 val1=arr/5;
    /*u16 val2=arr/4;
    u16 val3=arr/6;
    u16 val4=arr/8;*/


    GPIO_InitTypeDef GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;

    //ʱÖÓÅäÖÃ
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4 ,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO ,ENABLE);




    //¶Ë¿Ú³õʼ»¯
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    //¶¨Ê±Æ÷4»ù±¾ÅäÖÃ
    TIM_TimeBaseInitStructure.TIM_Period=arr;
    TIM_TimeBaseInitStructure.TIM_Prescaler=psc;
    TIM_TimeBaseInitStructure.TIM_ClockDivision=0;
    TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);

    //PWMģʽÅäÖÃ

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //Ñ¡Ôñ¶¨Ê±Æ÷ģʽ:TIMÂö³å¿í¶Èµ÷ÖÆģʽ1
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //±È½ÏÊä³öʹÄÜ
    TIM_OCInitStructure.TIM_Pulse = 0; //ÉèÖôý×°È벶»ñ±È½Ï¼Ä´æÆ÷µÄÂö³åÖµ
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //Êä³ö¼«ÐÔ:TIMÊä³ö±È½Ï¼«ÐÔ¸ß
    TIM_OC1Init(TIM4, &TIM_OCInitStructure);
    TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); //ʹÄÜTIMxÔÚCCR1ÉϵÄԤװÔؼĴæÆ÷

    /*TIM_OCInitStructure.TIM_Pulse=val2;
    TIM_OC2Init(TIM4,&TIM_OCInitStructure);
    TIM_OC2PreloadConfig(TIM4,TIM_OCPreload_Enable );

    TIM_OCInitStructure.TIM_Pulse=val3;
    TIM_OC3Init(TIM4,&TIM_OCInitStructure);
    TIM_OC3PreloadConfig(TIM4,TIM_OCPreload_Enable );

    TIM_OCInitStructure.TIM_Pulse=val4;
    TIM_OC4Init(TIM4,&TIM_OCInitStructure);
    TIM_OC4PreloadConfig(TIM4,TIM_OCPreload_Enable );*/


    TIM_ARRPreloadConfig(TIM4, ENABLE);

    TIM_ClearITPendingBit(TIM4, TIM_IT_CC1);
    TIM_ITConfig(TIM4,TIM_IT_CC1,ENABLE);

    //TIM_Cmd(TIM4,ENABLE);

    }
    void NVIC_Config(void)
    {
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn ;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    }

      主函数:

    #include "stm32f10x.h"
    #include "led.h"
    #include "delay.h"
    #include "pwm.h"
    #include "usart.h"
    u32 step=0;
    int main(void)
    {
    SystemInit();
    uart_init(115200);
    delay_init();
    LED_Init();
    NVIC_Config();
    PWM_Init(719,100);
    TIM_Cmd(TIM4,ENABLE);
    while(1)
    {

    // delay_ms(100);
    // LED1=!LED1;
    // delay_ms(100);
    TIM4->CCR1 = 300;

    }
    }
    void TIM4_IRQHandler(void)
    {
    if(TIM_GetITStatus(TIM4,TIM_IT_CC1)!=RESET)
    {
    TIM_ClearITPendingBit(TIM4,TIM_IT_CC1);
    step++;
    printf("%d ",step);
    if(step==80000)
    {
    TIM_Cmd(TIM4,DISABLE);
    }
    }

    }

    以上就是完整程序。欢迎同学交流,改正。  

  • 相关阅读:
    Activity相关知识点总结
    大端和小端
    两年前端感悟
    线性结构与树形结构相互转换(ES6实现)
    基于webpack的React项目搭建(三)
    MySQL安装之yum安装
    EL表达式中fn函数
    配置Log4j 详解
    Canvas学习:封装Canvas绘制基本图形API
    canvas
  • 原文地址:https://www.cnblogs.com/panlangen/p/7599901.html
Copyright © 2020-2023  润新知