STM32微项目03:使用PWM控制直流电机运行

一,项目目标

实现利用STM32F103C8T6+TB6612,输出不同占空比输出的PWM波,从而实现电机不同转速的运行、正反转的功能;

 

 二、硬件涉及

1,STM32核心板

2,TB6612直流电机驱动模块

3,直流电机 

三、硬件接线涉及

1,先看TB6612直流电机驱动模块:

①驱动模块是具备两路PWM输入,两路out口,两路AIN,可以实现对两个不同电机的转速控制、方向控制;

②模块引脚

仅使用第一路电机

PWMA控制电机占空比、AIN1 AIN2控制输入、A01 A02电机驱动

核心点:PWM控制电机转速、AIN控制转向、AO用于输出

 

2,STM32核心板接线

四、前置知识介绍

1,定时器输出比较,输出PWM波

见微项目02介绍

 五、代码模块介绍

1,思路分析:

①开始RCC时钟,GPIO和TIM2时钟模块

②开启TIM2时钟输入源为内部72MHZ

③配置时钟模块,ARR和PSC模块

④输出比较模块配置

⑤配置TIM2输出端口的GPIO,复用推挽输出

⑥开始使能时钟

⑦动态配置CCR

⑧配置PA4,PA5控制输出、配置GPIO模块

下面开始代码介绍:

①配置GPIO时钟和TIM2的模块时钟

//配置时钟RCC
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);

②配置TIM2的时钟源,内部时钟72MHZ

//配置时钟源为RCC -72mhz
	TIM_InternalClockConfig(TIM2);

③配置时基模块,主要是ARR和PSC

	//配置时基单元数值
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1 ;
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up ;
	TIM_TimeBaseInitStruct.TIM_Period=100-1;  //ARR
	TIM_TimeBaseInitStruct.TIM_Prescaler=720-1;  //psc
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);

④输出比较单元配置

	//输出比较单元配置
	TIM_OCInitTypeDef TIM_OCInitStruct;
	TIM_OCStructInit(&TIM_OCInitStruct);
	TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1 ;
	
	TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High ;
	
	TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;
	TIM_OCInitStruct.TIM_Pulse=0;//设置CCR数值

	TIM_OC3Init(TIM2, &TIM_OCInitStruct);

⑤配置PWM输出的端口PA2的GPIO  —复用推挽输出

	// 配置PA2端口
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_2;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init( GPIOA, &GPIO_InitStruct);

⑥开启时钟

//启动定时器
	TIM_Cmd(TIM2,ENABLE);

⑦动态配置CCR函数

void pwm_setcompare( uint16_t compare)
{
	TIM_SetCompare3(TIM2, compare);
}

⑧配置PA4,PA5控制输出、配置GPIO模块—推挽输出 

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4 | GPIO_Pin_5;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init( GPIOA, &GPIO_InitStruct);

到此核心代码已经配置完成

具体在代码各个模块的体现

PWM模块

#include "stm32f10x.h"                  // Device header

void pwm_init(void)
{
	//配置时钟RCC
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	
	//配置时钟源为RCC -72mhz
	TIM_InternalClockConfig(TIM2);
	
	//配置时基单元数值
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
	TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1 ;
	TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up ;
	TIM_TimeBaseInitStruct.TIM_Period=100-1;  //ARR
	TIM_TimeBaseInitStruct.TIM_Prescaler=720-1;  //psc
	TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);
	
	//输出比较单元配置
	TIM_OCInitTypeDef TIM_OCInitStruct;
	TIM_OCStructInit(&TIM_OCInitStruct);
	TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1 ;
	
	TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High ;
	
	TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;
	TIM_OCInitStruct.TIM_Pulse=0;//设置CCR数值

	TIM_OC3Init(TIM2, &TIM_OCInitStruct);
	
	// 配置PA2端口
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_2;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init( GPIOA, &GPIO_InitStruct);
	
	//启动定时器
	TIM_Cmd(TIM2,ENABLE);
}

void pwm_setcompare( uint16_t compare)
{
	TIM_SetCompare3(TIM2, compare);
}

motor模块配置,对于pwm模块二次封装和调整

#include "stm32f10x.h"                  // Device header
#include "pwm.h" 

void motor_init(void)
{
	pwm_init();
	//初始化方向控制的PA4 PA5
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4 | GPIO_Pin_5;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init( GPIOA, &GPIO_InitStruct);
	
}

void motor_setspeed(int8_t speed)
{
	if(speed >=0)
	{
		GPIO_SetBits(GPIOA,GPIO_Pin_4);
		GPIO_ResetBits(GPIOA,GPIO_Pin_5);
		pwm_setcompare(speed);
	}
	else
	{
		GPIO_SetBits(GPIOA,GPIO_Pin_5);
		GPIO_ResetBits(GPIOA,GPIO_Pin_4);
		pwm_setcompare(-speed);
	}
}

在主函数的中简单配置

#include "stm32f10x.h"                  // Device header
#include "delay.h"
#include "OLED.H"
#include "motor.H"
#include "key.H"



uint8_t keyn=0;
int8_t speed=0;
int main()
{
	
	OLED_Init();
	motor_init();
	keyinit();
	

	OLED_ShowString(1,1,"SPEED");
	OLED_ShowSignedNum(2,1,speed,3);
	while(1)
	{
		keyn=key_getnum();
		if(keyn==1)
		{
			speed+=20;
			if(speed>100)
			{
				speed=-100;
			}
			OLED_ShowSignedNum(2,1,speed,3);
		}
		motor_setspeed(speed);
	}
}

物联沃分享整理
物联沃-IOTWORD物联网 » STM32微项目03:使用PWM控制直流电机运行

发表评论