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
相关文章
|
3天前
【STM32】基于HAL库的360度编码器、摇杆代码编写
【STM32】基于HAL库的360度编码器、摇杆代码编写
|
22小时前
|
缓存 网络协议 算法
[蓝桥杯嵌入式]hal库 stm32 PWM的使用(随时修改占空比,随时修改频率)
[蓝桥杯嵌入式]hal库 stm32 PWM的使用(随时修改占空比,随时修改频率)
|
3天前
|
传感器
STM32循迹小车原理介绍和代码示例
STM32循迹小车原理介绍和代码示例
|
3天前
【STM32】通过RTThread驱动W25QXXX
【STM32】通过RTThread驱动W25QXXX
|
3天前
stm32f4外设学习篇(代码集合)(三)
stm32f4外设学习篇(代码集合)
|
3天前
stm32f4外设学习篇(代码集合)(二)
stm32f4外设学习篇(代码集合)
|
3天前
|
芯片
stm32f4外设学习篇(代码集合)(一)
stm32f4外设学习篇(代码集合)