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

相关推荐
悠哉悠哉愿意5 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
Lester_11015 天前
STM32霍尔传感器输入口设置为复用功能输入口时,还能用GPIO函数直接读取IO的状态吗
stm32·单片机·嵌入式硬件·电机控制
LCG元5 天前
低功耗显示方案:STM32L0驱动OLED,动态波形绘制与优化
stm32·嵌入式硬件·信息可视化
三佛科技-187366133975 天前
120W小体积碳化硅电源方案(LP8841SC极简方案12V10A/24V5A输出)
单片机·嵌入式硬件
z20348315205 天前
STM32F103系列单片机定时器介绍(二)
stm32·单片机·嵌入式硬件
古译汉书5 天前
【IoT死磕系列】Day 7:只传8字节怎么控机械臂?学习工业控制 CANopen 的“对象字典”(附企业级源码)
数据结构·stm32·物联网·http
Alaso_shuang5 天前
STM32 核心输入、输出模式
stm32·单片机·嵌入式硬件
脚后跟5 天前
AI助力嵌入式物联网项目全栈开发
嵌入式硬件·物联网·ai编程
2501_918126915 天前
stm32死锁是怎么实现的
stm32·单片机·嵌入式硬件·学习·个人开发
z20348315205 天前
STM32F103系列单片机定时器介绍(一)
stm32·单片机