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

相关推荐
KaiGer6662 小时前
AUTOSAR图解==>AUTOSAR_SWS_ICUDriver
单片机·汽车·嵌入式·autosar
SANGEDZ_YYDS2 小时前
三格电子上新了——IO-Link系列集线器
单片机
亿道电子Emdoor3 小时前
【ARM】MDK如何将变量存储到指定内存地址
arm开发·stm32·单片机
搬砖的小码农_Sky3 小时前
FPGA:Lattice的FPGA产品线以及器件选型建议
嵌入式硬件·fpga开发·硬件架构·硬件工程
mftang3 小时前
Zephyr OS Nordic芯片的Flash 操作
单片机·嵌入式硬件·物联网
阿川!5 小时前
嵌入式软件--stm32 DAY 6 USART串口通讯(下)
stm32·单片机·嵌入式硬件
繁星无法超越6 小时前
详解Windows(九)——系统性能优化
windows·stm32·性能优化
small_wh1te_coder13 小时前
从经典力扣题发掘DFS与记忆化搜索的本质 -从矩阵最长递增路径入手 一步步探究dfs思维优化与编程深度思考
c语言·数据结构·c++·stm32·算法·leetcode·深度优先
WKJay_14 小时前
深入理解 Cortex-M3 特殊寄存器
stm32·单片机·嵌入式硬件
Linux嵌入式木子16 小时前
# 2-STM32F103-复位和时钟控制RCC
stm32·单片机·嵌入式硬件