当前位置:首页 > 单片机 > 单片机
[导读]STM32产生PWM是非常的方便的,要需要简单的设置定时器,即刻产生!(1)使能定时器时钟:RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);(2)定义相应的GPIO:/* PA2,3,4,5,6输出->Key_Up,Key_Down,Key_Left

STM32产生PWM是非常的方便的,要需要简单的设置定时器,即刻产生!


(1)使能定时器时钟:RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);


(2)定义相应的GPIO:


/* PA2,3,4,5,6输出->Key_Up,Key_Down,Key_Left,Key_Right,Key_Ctrl */


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6;


GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //下拉接地,检测输入的高电平


GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M时钟速度


GPIO_Init(GPIOA, &GPIO_InitStructure);


/* PA7用于发出PWM波 */


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;


GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M时钟速度


GPIO_Init(GPIOA, &GPIO_InitStructure);


(3)如果是产生PWM(频率不变,占空比可变),记得打开PWM控制,在TIM_Configuration()中。


TIM_Cmd(TIM3,ENABLE);


/* TIM1 Main Output Enable */


TIM_CtrlPWMOutputs(TIM1,ENABLE);


利用定时器产生不同频率的PWM有时候,需要产生不同频率的PWM,这个时候,设置与产生相同PWM的程序,有关键的不一样。


(一) 设置的原理


利用改变定时器输出比较通道的捕获值,当输出通道捕获值产生中断时,在中断中将捕获值改变,这时, 输出的I/O会产生一个电平翻转,利用这种办法,实现不同频率的PWM输出。


(二)关键设置


在定时器设置中:TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable);


在中断函数中:


if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)


{


  TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);


  capture = TIM_GetCapture2(TIM3);


  TIM_SetCompare2(TIM3, capture + Key_Value);


}


一个定时器四个通道,分别产生不同频率(这个例子网上也有)


vu16 CCR1_Val = 32768;


vu16 CCR2_Val = 16384;


vu16 CCR3_Val = 8192;


vu16 CCR4_Val = 4096;


void TIM_Configuration(void)


{


  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;


  TIM_OCInitTypeDef TIM_OCInitStructure;


  /* TIM2 clock enable */


  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);


  /* ---------------------------------------------------------------


  TIM2 Configuration: Output Compare Toggle Mode:


  TIM2CLK = 36 MHz, Prescaler = 0x2, TIM2 counter clock = 12 MHz


  CC1 update rate = TIM2 counter clock / CCR1_Val = 366.2 Hz


  CC2 update rate = TIM2 counter clock / CCR2_Val = 732.4 Hz


  CC3 update rate = TIM2 counter clock / CCR3_Val = 1464.8 Hz


  CC4 update rate = TIM2 counter clock / CCR4_Val = 2929.6 Hz


  --------------------------------------------------------------- */


  /* Time base configuration */


  TIM_TimeBaseStructure.TIM_Period = 65535;


  TIM_TimeBaseStructure.TIM_Prescaler = 2;


  TIM_TimeBaseStructure.TIM_ClockDivision = 0;


  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;


  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);


  /* Channel 1 Configuration in PWM mode */


  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; //PWM模式2


  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //正向通道有效


  TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;//反向通道无效


  TIM_OCInitStructure.TIM_Pulse = CCR1_Val;//占空时间


  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性


  TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; //互补端的极性


  TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;


  TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;


  TIM_OC1Init(TIM2,&TIM_OCInitStructure); //通道1


  TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Disable);



  TIM_OCInitStructure.TIM_Pulse = CCR2_Val; //占空时间


  TIM_OC2Init(TIM2,&TIM_OCInitStructure);//通道2


  TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Disable);



  TIM_OCInitStructure.TIM_Pulse = CCR3_Val; //占空时间


  TIM_OC3Init(TIM2,&TIM_OCInitStructure); //通道3


  TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Disable);



  TIM_OCInitStructure.TIM_Pulse = CCR4_Val; //占空时间


  TIM_OC4Init(TIM2,&TIM_OCInitStructure);//通道4


  TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Disable);


  /* TIM2 counter enable */


  TIM_Cmd(TIM2,ENABLE);



  /* TIM2 Main Output Enable */


  //TIM_CtrlPWMOutputs(TIM2,ENABLE);


   /* TIM IT enable */


  TIM_ITConfig(TIM2, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE);


}



void GPIO_Configuration(void)


{


GPIO_InitTypeDef GPIO_InitStructure;



/*允许总线CLOCK,在使用GPIO之前必须允许相应端的时钟.


从STM32的设计角度上说,没被允许的端将不接入时钟,也就不会耗能,


这是STM32节能的一种技巧,*/



RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);


RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);


RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);


RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);




/* PA2,3,4,5,6,7输出->LED1,LED2,LED3,LED4,LED5,LED6 */


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;


GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //开漏输出


GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M时钟速度


GPIO_Init(GPIOA, &GPIO_InitStructure);




/* PB0,1输出->LED7,LED8*/


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;


GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //开漏输出


GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M时钟速度


GPIO_Init(GPIOB, &GPIO_InitStructure);



