STM32输出PWM控制舵机转向

这篇博客详细介绍了如何使用STM32F103微控制器通过TIM3 PWM输出控制SG90舵机进行180°转向。通过部分重映射TIM3通道,设置PWM模式,配置定时器参数,以及延时函数,实现了精确的脉冲宽度控制,以调整舵机的角度。代码中展示了从0.5ms到2.5ms的脉宽变化,模拟了舵机从0°到180°的转动过程。
摘要由CSDN通过智能技术生成

最终实现结果:STM32F103发出PWM信号控制舵机SG90进行180°转向

在这里插入图片描述

接线图

在这里插入图片描述

#include "stm32f10x.h"

void delay_us(uint32_t n){
	while(n--){
		SysTick->CTRL = 0;								//Disable SysTick 关闭系统定时器
		SysTick->LOAD = 9;							//Count from 255 to 0 (256 cycles) 配置计数值
		SysTick->VAL = 0;								//CLear current value as well as count flag 清空当前寄存器计数值
		SysTick->CTRL = 1;								//Enable SysTick timer with processor clock 使能系统定时器
		while((SysTick->CTRL & (1<<16)) == 0);			//Wait until count flag is set
	}	
	SysTick->CTRL = 0;									//Disable SysTick 关闭系统定时器
}

void delay_ms(uint32_t n){
	while(n--){
		SysTick->CTRL = 0;								//Disable SysTick 关闭系统定时器
		SysTick->LOAD = 9000;							//Count from 255 to 0 (256 cycles) 配置计数值
		SysTick->VAL = 0;								//CLear current value as well as count flag 清空当前寄存器计数值
		SysTick->CTRL = 1;								//Enable SysTick timer with processor clock 使能系统定时器
		while((SysTick->CTRL & (1<<16)) == 0);			//Wait until count flag is set
	}	
	SysTick->CTRL = 0;									//Disable SysTick 关闭系统定时器
}
/**
* 没有重映射时,TIM3的四个通道CH1, CH2, CH3, CH4分别对应PA6, PA7, PB0, PB1
* 部分重映射时,TIM3的四个通道CH1, CH2, CH3, CH4分别对应PB4, PB5, PB0, PB1
* 完全重映射时,TIM3的四个通道CH1, CH2, CH3, CH4分别对应PC6, PC7, PC8, PC9
* 
* 110:PWM模式1 - 在向上计数时,一旦TIMx_CNT<TIMx_CRRx时,通道x为有效电平,
* 否则为无效电平;在向下计数时,一旦TIMx_CNT>TIMx_CRRx时,通道x为无效电平,
* 否则为有效电平。
*
* 111:PWM模式2 - 在向上计数时,一旦TIMx_CNT<TIMx_CRRx时,通道x为无效电平,
* 否则为有效电平;在向下计数时,一旦TIMx_CNT>TIMx_CRRx时,通道x为有效电平,
* 否则为无效电平。
*/
void TIM3_PWM_Init(uint16_t arr,uint16_t psc,uint16_t time_Pulse){
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	
	GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE); //TIM3部分重映射 TIM3_CH2->PB5
	
	TIM_TimeBaseStructure.TIM_Period = arr;	 	 	//设置自动重装载寄存器周期的值 arr=value-1
	TIM_TimeBaseStructure.TIM_Prescaler = psc; 	 	//设置预分频值 psc=value-1
	TIM_TimeBaseStructure.TIM_ClockDivision = 0;	//设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//TIM向上计数模式
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);	//初始化TIMx时间基数
	
	//初始化TIM3 Channel2 PWM模式   
	TIM_OCInitStructure.TIM_Pulse = time_Pulse;						//脉冲值,即输出都是低电平  
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;				//选择定时器模式:TIM脉冲宽度调制模式1
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;	//开启关闭脉冲输出
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;		//有效状态为高电平,无效则为低电平
	
	//通道初始化
	TIM_OC2Init(TIM3, &TIM_OCInitStructure);						//根据T指定的参数初始化外设TIM3 OC2
	TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);				//通道使能或者失能TIMx在CCR2上的预装载寄存器

	TIM_Cmd(TIM3, ENABLE);											//使能TIMx
}

void GPIO_init_B(void){
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP; //配置为复用模式(PWM输出)
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;
	GPIO_Init(GPIOB, &GPIO_InitStruct);
}

/**
*  舵机工作需要20ms左右的时基脉冲,脉冲控制角度
*  0.5ms-----------  0度     
*  1.0ms-----------  45度	 
*  1.5ms-----------  90度    
*  2.0ms-----------  135度   
*  2.5ms-----------  180度   
*/

int main(void){
	
	/* 系统时钟初始化 */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);	// 打开功能复用IO时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);	// 使能TIM3的外设时钟
	TIM_CtrlPWMOutputs(TIM3,ENABLE);
	
	GPIO_init_B();
	GPIO_ResetBits(GPIOB, GPIO_Pin_5);
	//计算,假设PWM周期设置为20ms
	//公式为:溢出时间Tout=(arr+1)*(psc+1)/Tclk,Tclk为通用定时器的时钟,如果APB1没有分频,则就为系统时钟,72MHZ
	TIM3_PWM_Init(200 - 1, 7200 - 1, 0);
	
	while(1)
    {
	  TIM_SetCompare2(TIM3, 5); 
	  delay_ms(100);
	  TIM_SetCompare2(TIM3, 10); 
	  delay_ms(100);	
	  TIM_SetCompare2(TIM3, 15); 
	  delay_ms(100);
	  TIM_SetCompare2(TIM3, 20); 
	  delay_ms(100);
	  TIM_SetCompare2(TIM3, 25); 
	  delay_ms(100);
	  TIM_SetCompare2(TIM3, 20); 
	  delay_ms(100);	
	  TIM_SetCompare2(TIM3, 15); 
	  delay_ms(100);
	  TIM_SetCompare2(TIM3, 10); 
	  delay_ms(100);
    }

}

  • 4
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值