• PWM驱动舵机


    PWM驱动舵机

    接线图
    在这里插入图片描述

    程序结构图:
    在这里插入图片描述
    pwm.c部分代码
    在这里插入图片描述

    #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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    PWM.H文件

    #ifndef __PWM_H_
    #define __PWM_H_
    void PWM_Init(void);
    void PWM_SetCompare2(uint16_t Compare);
    #endif
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    电机驱动文件Servo.c文件

    在这里插入图片描述

    #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);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    servo.h文件

    #ifndef __SERVO_H_
    #define __SERVO_H_
    void Servo_Init(void);
    void Servo_SetAngle(float Angle);
    #endif
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    main函数文件

    #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);
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
  • 相关阅读:
    【附源码】计算机毕业设计JAVA宠物医院管理
    怎样选择第三方检测机构获取功能测试报告?
    只有线上出了bug,老板们才知道测试的价值?
    c语言练习61:malloc和free
    微软推出的Microsoft Fabric 到底是什么?
    洛谷 P2408 不同子串个数 题解
    初识Monorepo
    【书城项目】第三、四阶段--页面 jsp动态化、代码优化、EL修改表单
    数据结构复习之——图算法
    Git 的基本概念和使用方式
  • 原文地址:https://blog.csdn.net/qq_45973003/article/details/136776344