PWM驱动舵机

PWM驱动舵机

接线图

程序结构图:

pwm.c部分代码

cpp 复制代码
#include "stm32f10x.h"                  // Device header

void PWM_Init(void){
  // 开启时钟,这里TIM2是通用寄存器
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	// GPIO初始化代码
		/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);		//开启GPIOA的时钟
	

	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	// 使用复用开漏推挽输出模式
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);						//将PA1和PA2引脚初始化为推挽输出
	
	
	
	// 选择时基单元的时钟,选择内部时钟的模式,定时器默认使用的是内部单元的时钟
	TIM_InternalClockConfig(TIM2);
	
	// 配置时基单元,初始化结构体
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	// 将结构体成员都引用出来放置在这个位置
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;    // 配置参数是否分屏
	TIM_TimeBaseInitStructure.TIM_CounterMode =TIM_CounterMode_Up; // 选择计数的模式选择向上计数
	TIM_TimeBaseInitStructure.TIM_Period = 20000 -1;               // 表示ARR自动重装器的值,这两个参数的取值都要在0-65535之间
	TIM_TimeBaseInitStructure.TIM_Prescaler = 72-1;              // PSC预分频器的值
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;           // 重复计数器的值
	// 初始化结构体并将结构体的地址放置在init函数中
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
  // 初始化输出比较单元
	TIM_OCInitTypeDef TIM_OCInitStructure;
	// 给结构体赋初始值
	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 ;
	//设置CCR,设置ccr寄存器的值
	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);
}

PWM.H文件

cpp 复制代码
#ifndef __PWM_H_
#define __PWM_H_
void PWM_Init(void);
void PWM_SetCompare2(uint16_t Compare);
#endif

电机驱动文件Servo.c文件

cpp 复制代码
#include "stm32f10x.h"                  // Device header
#include "PWM.h"

void Servo_Init(void){
    // 初始化PWM底层
	 PWM_Init();
	

}


// 设置舵机的角度0   500,180 2500,输入角度/180 = x /2500 ---> 输入角度 / 180 * 2500 = x
// 求取一个线性函数,y =kx+b 已知(0,500)和(180,2500)求取k和b的值
void Servo_SetAngle(float Angle){
    // 调用PWM_SetCompare2,计算参数
	  PWM_SetCompare2(Angle / 180 * 2000 + 500);

}

servo.h文件

cpp 复制代码
#ifndef __SERVO_H_
#define __SERVO_H_
void Servo_Init(void);
void Servo_SetAngle(float Angle);
#endif

main函数文件

cpp 复制代码
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Servo.h"
#include "KEY.H"
uint8_t i;
// 按键键码
uint8_t KeyNum;
float Angle;

int main(void)
{
  // 初始化oled
	OLED_Init();
  Servo_Init();
	// 初始化按键
	Key_Init();
  // OLED显示角度的值
	OLED_ShowString(1,1,"Angle:");
	while (1)
	{
		 KeyNum = Key_GetNum();
		 if(KeyNum == 1){
		   Angle += 30;
			 if(Angle > 180){
			   Angle = 0;
			 }
		 }
		 Servo_SetAngle(Angle);
		 OLED_ShowNum(1, 7, Angle, 3);
	}
}
相关推荐
踏着七彩祥云的小丑43 分钟前
嵌入式测试学习第33 天:压力测试、反复开关机、反复插拔接口测试
单片机·嵌入式硬件·学习
布子麟1 小时前
NodeMcu(ESP8266)之更新固件
单片机·物联网·iot
开发笔记-阿牛2 小时前
CK6159A 可靠性测评:芯片工艺、环境测试与量产稳定性分析
stm32·单片机·嵌入式硬件
国科安芯2 小时前
商业航天通信载荷数字处理单元供电架构研究——基于ASP7A84AS的高精度低压差线性稳压器技术分析
前端·单片机·嵌入式硬件·fpga开发·架构·安全性测试
嵌入式ZYXC2 小时前
第8篇:《面试题:模拟地和数字地为什么要分开?怎么接?》
stm32·单片机·嵌入式硬件·面试·职场和发展
头枝3 小时前
ARM Cortex-M DWT CYCCNT 必须显式初始化,jlink调试时正常,使用时异常的问题
arm开发·stm32·单片机·问题·cyccnt
开发笔记-阿牛3 小时前
CK6159A 主控开发:多模式手电筒硬件架构、接线规范及选型参考
单片机·嵌入式硬件
一目Leizi3 小时前
通信协议完全指南
stm32·单片机·嵌入式硬件
Zyed3 小时前
[STM32]Day11-Part2硬件实现SPI读写W25Q64
stm32·单片机·嵌入式硬件
渡码桑3 小时前
STM32 TinyML实战2026:3步在单片机上跑通AI推理——从TensorFlow到Edge Impulse的嵌入式进化
人工智能·stm32·单片机