当前位置:文档之家› stm32中定时器产生不同PWM的基本思路

stm32中定时器产生不同PWM的基本思路

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0; //抢占式优先级为0
NVIC_InitStructure.NVIC_IRQChannelSubPriority=2; //从优先级为2
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //使能中断优先级
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
/* PA8设置为功能脚(PWM) */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出(该脚已经用过)
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;//输出极性
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; //互补端的极性
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; //输出空闲非工作状态
在stm32中利用定时器TIM调制PWM的几种方法:
说说我的学习经历:从开始接触到现在有好几个月了,但是学习还是比较的费劲,而且速度也比较的缓慢,当然相比之前还是有很大的进步,记得刚刚学习的时候,建工程都是大四学长手把手教的。废话不多说先来讲讲定时器的配置:
STM32F10系列最少3个、做多有8个定时器,都是16位定时器,且相互之间是独立的,计数范围为0x0000-0xffff,最大计数值为65535.可以用于测量输入信号的脉冲长度或者产生输出波形(输出比较和PWM)分为通用定时器,高级定时器,以及看门狗定时器
TIM_Cmd(TIM1,ENABLE); //使能定时器
}
关于时间的计算问题:
外设系统时钟的频率为72M,进行720分频以后,频率f=72M/720=100khz.如果要定时0.1s则计数值为10000,计算公式为:时间(t)=计数值(n)/频率(f).注意计数值n介于0到65535之间
有定时器则一定会有中断发生,所以要配置中断优先级,对于中断优先
第二种情况:频率一定占空比可以任意设置,频率一定的情况下可以改变定时器输出通道TIM_OCInitStructure.TIM_Pulse的值,
这种情况下可以通过给定时器的捕获寄存器的值进行改变,即改变脉冲的大小,从而改变占空比
在上述的程序的基础上增加如下程序:
//设置捕获寄存器1
void SetT1Pwm1(u16 pulse)
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//正向通道有效
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;//反向通道无效
TIM_OCInitStructure.TIM_Pulse = 72; //占空时间总的周期为8ms占空时间为约为4ms
功能模块2
.....
}
}
功能模块中写上自己需要实现的功能
至此,一个完整的定时器函数模块定义完成,
下面我给大家写一下如何调制PWM,定时器中对于PWM的调制有几种状态,第一种频率占空比一定,第二种频率和占空比可以改变,第三种频率一定,占空比可以改变。
先讲第一种情况:频率和占空比一定时的配置情况
void Tim1_Configuration(void)
接下来写中断处理函数:
Void TIM1_IRQHandler(void)
{
If(TIM_GetITStatus(TIM1,TIM_IT_Update)!=Reset) //接受到中断
{
TIM_ClearnITPendingBit(TIM1,TIM_IT_Update); //清除中断位
功能模块1,需要实现的功能
NVIC_Init(&NVIC_InitStructure);//初始化中断
}
对于优先级中的抢占式和从优先级做如下解释:
抢占式优先级:是可以抢占的中断,比如正在执行的优先级为10的中断,突然来了一个优先级为5的中断,此时cpu会转向优先级为5的中断;
从优先级:从优先级不会抢占正在执行的中断程序,但是如果两个事件同时发生,那么cpu会执行优先级高的事件,但是已经执行就不会再更改了,即使优先级比正在执行的高,这正好和抢占式优先级不同,抢占式优先级不论程序是否在执行,只要现在发生的中断优先级比正在执行的要高,就会更改。
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;//输出极性
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; //互补端的极性
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; //输出空闲非工作状态
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);//开TMI1外设时钟
TIM_DeInit(TIM1);//将TMI寄存器设置为缺省状态
/*TIM1时钟配置*/
TIM_TimeBaseStructure.TIM_Prescaler = 4000;//预分频(时钟分频)72M/4000=18K
//计数模式向上计数
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure)//初始化TIM1
TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);//开启定时器中断
//计时50000次时间为50000/10M=500ms
TIM_TimeBaseStructure.TIM_Period=50000;
TIM_TimeBaseStructure.TIM_Prescaler = 720-1;//720分频
TIM_TimeBaseStructure.TIM_ClockDivision =0;//时钟分割为0;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//正向通道有效
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;//反向通道无效
TIM_OCInitStructure.TIM_Pulse = 40;//占空时间总的周期为8ms占空时间为约为2.4ms
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;//输出互补空闲非工作状态
TIM_OC2Init(TIM1,&TIM_OCInitStructure);//初始化通道2
/* TIM1 counter enable */
TIM_Cmd(TIM1,ENABLE);//使能定时器1
/* TIM1 Main Output Enable */
TIM_CtrlPWMOutputs(TIM1,ENABLE);//使能定时器1的主输出
}
//一般定时器一种有个四个通道OC1、OC2、OC3、OC4;
//注意占空比TIM_OCInitStructure.TIM_Pulse的值不能超过定时器的周期,也即TIM_TimeBaseStructure.TIM_Period的值,
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0;//Repetition重复计数器
//TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0;//Repetition重复计数器。
TIM_RepetitionCounter:设置周期计数器,其值必须在0x00---0xFF之间,且此参数只适用于TMI1和TMI8种
{
TIM1->CCR1=pulse;
}
通过外接函数不断调用给函数 不断的改变pulse的值,从而会改变定时器输出通道中的TIM_OCInitStructure.TIM_Pulse,这就意味着占空比可以任意的设置。
第三种情况:根据情况二
以此类推,我们可以改变定时器的预分频值,从而改变其频率的大小,在此基础上就实现了第三种情况,既改变频率有改变占空比。具体操作读者自己发挥想象,我就不再写出具体操作步骤。
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;//输出互补空闲非工作状态
/* Channel 2 Configuration in PWM mode设置TIM1通道2的参数*/
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;//PWM模式2
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);
相关主题