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);
	}
}
相关推荐
Zevalin爱灰灰13 小时前
能源与电源管理电路——防倒灌电路
单片机·嵌入式硬件·电源管理
jianqiang.xue16 小时前
ESP-IDF保姆级入门02|Ubuntu24.04搭建EIM-GUI开发环境,打通Windows_Linux双平台统一开发
stm32·单片机·物联网
无垠的广袤16 小时前
【工业树莓派 CM0 Dev Board】扩展板设计
linux·python·嵌入式硬件·pcb设计·模块化·传感器
嵌入式-老费17 小时前
esp32开发与应用(添加数据分区)
单片机·嵌入式硬件
嵌入式-老费18 小时前
esp32开发与应用(OTA升级)
嵌入式硬件
CYLAM202520 小时前
STC32G 单片机0.96“OLED 西历农历可调万年历 (1901-2100)
单片机·嵌入式硬件·stc32g·万年历·西历农历·0.96”oled 12864·4x4 矩阵键盘
Discipline~Hai21 小时前
ARM03-蜂鸣器和中断
c语言·arm开发·单片机·嵌入式硬件·嵌入式
KaifuZeng21 小时前
电源面试问题汇总一
单片机·嵌入式硬件·面试·电路
驱动探索者1 天前
RISC-V PLIC 深度解析:从 Spec 到 Zephyr 驱动实现
单片机·嵌入式硬件·中断控制器
LCG元1 天前
STM32 FreeRTOS 实战:任务调度 + 互斥锁 + 消息队列 + 串口命令解析器
stm32·单片机·嵌入式硬件