当前位置: 首页 > news >正文

STM32中使用PWM对舵机控制

目录

1、硬件JIE

2、PWM口配置

3、角度转换

4、main函数中应用

5、工程下载连接


1、硬件介绍

单片机:STM32F1

舵机:MG995

2、PWM口配置

20毫秒的PWM脉冲占空比,对舵机控制效果较好

计算的公式:

PSC、ARR值的选取:SG90要求的频率是20ms,则72MHz / (PSC+1) / (ARR+1) = 1/0.02;这里PSC和ARR的参数是不固定的。经过多次尝试最终确定PSC=72-1,ARR=20k-1时,舵机旋转效果最好。

PWM配置程序

void pwm_init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure_For_Servo;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseImitStructure;
		TIM_OCInitTypeDef TIM_OCInitStructure;
	
	/*µÚÒ»²½¿ªÆôRCCʱÖÓ*/
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	/*µÚ¶þ²½ÅäÖÃGPIO¶Ë¿---PA1Ú*/
	GPIO_InitStructure_For_Servo.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure_For_Servo.GPIO_Pin = GPIO_Pin_1;
	GPIO_InitStructure_For_Servo.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure_For_Servo);
	
	TIM_InternalClockConfig(TIM2);/*??????*/
	
	/*µÚÈý²½ÅäÖÃʱ»ùµ¥Ôª*/   //20msƵÂÊ(¶æ»úÒªÇóµÄÕâ¸öƵÂÊЧ¹û×îºÃ)
	TIM_TimeBaseImitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseImitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseImitStructure.TIM_Period = 20000 - 1;
	TIM_TimeBaseImitStructure.TIM_Prescaler = 72 - 1;
	TIM_TimeBaseImitStructure.TIM_RepetitionCounter = 0;
	
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseImitStructure);
	
	/*µÚËIJ½ÅäÖÃÊä³ö±È½Ïµ¥Ôª*/
	TIM_OCStructInit(&TIM_OCInitStructure);
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_Pulse = 0; /*CCR*/
	TIM_OC2Init(TIM2,&TIM_OCInitStructure);
	
	/*µÚÎ岽ʹÄÜʱÖÓ*/
	TIM_Cmd(TIM2,ENABLE);
}

设置脉冲

void pwm_setcompare2(uint16_t compare)
{
	TIM_SetCompare2(TIM2,compare);
}

完整代码


#include "pwm.h"

void pwm_init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure_For_Servo;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseImitStructure;
		TIM_OCInitTypeDef TIM_OCInitStructure;
	
	/*µÚÒ»²½¿ªÆôRCCʱÖÓ*/
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	/*µÚ¶þ²½ÅäÖÃGPIO¶Ë¿---PA1Ú*/
	GPIO_InitStructure_For_Servo.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure_For_Servo.GPIO_Pin = GPIO_Pin_1;
	GPIO_InitStructure_For_Servo.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure_For_Servo);
	
	TIM_InternalClockConfig(TIM2);/*??????*/
	
	/*µÚÈý²½ÅäÖÃʱ»ùµ¥Ôª*/   //20msƵÂÊ(¶æ»úÒªÇóµÄÕâ¸öƵÂÊЧ¹û×îºÃ)
	TIM_TimeBaseImitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseImitStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseImitStructure.TIM_Period = 20000 - 1;
	TIM_TimeBaseImitStructure.TIM_Prescaler = 72 - 1;
	TIM_TimeBaseImitStructure.TIM_RepetitionCounter = 0;
	
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseImitStructure);
	
	/*µÚËIJ½ÅäÖÃÊä³ö±È½Ïµ¥Ôª*/
	TIM_OCStructInit(&TIM_OCInitStructure);
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_Pulse = 0; /*CCR*/
	TIM_OC2Init(TIM2,&TIM_OCInitStructure);
	
	/*µÚÎ岽ʹÄÜʱÖÓ*/
	TIM_Cmd(TIM2,ENABLE);
}
 
void pwm_setcompare2(uint16_t compare)
{
	TIM_SetCompare2(TIM2,compare);
}

3、角度转换

void servo_set_angle(double angle)
{
	pwm_setcompare2(angle / 180 * 2000 + 500);
}

完整代码

#include "stepmotor.h"
#include "pwm.h"

void servo_init(void)
{
	pwm_init();
	
}
 
void servo_set_angle(double angle)
{
	pwm_setcompare2(angle / 180 * 2000 + 500);
}

4、main函数中应用

2秒运动执行一次,分别从0度->180度->270度。(若180度舵机,运动到180度就不再往后转270度了,等到0度的时候转到0度)

        //2秒运行一次
		if(i%2000==0)
		{
			count++;
			//printf("count:%d \r\n",count);
			//printf("Pitch: %.2f ,Roll: %.2f,Yaw: %.2f \r\n",Pitch,Roll,Yaw);			//Pitch,Roll,YawÊý¾Ý´«µ½´®¿Ú	
			
			count2++;
			if(count2==1)
			{
				angle=0;
				servo_set_angle(angle);
				printf("angle:%.2f \r\n",angle);
			}
			if(count2==2)
			{
				angle=180;
				servo_set_angle(angle);
				printf("angle:%.2f \r\n",angle);
			}
			if(count2==3)
			{
				angle=270;
				servo_set_angle(angle);
				count2=0;
				printf("angle:%.2f \r\n",angle);
			}
		}

