新手上路
- 积分
- 23
- 金钱
- 23
- 注册时间
- 2017-8-4
- 在线时间
- 3 小时
|

楼主 |
发表于 2017-8-7 21:34:11
|
显示全部楼层
本帖最后由 youlikesoilove 于 2017-8-7 21:36 编辑
TIMx与PWM波:
[mw_shl_code=c,true]]#include "pwm_output.h"
extern int Speed;
static void TIM2_GPIO_Config(void)//此处使用静态函数,不知道为啥。、、、、。。。。
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//TIM2在APB1通道
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);
GPIO_AFIODeInit();//将复用功能(重映射事件控制和 EXTI 设置)重设为缺省值,又做初始化交错功能(remap, event control和 EXTI 配置) 寄存器
GPIO_PinRemapConfig(GPIO_FullRemap_TIM2 , ENABLE); //这个就是重映射功能函数、、改变指定管脚的映射
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//作为TIM3的通道,要求使用复用推挽输出(详见数据手册“外设的GPIO配置 表20通用定时器TIM/2/3/4/5”)
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10|GPIO_Pin_11;//此处希望直流电机反向转,如果只使舵机朝一个方向转动的话,只需配置一个端口
//注:使用pin_10及pin_11的原因是:直流电机模块及直流电机转接板的原理图
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
}
static void TIM2_Mode_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure ;
TIM_OCInitTypeDef TIM_OCInitStructure;
/*PWM信号电平跳变值*/
u16 CCR3_Val=Speed*100;
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//设置时钟分频系数:不分频。
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数模式
TIM_TimeBaseStructure.TIM_Period=999;//设置定时周期为1000次
TIM_TimeBaseStructure.TIM_Prescaler=0;//设置预分频,不预分频即为72MHz
//TIM_TimeBaseStructure.TIM_RepetitionCounter=0x00;//据说这个叫做重复计数器,仅适用于TIM1和TIM8
/*具体说明如下
Specifies the repetition counter value. Each time the RCR downcounter reaches zero, an update event is generated and counting restarts from the RCR value (N).
This means in PWM mode that (N+1) corresponds to:
- the number of PWM periods in edge-aligned mode
- the number of half PWM period in center-aligned mode
This parameter must be a number between 0x00 and 0xFF.
@note This parameter is valid only for TIM1 and TIM8.
指定重复计数器值。 每次RCR downcounter达到零,生成更新事件并重新计数从RCR值(N)。
这意味着在PWM模式下,(N + 1)对应于:
- 边沿对齐模式下的PWM周期数
- 中心对齐模式下的半周期PWM周期数
此参数必须是0x00和0xFF之间的数字。
@note此参数仅对TIM1和TIM8有效。*/
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;//配置为PWM模式1
/*
PWM1与PWM2模式的区别:
PWM1:向上计数时,(计数寄存器)TIMx_CNT<TIMx_CCRn(比较寄存器)时输出有效电平,TIMx_CCRn<=TIMx_CNT<=TIMc_ARR(自动重载寄存器)时输出无效电平。
有效电平和无效电平稍后定义。(有效电平是高电平还是低电平是自己定义的)
PWM2:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx输出无效电平xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx输出有效电平。
*/
TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//配置输出模式的状态,使能或关闭输出,当前为使能状态
TIM_OCInitStructure.TIM_Pulse=CCR3_Val;//设置跳变值,当计数器计数到这个值时,电平发生跳变。
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;//设置有效电平的极性,当前为高电平。
TIM_OC3Init(TIM2,&TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM2,TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM2, ENABLE);
TIM_Cmd(TIM2,ENABLE);//使能定时器三
}
void TIM2_PWM_Init(void)
{
TIM2_GPIO_Config();
TIM2_Mode_Config();
}[/mw_shl_code]
本PWM波花了我两天时间,原因并不是他难,而是,我手里面的单片机的借口是内置的,只能用固定的端口。所以刚开始一直输出不出来。后来补充知识之后,才知道需要重映射,经过查复用功能重映像,发现其端口是TIM2的重映像。至此顺风顺水。
允许我总结一下,其实TIMx输出PWM就是设置一个跳变值和周期值,系统以系统时钟周期为单位进行计数(可设置加和减),加则加到跳变值电平反转。减则减到跳变值电平反转,加的话继续计数到周期值。计数恢复初始值,减的话。减到零,计数恢复初始值。
距离;如果设定,有效电平为高电平,跳变值为500,周期值为999;则,在0-500系统时钟周期内,输出高电平。500-999周期内是低电平。500/1000是占空比。
但是有个问题,就是:我尝试使跳变值为50,周期值为99,我认为占空比和500/1000一样。但是连上电机其实实际效果不一样、现在还在困惑我。
而且目前不会改变pwm的跳变值。。。。。。等我学会,我再上传吧
|
|