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
相关文章
|
14天前
STM32Cubemx PWM驱动加湿器模拟火山喷发效果
STM32Cubemx PWM驱动加湿器模拟火山喷发效果
34 14
|
14天前
STM32Cubemx PWM驱动SG90舵机
STM32Cubemx PWM驱动SG90舵机
34 13
|
14天前
STM32CubeMX mpu6050驱动
STM32CubeMX mpu6050驱动
32 10
|
14天前
STM32CubeMX WS2812B灯驱动
STM32CubeMX WS2812B灯驱动
19 1
|
14天前
STM32CubeMX ULN2003步进电机驱动
STM32CubeMX ULN2003步进电机驱动
14 0
|
14天前
STM32Cubemx TB6612直流电机驱动
STM32Cubemx TB6612直流电机驱动
16 0
|
17天前
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
|
1月前
使用STM32F103标准库实现定时器控制LED点亮和关闭
通过这篇博客,我们学习了如何使用STM32F103标准库,通过定时器来控制LED的点亮和关闭。我们配置了定时器中断,并在中断处理函数中实现了LED状态的切换。这是一个基础且实用的例子,适合初学者了解STM32定时器和中断的使用。 希望这篇博客对你有所帮助。如果有任何问题或建议,欢迎在评论区留言。
115 2
|
1月前
|
IDE 开发工具
使用STM32F103标准库实现自定义键盘
通过本文,我们学习了如何使用STM32F103标准库实现一个简单的自定义键盘。我们首先初始化了GPIO引脚,然后实现了一个扫描函数来检测按键状态。这个项目不仅能够帮助我们理解STM32的GPIO配置和按键扫描原理,还可以作为进一步学习中断处理和低功耗设计的基础。希望本文对你有所帮助,祝你在嵌入式开发的道路上不断进步!
175 4
|
22天前
|
传感器 编解码 API
【STM32开发入门】温湿度监测系统实战:SPI LCD显示、HAL库应用、GPIO配置、UART中断接收、ADC采集与串口通信全解析
SPI(Serial Peripheral Interface)是一种同步串行通信接口,常用于微控制器与外围设备间的数据传输。SPI LCD是指使用SPI接口与微控制器通信的液晶显示屏。这类LCD通常具有较少的引脚(通常4个:MISO、MOSI、SCK和SS),因此在引脚资源有限的系统中非常有用。通过SPI协议,微控制器可以向LCD发送命令和数据,控制显示内容和模式。