5.2 PWM

一、基本信息

1.输出比较模式

模式

描述

冻结

CNT=CCR时,REF保持为原状态

匹配时置有效电平

CNT=CCR时,REF置有效电平

匹配时置无效电平

CNT=CCR时,REF置无效电平

匹配时电平翻转

CNT=CCR时,REF电平翻转

强制为无效电平

CNT与CCR无效,REF强制为无效电平

强制为有效电平

CNT与CCR无效,REF强制为有效电平

PWM模式1

向上计数:CNT<CCR时,REF置有效电平,CNT≥CCR时,REF置无效电平

向下计数:CNT>CCR时,REF置无效电平,CNT≤CCR时,REF置有效电平

PWM模式2

向上计数:CNT<CCR时,REF置无效电平,CNT≥CCR时,REF置有效电平

向下计数:CNT>CCR时,REF置有效电平,CNT≤CCR时,REF置无效电平

结构

 2.参数设置

PWM频率:        Freq = CK_PSC / (PSC + 1) / (ARR + 1)

PWM占空比:    Duty = CCR / (ARR + 1)

PWM分辨率:    Reso = 1 / (ARR + 1)

二、代码

1.基础代码

初始化        

void PWM_Init()
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //开启TIM2时钟,TIM2是总线1
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStr;
	GPIO_InitStr.GPIO_Mode=GPIO_Mode_AF_PP;  //复用输出
	GPIO_InitStr.GPIO_Pin=GPIO_Pin_0;  //选择A0口作为输出
	GPIO_InitStr.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStr);
	GPIO_SetBits(GPIOA,GPIO_Pin_0);
	
	TIM_InternalClockConfig(TIM2);  //使用内部时钟
	
	TIM_TimeBaseInitTypeDef TIM_TIM_TimeBaseInitStr;
	TIM_TIM_TimeBaseInitStr.TIM_ClockDivision=TIM_CKD_DIV1;  //滤波采样不分频
	TIM_TIM_TimeBaseInitStr.TIM_CounterMode=TIM_CounterMode_Up;  //向上计数
	TIM_TIM_TimeBaseInitStr.TIM_Period=100-1;    //ARR
	TIM_TIM_TimeBaseInitStr.TIM_Prescaler=720-1;  //PSC
	TIM_TIM_TimeBaseInitStr.TIM_RepetitionCounter=0;
	TIM_TimeBaseInit(TIM2,&TIM_TIM_TimeBaseInitStr);//配置时基单元
	TIM_ClearITPendingBit(TIM2,TIM_IT_Update);  //清除中断标志位
	
	TIM_OCInitTypeDef TIM_OC1InitSte;
	TIM_OCStructInit(&TIM_OC1InitSte);  //结构体赋初始值,防止使用高级TIM时出错
	TIM_OC1InitSte.TIM_OCMode=TIM_OCMode_PWM1;  //使用PWM1模式
	TIM_OC1InitSte.TIM_OCPolarity=TIM_OCPolarity_High;  //有效电平为高电平
	TIM_OC1InitSte.TIM_OutputState=TIM_OutputState_Enable;  
	TIM_OC1InitSte.TIM_Pulse=0;  //CCR
	
	TIM_OC1Init(TIM2,&TIM_OC1InitSte);
	
	TIM_Cmd(TIM2,ENABLE);
}

修改CCR值,达到改变占空比:

void PWM_SetCompare1(uint16_t Compare)
{
	TIM_SetCompare1(TIM2,Compare);  //设置CCR寄存器的值
}

2.应用一:LED呼吸灯

PWM_Init();
	while(1)
		{
			for(i=0;i<100;i++)
			{
				PWM_SetCompare1(i);
				Delay_ms(10);
			}
			for(i=0;i<100;i++)
			{
				PWM_SetCompare1(100-i);
				Delay_ms(10);
			}
		}

3.应用二:舵机

①舵机:

  • 根据输入PWM信号占空比来控制输出角度的装置
  • 输入PWM信号要求:周期为20ms,高电平宽度为0.5ms~2.5ms
  • 一个周期内,高电平时长0.5ms时,旋转0度:高电平时长2.5ms时,旋转180度,线性变化

void Servo_Init()
{
	PWM_Init();
}

void Servo_SetAngle(float Angle)
{
	PWM_SetCompare2(Angle/180*2000+500);
}

4.应用三:直流电机

①直流电机

  • 直流电机有两个电极,当电极正接时,电机正转,当电极反接时,电机反转
  • 直流电机属于大功率器件,GPIO口无法直接驱动,需要配合电机驱动电路来操作
  • TB6612是一款双路H桥型的直流电机驱动芯片,可以驱动两个直流电机并且控制其转速和方向

  • 当PMW口信号高电平且IN1 和 IN2口不同时,O1、O2输出IN1、IN2口的信号

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

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_SetBits(GPIOA,GPIO_Pin_5);
		GPIO_ResetBits(GPIOA,GPIO_Pin_4);
		PWM_SetCompare3(-speed);
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值