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

相关推荐
清月电子2 小时前
杰理AC109N系列AC1082 AC1074 AC1090 芯片停产替代及资料说明
人工智能·单片机·嵌入式硬件·物联网
智嵌电子3 小时前
【笔记篇】【硬件基础篇】模拟电子技术基础 (童诗白) 第10章 模拟电子电路读图
笔记·单片机·嵌入式硬件
一颗青果3 小时前
51单片机 计算指令
单片机·嵌入式硬件·51单片机
一路往蓝-Anbo3 小时前
【第20期】延时的艺术:HAL_Delay vs vTaskDelay
c语言·数据结构·stm32·单片机·嵌入式硬件
Aaron15884 小时前
AD9084和Versal RF系列具体应用案例对比分析
嵌入式硬件·算法·fpga开发·硬件架构·硬件工程·信号处理·基带工程
LCG米6 小时前
低功耗设计艺术:基于STM32U3系列MCU实现人类存在检测(仅6%占空比)
stm32·单片机·嵌入式硬件
zd8451015006 小时前
[LWIP] 如何启LWIP用调试信息输出
单片机
v先v关v住v获v取7 小时前
桌面级五轴机械臂cad1张总图+三维图+设计说明书
科技·单片机·51单片机
电子工程师-C517 小时前
基于51单片机的智能调温淋浴器
单片机·嵌入式硬件·51单片机