STM32F1 - 库函数配置keil代码 驱动四个直流电机完成运动

//所用系统板为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)
	{
		
			
	}
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值