【STM32 标准库】PWM控制电机(开环控制)

目录

1.原理简介

1.1PWM控制原理

1.1.1 电机

1.1.2 电机驱动

2.硬件设计

2.1 PWM电机控制电路接线图

         2.2 PWM电机控制电路原理图​

3.软件设计

 3.1 PWM.c

3.2 PWM.h

3.3 direction.c

3.4 direction.h

3.5 mian.c


1.原理简介

1.1PWM控制原理

        使用STM32F103ZET6单片机输出2路PWM波(方波),通过L298N驱动芯片放大后输入GM37直流减速电机中,实现对电机的PWM调速、正反转。

1.1.1 电机

        (1)选型:直流减速电机——GM37直流减速电机

        (2)接线:

        红色、黑色线:PWM输入

        绿色、蓝色线:编码器电源

        黄色、白色线:编码器输出

1.1.2 电机驱动

        (1)选型:L298N

        (2)接线:

2.硬件设计

2.1 PWM电机控制电路接线图

 2.2 PWM电机控制电路原理图

3.软件设计

3.1 PWM.c

1.#include "PWM.h"
2.// ----------------------------1.初始化PWM--------------------------------------
3./* ---------------------------------函数声明-------------------------------------
4.*函数名称:TIM3_CH2_PWM_Iint(u16 per, u16 psc)
5.*输入参数:u16 per:自动重装载值;u16 psc:预分频系数
6.*返回参数:无
7.*功    能:初始化PWM,使用TIM3的通道2输出PWM
8.*作    者:lph
9.*日    期:2024/03/27
10.------------------------------------------------------------------------------ */
11.void TIM2_CH3_PWM_Iint(u16 per, u16 psc)
12.{
13.    //1.1使能定时器及端口时钟
14.    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
15.    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
16.    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
17.    
18.    //1.2初始化GPIO
19.    GPIO_InitTypeDef GPIO_InitStruct;
20.    
21.    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
22.    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
23.    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
24.    GPIO_Init(GPIOA, &GPIO_InitStruct);
25.    
26.    //1.3设置引脚复用器映射
27.    GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);
28.    
29.    //2.初始化定时器参数,包含自动重装值,分频系数,计数方式等
30.    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
31.    
32.    TIM_TimeBaseInitStructure.TIM_Period=per;
33.    TIM_TimeBaseInitStructure.TIM_Prescaler=psc;
34.    TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
35.    TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
36.    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
37.    
38.    //3.初始化PWM输出参数,包含PWM模式、输出极性,使能等
39.    TIM_OCInitTypeDef TIM_OCInitStructure;
40.    
41.    TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
42.    TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
43.    TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;  //TIM_OCPolarity_Low,TIM_OCPolarity_High
44.    TIM_OC3Init(TIM2, &TIM_OCInitStructure);
45.    
46.    //5.使能TIMx在CCRx上的预装载寄存器
47.    TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);
48.    
49.    //6.使能 TIMx 在 ARR 上的预装载寄存器允许位
50.    TIM_ARRPreloadConfig(TIM2, ENABLE);
51.    
52.    //4.开启定时器
53.    TIM_Cmd(TIM2, ENABLE); 
54.}
55.void TIM2_CH4_PWM_Iint(u16 per, u16 psc)
56.{
57.    //1.1使能定时器及端口时钟
58.    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
59.    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
60.    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
61.    
62.    //1.2初始化GPIO
63.    GPIO_InitTypeDef GPIO_InitStruct;
64.    
65.    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
66.    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;
67.    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
68.    GPIO_Init(GPIOA, &GPIO_InitStruct);
69.    
70.    //1.3设置引脚复用器映射
71.    GPIO_PinRemapConfig(GPIO_PartialRemap2_TIM2, ENABLE);
72.    
73.    //2.初始化定时器参数,包含自动重装值,分频系数,计数方式等
74.    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
75.    
76.    TIM_TimeBaseInitStructure.TIM_Period=per;
77.    TIM_TimeBaseInitStructure.TIM_Prescaler=psc;
78.    TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
79.    TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
80.    TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
81.    
82.    //3.初始化PWM输出参数,包含PWM模式、输出极性,使能等
83.    TIM_OCInitTypeDef TIM_OCInitStructure;
84.    
85.    TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
86.    TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
87.    TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;  //TIM_OCPolarity_Low, TIM_OCPolarity_High
88.    TIM_OC4Init(TIM2, &TIM_OCInitStructure);
89.    
90.    //5.使能TIMx在CCRx上的预装载寄存器
91.    TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);
92.    
93.    //6.使能 TIMx 在 ARR 上的预装载寄存器允许位
94.    TIM_ARRPreloadConfig(TIM2, ENABLE);
95.    
96.    //4.开启定时器
97.    TIM_Cmd(TIM2, ENABLE); 
98.}
99.void TIM3_CH3_PWM_Iint(u16 per, u16 psc)
100.{
101.    //1.1使能定时器及端口时钟
102.    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
103.    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
104.    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
105.    
106.    //1.2初始化GPIO
107.    GPIO_InitTypeDef GPIO_InitStruct;
108.    
109.    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
110.    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
111.    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
112.    GPIO_Init(GPIOB, &GPIO_InitStruct);
113.    
114.    //1.3设置引脚复用器映射
115.    GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);
116.    
117.    //2.初始化定时器参数,包含自动重装值,分频系数,计数方式等
118.    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
119.    
120.    TIM_TimeBaseInitStructure.TIM_Period=per;
121.    TIM_TimeBaseInitStructure.TIM_Prescaler=psc;
122.    TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
123.    TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
124.    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
125.    
126.    //3.初始化PWM输出参数,包含PWM模式、输出极性,使能等
127.    TIM_OCInitTypeDef TIM_OCInitStructure;
128.    
129.    TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
130.    TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
131.    TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;  //TIM_OCPolarity_Low, TIM_OCPolarity_High
132.    TIM_OC3Init(TIM3, &TIM_OCInitStructure);
133.    
134.    //5.使能TIMx在CCRx上的预装载寄存器
135.    TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
136.    
137.    //6.使能 TIMx 在 ARR 上的预装载寄存器允许位
138.    TIM_ARRPreloadConfig(TIM3, ENABLE);
139.    
140.    //4.开启定时器
141.    TIM_Cmd(TIM3, ENABLE); 
142.}