完整代码

#include "system.h"
#include "SysTick.h"
#include "SysDelay.h"
#include "led.h"
#include "usart.h"
#include "mpu6050.h"
#include "stepmotor.h"

double angle;

int main()
{
	u8 count=0;
	u16 i=0;	
	u16 count2=0;
	
	SystemInit();                   		//ϵͳ³õʼ»¯	
	SysDelay_Init(72);									//×Ô¶¨ÒåÑÓʱº¯Êý³õʼ»¯
	LED_Init();
	USART1_Config();										//´®¿Ú1³õʼ»¯ ÉÏλ»ú
	USART3_Config();										//´®¿Ú3³õʼ»¯ À¶ÑÀÓëUSART3¹«ÓÃÏàͬIO¿Ú
	SysDelay_ms(10);										//10ºÁÃëÑÓʱ
	MPU6050_Init();						   				//MPU6050 DMPÍÓÂÝÒdzõʼ»¯
	delay_ms(1000);
	servo_init();
	
	
	while(1)
	{
		
		/* 1¡¢LEDµÆÉÁ˸ */	
		if(i%500==0)
		{
			led1=!led1;
			
		}
		
		//2ÃëÖ´ÐÐÒ»´Î
		if(i%2000==0)
		{
			count++;
			//printf("count:%d \r\n",count);
			//printf("Pitch: %.2f ,Roll: %.2f,Yaw: %.2f \r\n",Pitch,Roll,Yaw);			//Pitch,Roll,YawÊý¾Ý´«µ½´®¿Ú	
			
			count2++;
			if(count2==1)
			{
				angle=0;
				servo_set_angle(angle);
				printf("angle:%.2f \r\n",angle);
			}
			if(count2==2)
			{
				angle=180;
				servo_set_angle(angle);
				printf("angle:%.2f \r\n",angle);
			}
			if(count2==3)
			{
				angle=270;
				servo_set_angle(angle);
				count2=0;
				printf("angle:%.2f \r\n",angle);
			}
		}
		
		//20ºÁÃëÖ´ÐÐÒ»´Î
		if(i%20==0)
		{
			
			
		}
		/*»ñÈ¡MPU6050½Ç¶È״̬*/
		//ÔÚ´®¿ÚÊý¾Ý·¢ËÍÖ®ºó 
		MPU6050_Pose();										//Pitch·­¹ö£¬Roll¸©Ñö£¬YawÆ«º½
		
		
		
		SysDelay_ms(1);									//1ºÁÃëÑÓʱ
		i++;

		
	}
}



5、工程下载连接

https://download.csdn.net/download/panjinliang066333/90437321

相关文章:

  • Octave3D 关卡设计插件
  • 数据库的三个范式及其含义
  • 内网穿透:打破网络限制的利器
  • AI问答-供应链管理:SIPOC图 / 供方(S)、输入(I)、流程(P)、输出(O)、客户(C)
  • 前端面试题---小程序跟vue的声明周期的区别
  • STM32寄存器控制引脚高低电平
  • Python中if else以及嵌套
  • 1.68M 免安装多格式图片批量转 webp 无广告软件推荐
  • MySQL 性能优化
  • 开源工具推荐:Checkmate监控
  • AI触手可及 | 基于函数计算玩转AI大模型
  • 【Docker基础】理解 Registry 镜像仓库:分类、工作机制、命令与实操
  • 【多部电梯群控】01群控要求分析与策略简介
  • 面试基础---内存泄漏与内存溢出排查
  • 【图文详解】论文《Attention Is All You Need》中位置嵌入(Positional Encoding)的流程和作用
  • 关于回溯算法中的剪枝是否需要for循环的总结归纳
  • 51c嵌入式~电路~合集12
  • DeepSeek开源周Day4:三连发!突破 AI 训练瓶颈的立体解决方案,并行计算三剑客DualPipe、EPLB与Profile-data
  • 设计模式之责任链模式
  • Redis安装及其AnotherRedisDesktopManagera安装使用
  • 俄媒:俄乌伊斯坦布尔谈判将于北京时间今天17时30分开始
  • 国税总局上海市税务局回应刘晓庆被举报涉嫌偷漏税:正依法依规办理
  • 马上评|中学生被操场地面烫伤,谁的“大课间”?
  • MSCI中国指数5月调整:新增5只A股、1只港股
  • 科普|揭秘女性压力性尿失禁的真相
  • 沈阳一超市疑借领养名义烹食流浪狗,当地市监局:已收到多起投诉