STM32:PWM驱动直流电机(内含:1.实验现象+2.代码部分/详细注释)

简介: STM32:PWM驱动直流电机(内含:1.实验现象+2.代码部分/详细注释)

1.接线原理图/实验现象如下:


b50c5bb0a4ab42b39202952c86152278.png

8db2329a5f0f4c7b91d33f58b67e44ff.png

 

2.代码部分:

主函数(main.c)代码部分:


#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Motor.h"
#include "Key.h"
uint8_t KeyNum;
int8_t Speed;//有符合的变量
int main(void)
{
    OLED_Init();
    Motor_Init();
    Key_Init();
    OLED_ShowString(1, 1, "Speed:");
    while(1)
    {
        KeyNum = Key_GetNum();
        if (KeyNum == 1)
        {
            Speed += 20;
            if (Speed > 100)
            {
                Speed = -100;
            }
        }
        Motor_SetSpeed(Speed);//按键控制速度
        OLED_ShowSignedNum(1, 7, Speed, 3);
    }
}

PWM.c代码部分:


#include "stm32f10x.h"                  // Device header
//操作思路可参考:(图PWM基本结构)
//1.RCC开启时钟,把TIM外设和GPIO外设的时钟打开。
//2.初始化时基单元,选择内部时钟-----使用的还是TIM2,所以直接复制粘贴内部时钟部分代码
//3.初始化输出比较单元,(重要函数TIM_OC3Init)包括CCR的值,输出比较模式,极性选择,输出使能。(结构体)
//4.初始化GPIO,(第三步的输出比较模式的值需要GPIO输出展示)TIM_OC3Init,GPIO口初始化为复用推挽输出
//5.运行控制,启动计数器。
void PWM_Init(void)
{
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//第一步:开启APB1时钟,因为TIM2是APB1总线的外设
    TIM_InternalClockConfig(TIM2);//第二步:选择内部时钟
    //第二步:初始化时基单元----TIM_TimeBaseInit的第二个参数是结构体,配置结构体
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
    TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
    //TIM_CKD_DIV1,1分频,不分配;TIM_CKD_DIV2,2分频;TIM_CKD_DIV4,4分频----要求不高时,随意选择
    TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
    //TIM_CounterMode_Up向上计数;TIM_CounterMode_Down向下计数;TIM_CounterMode_CenterAligned1等为中央对齐
    TIM_TimeBaseInitStructure.TIM_Period=100-1;//ARR的值   
    TIM_TimeBaseInitStructure.TIM_Prescaler=36-1;//PSC的值
    TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;
    TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//结构体
    //第三步:初始化输出比较单元,总共有四个,需要3通道,初始化3函数
    TIM_OCInitTypeDef TIM_OCInitStructure;
    TIM_OCStructInit(&TIM_OCInitStructure);//给结构体赋初始值
    //TIM_OCInitStructure.TIM_OCIdleState=;//高级定时器才会用到
    TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;//设置输出比较模式
    //TIM_OCInitStructure.TIM_OCNIdleState=;//高级定时器
    //TIM_OCInitStructure.TIM_OCNPolarity=;//高级定时器才会用到
    TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;//设置输出比较极性,TIM_OCPolarity_High有效电平为高电平
    //TIM_OCInitStructure.TIM_OutputNState=;//高级定时器才会用到
    TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//设置输出使能,TIM_OutputState_Enable使能
    TIM_OCInitStructure.TIM_Pulse=0;//设置CCR寄存器的值。
    TIM_OC3Init(TIM2,&TIM_OCInitStructure);
    //TIM2的引脚复用在PA0上,在引脚说明手册里,默认复用功能对应的引脚不能更改,
    //但是,如果两个外设接在同一引脚,可查找重定义功能更改外设的引脚。
    //如需要用TIM的CH1通道输出PWM.则只能在PA0引脚输出,或在重映射改为PA15,因此需要初始化GPIO的PA0
    //4.初始化GPIO,(使用第三通道)
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//选择复用推挽输出,使外设控制引脚(参照复用开漏/推挽输出图)
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2;//直流电机在通道3输出的PWM
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
    //启动定时器
    TIM_Cmd(TIM2,ENABLE);
}
//通道3
void PWM_SetCompare3(uint16_t Compare)
{
    TIM_SetCompare3(TIM2,Compare);
}

