高级会员

- 积分
- 913
- 金钱
- 913
- 注册时间
- 2015-9-17
- 在线时间
- 117 小时
|
5金钱
我目前想控制输出不同频率的脉冲,参考了论坛里帖子 :http://www.openedv.com/posts/list/2475.htm
目前 我实现了控制四路pwm输出不同的占空比,但是占空比不等价于频率。
参考帖子里所讲,我个人认为他是通过中断实行脉冲翻转进而实现不同周期(即频率)
但是为何我是指定时器作为计数器时没有效果呢? 在示波器上的各路脉冲的周期是相等的
下面是我timer的 设置,恳请各位大神帮小弟看一下。新手我找了好几天问题了。望各位能帮帮我 现行写过。写好后我愿意吧程序共享出来
#include "pwm.h"
#include "led.h"
//////////////////////////////////////////////////////////////////////////////////
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK Mini STM32开发板
//PWM 驱动代码
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//修改日期:2010/12/03
//版本:V1.0
//版权所有,盗版必究。
//Copyright(C) 正点原子 2009-2019
//All rights reserved
//////////////////////////////////////////////////////////////////////////////////
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
vu8 SysTimer10mS = 0; /*Unit: mS*/
//------------------------------------------------------------
uint16_t capture = 0;
//TIM1 35+1 0.5us/2M
u16 CCR1_Val = 200; //us
u16 CCR2_Val = 1000;
u16 CCR3_Val = 500; //M X 20000
//u16 CCR4_Val = 500; //M Y
void TIM3_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE); //使能GPIO外设时钟
//设置该引脚为复用输出功能,输出TIM3 CH1-CH4的PWM脉冲波形
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; //T3 - PWM1/PWM2/PWM3/PWM4引脚配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; //T3 - PWM1/PWM2/PWM3/PWM4引脚配置
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIO
//--------------------------------------------------------------------------------------------------------------------------------
//初始化TIM3
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler = psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
//--------------------------------------------------------------------------------------------------------------------------------
//初始化TIM3 Channel1 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
//用户定义定时的周期
TIM_OC1Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC1
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable); //关闭预载入寄存器
//--------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------
//初始化TIM3 Channel2 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
//用户定义定时的周期
TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC2
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable); //关闭预载入寄存器
//--------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------
//初始化TIM3 Channel3 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
//用户定义定时的周期
TIM_OC3Init(TIM3, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM3 OC3
TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Disable); //关闭预载入寄存器
//--------------------------------------------------------------------------------------------------------------------------------//--------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------
TIM_Cmd(TIM3, ENABLE); //使能TIM3
//--------------------------------------------------------------
TIM_ClearFlag(TIM3, TIM_FLAG_Update); //清除定时器3中断标志
//--------------------------------------------------------------
TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); //使能定时器3更新中断
}
/************************************************************
*函数名称:void TIM1_Int_Init(u16 arr,u16 psc)
*功 能:TIM1 定时器1初始化
*输入参数:arr=自动重装载寄存器周期的值,psc=时钟频率预分频值
*输出参数:无
*************************************************************/
void TIM3_Int_Init(u16 arr,u16 psc)
{
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //使能定时器1时钟
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = 65535; //这里必须是65535
TIM_TimeBaseStructure.TIM_Prescaler = 2; //3分频
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //初始化TIM3
/* Output Compare Toggle Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; //输出比较翻转模式
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //使能通道1
TIM_OCInitStructure.TIM_Pulse = CCR1_Val; //待装入输出比较寄存器中的脉冲值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出为正逻辑
TIM_OC1Init(TIM3, &TIM_OCInitStructure); //写入配置
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable); //使能或者失能TIMx在CCR1上的预装载寄存器
/* Output Compare Toggle Mode configuration: Channel2 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
TIM_OC2Init(TIM3, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable);
/* Output Compare Toggle Mode configuration: Channel3 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR3_Val;
TIM_OC3Init(TIM3, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Disable);
/* TIM enable counter */
TIM_Cmd(TIM3, ENABLE); //开启计数器
/* TIM IT enable */ //TIM1中断源设置,开启相应通道的捕捉比较中断
TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE);
}
/************************************************************
*函数名称:void TIM1_IRQHandler(void)
*功 能:TIM1中断入口函数
*说 明:定时45us控制电机S曲线加速
*输入参数:无
*输出参数:无
*************************************************************/
void TIM3_IRQHandler(void)
{
/* TIM3_CH1 toggling with frequency = 183.1 Hz */
if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET) //检查指定的TIM中断发生与否
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC1 ); //清除TIMx的中断待处理位
capture = TIM_GetCapture1(TIM3); //获得输入捕获值,即计数器中的计数值
TIM_SetCompare1(TIM3, capture +CCR1_Val ); //将计数值加上翻转的脉冲值写入输出比较寄存器中,以保证下一个TIM事
//件也是相同的脉冲数
}
/* TIM3_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 + CCR2_Val);
}
/* TIM3_CH3 toggling with frequency = 732.4 Hz */
if (TIM_GetITStatus(TIM3, TIM_IT_CC3) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC3);
capture = TIM_GetCapture3(TIM3);
TIM_SetCompare3(TIM3, capture + CCR3_Val);
}
}
|
|