3.2 PWM.h

1.#ifndef __PWM_H
2.#define __PWM_H
3.#include "system.h"
4.void TIM2_CH3_PWM_Iint(u16 per, u16 psc);
5.void TIM2_CH4_PWM_Iint(u16 per, u16 psc);
6.void TIM3_CH3_PWM_Iint(u16 per, u16 psc);
7.#endif

3.3 direction.c

1.#include "direction.h"
2.
3./* ---------------------------------函数声明-------------------------------------
4.*函数名称:void Direction_Control(void)
5.*输入参数:无
6.*返回参数:无
7.*功    能:电机转动方向控制
8.*作    者:lph
9.*日    期:2024/03/27
10.------------------------------------------------------------------------------ */
11.void Direction_Iint(void)
12.{
13.    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
14.    
15.    GPIO_InitTypeDef GPIO_InitStructure;
16.    
17.    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;   
18. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   
19. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
20. GPIO_Init(GPIOA, &GPIO_InitStructure);      
21. GPIO_ResetBits(GPIOA, GPIO_Pin_4);     
22. 
23. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
24. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;     
25. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
26. GPIO_Init(GPIOA, &GPIO_InitStructure);    
27. GPIO_ResetBits(GPIOA,GPIO_Pin_5);
28.}
29.
30.void Direction_Control(u8 mode, u16 compare)
31.{   
32.    //L298N输入使能
33.    INB_1 = 1;
34.    INB_2 = 1;
35.    if(mode == 1)   //左转
36.    { 
37.        TIM_SetCompare3(TIM2, compare);
38.//        TIM_SetCompare4(TIM2, 0);
39.        TIM_SetCompare3(TIM3, 0);
40.    } 
41.    else if(mode == 2)   //右转
42.    {
43.        TIM_SetCompare3(TIM2, 0);
44.//        TIM_SetCompare4(TIM2, compare);
45.        TIM_SetCompare3(TIM3, compare);
46.    }
47.}

3.4 direction.h

1.#ifndef __direction_H
2.#define __direction_H
3.#include "system.h"
4.#include "PWM.h"
5.// GPIO位带操作
6.#define INB_1   PAout(4)
7.#define INB_2   PAout(5)
8.void Direction_Iint(void);
9.void Direction_Control(u8 mode, u16 compare);
10.#endif