/* PA0,1->KEY_LEFT,KEY_RIGHT*/


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;


GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;? //上拉输入


GPIO_Init(GPIOA, &GPIO_InitStructure);



/* PC13->KEY_UP*/


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;


GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;? //上拉输入


GPIO_Init(GPIOC, &GPIO_InitStructure);



/* PB5->KEY_DOWN*/


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;


GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;? //上拉输入


GPIO_Init(GPIOB, &GPIO_InitStructure);



/* GPIOA Configuration:TIM2 Channel1, 2, 3 and 4 in Output */


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;


GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;


GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;



GPIO_Init(GPIOA, &GPIO_InitStructure);


}



void NVIC_Configuration(void)


{


NVIC_InitTypeDef NVIC_InitStructure;



/* Configure one bit for preemption priority */


NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);



NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn;


NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;


NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;


NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;


NVIC_Init(&NVIC_InitStructure);


}



u16 capture = 0;


extern vu16 CCR1_Val;


extern vu16 CCR2_Val;


extern vu16 CCR3_Val;


extern vu16 CCR4_Val;


void TIM2_IRQHandler(void)


{


/* TIM2_CH1 toggling with frequency = 183.1 Hz */


if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)


{


  TIM_ClearITPendingBit(TIM2, TIM_IT_CC1 );


  capture = TIM_GetCapture1(TIM2);


  TIM_SetCompare1(TIM2, capture + CCR1_Val );


}


/* TIM2_CH2 toggling with frequency = 366.2 Hz */


if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET)


{


  TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);


  capture = TIM_GetCapture2(TIM2);


  TIM_SetCompare2(TIM2, capture + CCR2_Val);


}



/* TIM2_CH3 toggling with frequency = 732.4 Hz */


if (TIM_GetITStatus(TIM2, TIM_IT_CC3) != RESET)


{


   TIM_ClearITPendingBit(TIM2, TIM_IT_CC3);


  capture = TIM_GetCapture3(TIM2);


  TIM_SetCompare3(TIM2, capture + CCR3_Val);


}



/* TIM2_CH4 toggling with frequency = 1464.8 Hz */


if (TIM_GetITStatus(TIM2, TIM_IT_CC4) != RESET)


{


  TIM_ClearITPendingBit(TIM2, TIM_IT_CC4);


  capture = TIM_GetCapture4(TIM2);


   TIM_SetCompare4(TIM2, capture + CCR4_Val);


}



}


一个定时器一个通道,产生不同频率



其它的设置都一样,就是在主函数中修改一个参数,然后在定时器中断中,根据这个参数,改变频率。



#include "stm32lib\stm32f10x.h"


#include "hal.h"



volatile u16 Key_Value=1000;? //用于保存按键相应的PWM波占空比值




int main(void)


{


ChipHalInit();


ChipOutHalInit();



while(1)


{?


? if( (!Get_Key_Up)&(!Get_Key_Down)&(!Get_Key_Left)&(!Get_Key_Right)&(!Get_Key_Ctrl) )


? {


? ? Key_Value=12000;


? }


? else


? {


? ? if(Get_Key_Up)? ? //按键前进按下 ,对应1kHz


? ? {


? ? Key_Value=6000;


? ? }


? ? else if(Get_Key_Down)? //按键后退按下 ,对应2kHz


? ? {


? ? ? Key_Value=3000;


? ? }


? ? Delay_Ms(20);? ? ? //10ms延时



? ? if(Get_Key_Left)? ? //按键左转按下,对应3kHz


? ? {


? ? Key_Value=2000;


? ? }


? ? else if(Get_Key_Right) //按键右转按下,对应4kHz


? ? {


? ? ? Key_Value=1500;


? ? }?


? ? Delay_Ms(20);? ? ? //10ms延时



? ? if(Get_Key_Ctrl)? ? //按键控制按下,对应5kHz


? ? {


? ? ? Key_Value=1200;


? ? }


? ? Delay_Ms(20);? ? ? //10ms延时


? }


}


}



extern volatile u16 Key_Value;


u16 capture=0;


void TIM3_IRQHandler(void)


{


/* TIM2_CH2 toggling with frequency = 366.2 Hz */


if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)


{


? ? TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);


capture = TIM_GetCapture2(TIM3);


? ? TIM_SetCompare2(TIM3, capture + Key_Value);


}


}



void TIM3_Configuration(void)


{


TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;


TIM_OCInitTypeDef TIM_OCInitStructure;



/* TIM2 clock enable */


RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);



/*TIM1时钟配置*/


TIM_TimeBaseStructure.TIM_Prescaler = 5;? ? ? //预分频(时钟分频)72M/6=12M


TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;? //向上计数


TIM_TimeBaseStructure.TIM_Period = 65535;? ? ? ? //装载值选择最大


TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;


TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0;


TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);



/* Channel 1 Configuration in PWM mode */


TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; //PWM模式2


TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //正向通道有效


TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;//反向通道无效


TIM_OCInitStructure.TIM_Pulse = Key_Value; //占空时间


TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性


TIM_OCInitStruct

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