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

相关推荐
三佛科技-134163842123 小时前
过认证72W碳化硅方案(12V6A)主控HN1562+HN36228V 典型应用电路、变压器参数分享
单片机·嵌入式硬件·物联网·智能家居·pcb工艺
Zwawa4 小时前
串口为什么会丢字节:从轮询到中断和环形缓冲区
c语言·单片机·嵌入式
Brilliantwxx4 小时前
【STM32】 内部 Flash 详解:寄存器逐位拆解 + 工作流程顺序全讲 + EEPROM再实现
stm32·单片机·嵌入式硬件·1024程序员节
木子单片机4 小时前
基于单片机的DS18B20温度传感器测温系统设计
单片机·嵌入式硬件·51单片机·keil
华清远见IT开放实验室4 小时前
实验室建设案例 | 安徽三联学院物联网实验室
stm32·单片机·嵌入式硬件·物联网·华清远见
Zw-awa5 小时前
串口为什么会丢字节:从轮询到中断和环形缓冲区
stm32
深圳光特通信豆子6 小时前
TTL 光模块在工业控制与串口通信中的应用指南(10M BIDI 单模系列)
单片机·嵌入式硬件
桀人6 小时前
SPI概念引入
stm32·单片机·嵌入式硬件
离凌寒7 小时前
一、基于stm32+freertos下LD2410D和R60ADB1两款雷达的使用效果
stm32·单片机·嵌入式硬件
国科安芯7 小时前
商业光学遥感载荷焦平面供电链的低噪声稳压器研究综述——以国科安芯ASP7A84AS型3A低压差线性稳压器为器件级参照
大数据·网络·嵌入式硬件·平面·卫星·商业航天·抗辐射