PWM.h代码部分:

#ifndef  __PWM_H
#define  __PWM_H
void PWM_Init(void);
void PWM_SetCompare3(uint16_t Compare);
#endif

直流电机(Motor.c)代码部分:

#include "stm32f10x.h"                  // Device header
#include "PWM.h"//继承PWM模块
//初始化直流电机
void Motor_Init(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//开启GPIOA时钟
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;//电机方向控制脚4,5脚
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化电机方向控制脚
    PWM_Init();//初始化PWM
}
void Motor_SetSpeed(int8_t Speed)//设置速度时要有正有负,表示反转。选择int8_t
{
    if (Speed >= 0)//判断正反转
    {
        GPIO_SetBits(GPIOA, GPIO_Pin_4);//设置一个正转,一个反转
        GPIO_ResetBits(GPIOA, GPIO_Pin_5);
        PWM_SetCompare3(Speed);
    }
    else
    {
        GPIO_ResetBits(GPIOA, GPIO_Pin_4);
        GPIO_SetBits(GPIOA, GPIO_Pin_5);
        PWM_SetCompare3(-Speed);
    }
}

直流电机(Motor.h)代码部分:

#ifndef __MOTOR_H
#define __MOTOR_H
void Motor_Init(void);
void Motor_SetSpeed(int8_t Speed);
#endif
相关文章
|
4月前
|
传感器
手把手在STM32F103C8T6上构建可扩展可移植的DHT11驱动
【8月更文挑战第29天】本文详细介绍在STM32F103C8T6上构建可扩展且可移植的DHT11温湿度传感器驱动的步骤,包括硬件与软件准备、硬件连接、驱动代码编写及测试。通过这些步骤,可根据实际项目需求优化和扩展代码。
153 0
|
5月前
STM32Cubemx PWM驱动加湿器模拟火山喷发效果
STM32Cubemx PWM驱动加湿器模拟火山喷发效果
79 14
|
5月前
STM32CubeMX mpu6050驱动
STM32CubeMX mpu6050驱动
85 10
|
5月前
STM32CubeMX WS2812B灯驱动
STM32CubeMX WS2812B灯驱动
234 1
|
5月前
STM32CubeMX ULN2003步进电机驱动
STM32CubeMX ULN2003步进电机驱动
71 0
|
4月前
|
编解码 算法
掌握PWM:STM32F103实现PWM控制直流电机小风扇
PWM,即脉冲宽度调制(Pulse Width Modulation),是一种广泛应用于电子和电机控制领域的信号编码方法。PWM的核心思想是通过改变数字信号的脉冲宽度来模拟模拟信号的幅度变化,从而达到控制输出功率的目的。
638 0
|
5月前
STM32Cubemx TB6612直流电机驱动
STM32Cubemx TB6612直流电机驱动
178 0
|
6月前
使用STM32F103标准库实现定时器控制LED点亮和关闭
通过这篇博客,我们学习了如何使用STM32F103标准库,通过定时器来控制LED的点亮和关闭。我们配置了定时器中断,并在中断处理函数中实现了LED状态的切换。这是一个基础且实用的例子,适合初学者了解STM32定时器和中断的使用。 希望这篇博客对你有所帮助。如果有任何问题或建议,欢迎在评论区留言。
472 2
|
5月前
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
783 0
|
6月前
|
IDE 开发工具
使用STM32F103标准库实现自定义键盘
通过本文,我们学习了如何使用STM32F103标准库实现一个简单的自定义键盘。我们首先初始化了GPIO引脚,然后实现了一个扫描函数来检测按键状态。这个项目不仅能够帮助我们理解STM32的GPIO配置和按键扫描原理,还可以作为进一步学习中断处理和低功耗设计的基础。希望本文对你有所帮助,祝你在嵌入式开发的道路上不断进步!
533 4