PWM驱动LED呼吸灯&PWM驱动舵机&PWM驱动直流电机----TIM输出比较

 PWM驱动LED呼吸灯

为什么led为PA0引脚时要用TIM2的CH1引脚:在下标可以看出默认复用功能的引脚对应关系。

引脚功能重映射   同时也有重定义功能需要用AFIO配置,如果把引脚重定义到PA15,需要用到函数GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);然后再查看手册表43 TIM2复用功能重映像选择合适的参数。但是从表中看出还要关闭PA15对应的调试功能,同样用这个(可以参考表35)

PWM初始化代码: 

#include "stm32f10x.h"                  // Device header

void PWM_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	//外设时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	//AFIO用来设置引脚的重映射
//	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//打开AFIO时钟
//	GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2,ENABLE);//重映射外设复用的引脚
//	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//接触ITAG复用
//	
	//GPIO
	GPIO_InitTypeDef GPIO_Init_Structure;
	//要用复用推挽输出 普通开漏推挽输出引脚控制权来自输出数据寄存器,如果想要定时器控制引脚,要用复用开漏推挽模式
	GPIO_Init_Structure.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_Init_Structure.GPIO_Pin=GPIO_Pin_0;   //15
	GPIO_Init_Structure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_Init_Structure);
	//TIMx internal Clock
	TIM_InternalClockConfig(TIM2);

	//时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
	TIM_TimeBaseInitStructure.TIM_Period=100-1;   //ARR
	TIM_TimeBaseInitStructure.TIM_Prescaler=720-1;  //PSC
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
	//TIM peripheral
	TIM_Cmd(TIM2,ENABLE);

	//输出比较初始化
	TIM_OCInitTypeDef TIM_OCInitStruct;
	TIM_OCStructInit (&TIM_OCInitStruct);
	TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1;
	TIM_OCInitStruct.TIM_OCPolarity=TIM_OCNPolarity_High;
	TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;
	TIM_OCInitStruct.TIM_Pulse=0;   //CCR 求占空比;数值越大灯光越亮;根据参数计算的三个公式可以得出参数的值

	//通道和GPIO对应引脚  需要查看引脚对应表
	TIM_OC1Init(TIM2,&TIM_OCInitStruct);
}

void PWM_SetCompare1(uint16_t Compare)
{
	//设置CCR的值,注意这里只是CCR的值要和ARR一起才能算占空比
	TIM_SetCompare1(TIM2,Compare);
}

PWM驱动舵机

对于同一个定时器的不同通道,在TIM通用寄存器的框图中可以看到,他们共用一个CNT所以频率一样,它们又有各自的CCR所以可以设置不同的占空比,计数器更新,所有的PWM同时跳变,所以相位是同步的。

舵机要求周期20ms则频率50hz,由公式可以给定ARR和PSC的值

PWM初始化部分代码:

GPIO_Init_Structure.GPIO_Pin=GPIO_Pin_1;

TIM_TimeBaseInitStructure.TIM_Period=20000-1;   //ARR
TIM_TimeBaseInitStructure.TIM_Prescaler=72-1;  //PSC

//用P1口对应通道2
TIM_OC2Init(TIM2,&TIM_OCInitStruct);

舵机部分代码:

//180 2500
//0    500
//找出角度和占空比的线性关系 
void Servo_SetAngle(float angle)
{
	PWM_SetCompare2(angle/180*2000+500);
}

PWM驱动直流电机

PWM初始化部分:

GPIO_Init_Structure.GPIO_Pin=GPIO_Pin_2;

TIM_TimeBaseInitStructure.TIM_Period=100-1;   //ARR
TIM_TimeBaseInitStructure.TIM_Prescaler=36-1;  //PSC

//这里选用P2口,对应通道3
TIM_OC3Init(TIM2,&TIM_OCInitStruct);

直流电机代码:还需要通过设置IN1/IN2高低电平控制电机正反转,所以还要两个GPIO引脚

void Motor_Init(void)
{
		
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4|GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	PWM_Init();

}
//注意这里是int8_t不要写成无符号的
//因为设置ARR+1=100 所以CCR speed范围在-100,100
void Motor_SetSpeed(int8_t speed)
{
	if(speed>=0)
	{
		GPIO_SetBits(GPIOA,GPIO_Pin_4);
		GPIO_ResetBits(GPIOA,GPIO_Pin_5);
		PWM_SetCompare3(speed);
	}
	else{
		GPIO_ResetBits(GPIOA,GPIO_Pin_4);
		GPIO_SetBits(GPIOA,GPIO_Pin_5);
		PWM_SetCompare3(-speed);
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值