//所用系统板为STM32F103C8T6,所用引脚为PA0,PA1,PA2,PA3,PB6,PB7,PB8,PB9,每两个控制一个电机
//文章结尾附上完整代码
工程可完成前进,后退,左拐,右拐,转向和停下
关于PWM的知识,我在之前的文章已详细说明
(1)硬件
1.引脚
四路PWM输出分别控制四个电机
2.l298n电机驱动模块
将控制电机的4个io口接到L298N的逻辑输入接口,输出A和输出B分别连接两个电机。12V供电接电源正极,5V供电接单片机5V供电,gnd接电源负极和单片机gnd。
3.运动控制
当控制电机的两个引脚高低电平不一样时,电机会正转或者反转,这部分代码在Motor.c文件
(2)初始化的基本思路
1.初始化GPIO
2.初始化时基单元
3.初始化输出比较单元
4.启动相应的定时器
(3)控制电机的思路
1.封装函数控制单个电机能区分正转和反转,并且能够配速
//Dir = 1 正转
//Dir = 0 反转
void Motor4_SetSpeed(uint8_t Dir, uint16_t Speed)
{
if (Speed > 1000) Speed = 1000;
if (Dir)
{
GPIO_SetBits(GPIOB, GPIO_Pin_6);
GPIO_ResetBits(GPIOB, GPIO_Pin_7);
PWM_SetCompare4(Speed);
}
else if (! Dir)
{
GPIO_SetBits(GPIOB, GPIO_Pin_7);
GPIO_ResetBits(GPIOB, GPIO_Pin_6);
PWM_SetCompare4(Speed);
}
}
2.封装函数完成基本运动
void Car_TurnLeft(uint16_t Speed)
{
Motor1_SetSpeed(0,Speed);
Motor2_SetSpeed(1,Speed);
Motor3_SetSpeed(1,Speed);
Motor4_SetSpeed(0,Speed);
}
代码部分
Motor.h
#ifndef _MOTOR_H
#define _MOTOR_H
void Motor_Init(void);
void Motor1_SetSpeed(uint8_t Dir, uint16_t Speed);
void Motor2_SetSpeed(uint8_t Dir, uint16_t Speed);
void Motor3_SetSpeed(uint8_t Dir, uint16_t Speed);
void Motor4_SetSpeed(uint8_t Dir, uint16_t Speed);
void Car_Stop(void);
void Car_Forward(uint16_t Speed);
void Car_Backward(uint16_t Speed);
void Car_TurnLeft(uint16_t Speed);
void Car_TurnRight(uint16_t Speed);
void Car_TransLeft(uint16_t Speed);
void Car_TransRight(uint16_t Speed);
#define MOTOR_GPIO_PORT1_CLK RCC_APB2Periph_GPIOA
#define MOTOR_GPIO1_PORT GPIOA
#define MOTOR_GPIO1_Pin GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3
#define MOTOR_GPIO_PORT2_CLK RCC_APB2Periph_GPIOB
#define MOTOR_GPIO2_PORT GPIOB
#define MOTOR_GPIO2_Pin GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9
#endif
Motor.c
#include "stm32f10x.h" // Device header
#include "Motor.h"
#include "PWM.h"
void Motor_Init(void)
{
RCC_APB2PeriphClockCmd(MOTOR_GPIO_PORT1_CLK, ENABLE); //开启时钟
RCC_APB2PeriphClockCmd(MOTOR_GPIO_PORT2_CLK, ENABLE);
//初始化GPIO
GPIO_InitTypeDef GPIO_InitStruture;
GPIO_InitStruture.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruture.GPIO_Pin = MOTOR_GPIO1_Pin;
GPIO_InitStruture.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(MOTOR_GPIO1_PORT, &GPIO_InitStruture);
//初始化GPIO
GPIO_InitStruture.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruture.GPIO_Pin = MOTOR_GPIO2_Pin;
GPIO_InitStruture.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(MOTOR_GPIO2_PORT, &GPIO_InitStruture);
}
//Dir = 1 正转
//Dir = 0 反转
void Motor1_SetSpeed(uint8_t Dir, uint16_t Speed)
{
if (Speed > 1000) Speed = 1000;
if (Dir)
{
GPIO_SetBits(GPIOA, GPIO_Pin_0);
GPIO_ResetBits(GPIOA, GPIO_Pin_1);
PWM_SetCompare1(Speed);
}
else if (! Dir)
{
GPIO_SetBits(GPIOA, GPIO_Pin_1);
GPIO_ResetBits(GPIOA, GPIO_Pin_0);
PWM_SetCompare1(Speed);
}
}
void Motor2_SetSpeed(uint8_t Dir, uint16_t Speed)
{
if (Speed > 1000) Speed = 1000;
if (Dir)
{
GPIO_SetBits(GPIOA, GPIO_Pin_3);
GPIO_ResetBits(GPIOA, GPIO_Pin_2);
PWM_SetCompare2(Speed);
}
else if (! Dir)
{
GPIO_SetBits(GPIOA, GPIO_Pin_2);
GPIO_ResetBits(GPIOA, GPIO_Pin_3);
PWM_SetCompare2(Speed);
}
}
void Motor3_SetSpeed(uint8_t Dir, uint16_t Speed)
{
if (Speed > 1000) Speed = 1000;
if (Dir)
{
GPIO_SetBits(GPIOB, GPIO_Pin_9);
GPIO_ResetBits(GPIOB, GPIO_Pin_8);
PWM_SetCompare3(Speed);
}
else if (! Dir)
{
GPIO_SetBits(GPIOB, GPIO_Pin_8);
GPIO_ResetBits(GPIOB, GPIO_Pin_9);
PWM_SetCompare3(Speed);
}
}
void Motor4_SetSpeed(uint8_t Dir, uint16_t Speed)
{
if (Speed > 1000) Speed = 1000;
if (Dir)
{
GPIO_SetBits(GPIOB, GPIO_Pin_6);
GPIO_ResetBits(GPIOB, GPIO_Pin_7);
PWM_SetCompare4(Speed);
}
else if (! Dir)
{
GPIO_SetBits(GPIOB, GPIO_Pin_7);
GPIO_ResetBits(GPIOB, GPIO_Pin_6);
PWM_SetCompare4(Speed);
}
}
void Car_Stop(void)
{
Motor1_SetSpeed(1, 0);
Motor2_SetSpeed(1, 0);
Motor3_SetSpeed(1, 0);
Motor4_SetSpeed(1, 0);
}
void Car_Forward(uint16_t Speed)
{
Motor1_SetSpeed(1, Speed);
Motor2_SetSpeed(1, Speed);
Motor3_SetSpeed(1, Speed);
Motor4_SetSpeed(1, Speed);
}
void Car_Backward(uint16_t Speed)
{
Motor1_SetSpeed(0, Speed);
Motor2_SetSpeed(0, Speed);
Motor3_SetSpeed(0, Speed);
Motor4_SetSpeed(0, Speed);
}
void Car_TurnLeft(uint16_t Speed)
{
Motor1_SetSpeed(0,Speed);
Motor2_SetSpeed(1,Speed);
Motor3_SetSpeed(1,Speed);
Motor4_SetSpeed(0,Speed);
}
void Car_TurnRight(uint16_t Speed)
{
Motor1_SetSpeed(1,Speed);
Motor2_SetSpeed(0,Speed);
Motor3_SetSpeed(0,Speed);
Motor4_SetSpeed(1,Speed);
}
void Car_TransLeft(uint16_t Speed)
{
Motor1_SetSpeed(1,Speed);
Motor2_SetSpeed(0,Speed);
Motor3_SetSpeed(1,Speed);
Motor4_SetSpeed(0,Speed);
}
void Car_TransRight(uint16_t Speed)
{
Motor1_SetSpeed(0,Speed);
Motor2_SetSpeed(1,Speed);
Motor3_SetSpeed(0,Speed);
Motor4_SetSpeed(1,Speed);
}
PWM.h
#ifndef _PWM_H
#define _PWM_H
void PWM_Init(void);
//void PWM_SetPrescaler(uint16_t Prescaler);
void PWM_SetCompare1(uint16_t Compare);
void PWM_SetCompare2(uint16_t Compare);
void PWM_SetCompare3(uint16_t Compare);
void PWM_SetCompare4(uint16_t Compare);
#define PWM_GPIO_PORT_CLK RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB
#define PWM_TIM_PORT_CLK RCC_APB1Periph_TIM3
#define PWM_GPIO1_PORT GPIOA
#define PWM_GPIO1_Pin GPIO_Pin_6|GPIO_Pin_7
#define PWM_GPIO2_PORT GPIOB
#define PWM_GPIO2_Pin GPIO_Pin_0|GPIO_Pin_1
#define PWM_TIM TIM3
#endif
PWM.c
#include "stm32f10x.h" // Device header
#include "PWM.h"
void PWM_Init(void) //初始化PWM
{
RCC_APB1PeriphClockCmd(PWM_TIM_PORT_CLK, ENABLE); //打开时钟
RCC_APB2PeriphClockCmd(PWM_GPIO_PORT_CLK, ENABLE); //开启时钟
//初始化ENA ENB GPIO
GPIO_InitTypeDef GPIO_InitStruture;
GPIO_InitStruture.GPIO_Mode = GPIO_Mode_AF_PP; //只有在复用情况下,片上外设才能控制PWM
GPIO_InitStruture.GPIO_Pin = PWM_GPIO1_Pin;
GPIO_InitStruture.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(PWM_GPIO1_PORT, &GPIO_InitStruture);
GPIO_InitStruture.GPIO_Pin = PWM_GPIO2_Pin;
GPIO_Init(PWM_GPIO2_PORT, &GPIO_InitStruture);
TIM_InternalClockConfig(PWM_TIM); //选择内部时钟
//初始化时基单元
TIM_TimeBaseInitTypeDef TIM_TimeBaseIniture;
TIM_TimeBaseIniture.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseIniture.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseIniture.TIM_Period = 100 - 1; //ARR
TIM_TimeBaseIniture.TIM_Prescaler = 7200 - 1; //PSC
TIM_TimeBaseIniture.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(PWM_TIM, &TIM_TimeBaseIniture);
//初始化输出比较单元
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCStructInit(&TIM_OCInitStructure); //给结构体赋初始值,防止多路PWM输出通道不能输出
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //设置输出比较模式 PWM模式1
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //设置输出比较的极性 有效电平为高电平
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //设置输出使能
TIM_OCInitStructure.TIM_Pulse = 0; //设置CCR
TIM_OC1Init(PWM_TIM, &TIM_OCInitStructure); //PA6
TIM_OC1PreloadConfig(PWM_TIM, TIM_OCPreload_Enable);
TIM_OC2Init(PWM_TIM, &TIM_OCInitStructure); //PA7
TIM_OC2PreloadConfig(PWM_TIM, TIM_OCPreload_Enable);
TIM_OC3Init(PWM_TIM, &TIM_OCInitStructure); //PB0
TIM_OC3PreloadConfig(PWM_TIM, TIM_OCPreload_Enable);
TIM_OC4Init(PWM_TIM, &TIM_OCInitStructure); //PB1
TIM_OC4PreloadConfig(PWM_TIM, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(PWM_TIM, ENABLE);
//启动定时器
TIM_Cmd(PWM_TIM, ENABLE);
}
//void PWM_SetPrescaler(uint16_t Prescaler)
//{
// TIM_PrescalerConfig(PWM_TIM,Prescaler,TIM_PSCReloadMode_Immediate);
//}
void PWM_SetCompare4(uint16_t Compare)
{
TIM_SetCompare4(PWM_TIM, Compare);
}
void PWM_SetCompare3(uint16_t Compare)
{
TIM_SetCompare3(PWM_TIM, Compare);
}
void PWM_SetCompare1(uint16_t Compare)
{
TIM_SetCompare1(PWM_TIM, Compare);
}
void PWM_SetCompare2(uint16_t Compare)
{
TIM_SetCompare2(PWM_TIM, Compare);
}
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "Motor.h"
#include "PWM.h"
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
PWM_Init();
Motor_Init();
// Car_Forward(50);
// Delay_ms(5000);
// Car_Backward(500);
// Delay_ms(5000);
Car_TurnLeft(500);
Delay_ms(5000);
// Car_TurnRight(500);
// Delay_ms(5000);
// Car_TransLeft(500);
// Delay_ms(5000);
// Car_TransRight(500);
// Car_Stop();
while(1)
{
}
}