3.5 mian.c

1./* Includes ------------------------------------------------------------------*/
2.#include "stm32f10x.h"
3.#include "system.h"
4.#include "SysTick.h"
5.#include "PWM.h"
6.#include "direction.h"
7.
8./* 主函数main() --------------------------------------------------------------*/
9.int main()
10.{   
11.    // 一.自定义变量
12.
13.    // 二.初始化-------------------
14.    SysTick_Iint(72);
15.    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  // 中断分组
16.    Direction_Iint();
17.    TIM2_CH3_PWM_Iint(65536 - 1, 36 - 1); 
18.    TIM3_CH3_PWM_Iint(65536 - 1, 36 - 1);    
19.    while(1)
20.    {
21.        //电机正反转控制
22.        Direction_Control(2, 65536 - 1);
23.    }
24.}

  • 19
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
1. 首先,需要配置GPIO端口和定时器计数器。 2. 然后,需要编写函数来控制电机的旋转方向和步数。 3. 在主函数中,初始化GPIO和定时器,并使用编写的函数来控制电机的运动。 下面是一个简单的示例代码,用于控制两个环步进电机: ```c #include "stm32f10x.h" #include "hel.h" // 定义GPIO端口 #define MOTOR1_DIR_PORT GPIOA #define MOTOR1_DIR_PIN GPIO_Pin_0 #define MOTOR1_STEP_PORT GPIOA #define MOTOR1_STEP_PIN GPIO_Pin_1 #define MOTOR2_DIR_PORT GPIOA #define MOTOR2_DIR_PIN GPIO_Pin_2 #define MOTOR2_STEP_PORT GPIOA #define MOTOR2_STEP_PIN GPIO_Pin_3 // 定义定时器计数器 #define TIMER_PERIOD 1000 // 定义电机运动方向 #define MOTOR_DIR_FORWARD 1 #define MOTOR_DIR_BACKWARD 0 // 定义电机步数 #define MOTOR_STEPS_PER_REVOLUTION 200 void motor_control(GPIO_TypeDef* dir_port, uint16_t dir_pin, GPIO_TypeDef* step_port, uint16_t step_pin, uint8_t direction, uint16_t steps) { // 设置电机方向 GPIO_WriteBit(dir_port, dir_pin, direction); // 控制电机步数 for (uint16_t i = 0; i < steps; i++) { GPIO_WriteBit(step_port, step_pin, Bit_SET); GPIO_WriteBit(step_port, step_pin, Bit_RESET); } } int main(void) { // 初始化系统时钟和GPIO SystemInit(); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitTypeDef gpio_init = {0}; gpio_init.GPIO_Mode = GPIO_Mode_Out_PP; gpio_init.GPIO_Speed = GPIO_Speed_50MHz; gpio_init.GPIO_Pin = MOTOR1_DIR_PIN | MOTOR1_STEP_PIN | MOTOR2_DIR_PIN | MOTOR2_STEP_PIN; GPIO_Init(GPIOA, &gpio_init); // 初始化定时器 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_TimeBaseInitTypeDef tim_init = {0}; tim_init.TIM_Period = TIMER_PERIOD; tim_init.TIM_Prescaler = SystemCoreClock / TIMER_PERIOD - 1; tim_init.TIM_ClockDivision = TIM_CKD_DIV1; tim_init.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &tim_init); TIM_Cmd(TIM2, ENABLE); // 控制电机运动 while (1) { // 控制电机1顺时针旋转2圈 motor_control(MOTOR1_DIR_PORT, MOTOR1_DIR_PIN, MOTOR1_STEP_PORT, MOTOR1_STEP_PIN, MOTOR_DIR_FORWARD, MOTOR_STEPS_PER_REVOLUTION * 2); // 控制电机2逆时针旋转1圈 motor_control(MOTOR2_DIR_PORT, MOTOR2_DIR_PIN, MOTOR2_STEP_PORT, MOTOR2_STEP_PIN, MOTOR_DIR_BACKWARD, MOTOR_STEPS_PER_REVOLUTION); } } ``` 请注意,此示例代码仅作为参考,实际使用时需要根据具体的硬件和需求进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值