【STM32智能小车/模式1】电机驱动功能

前言

本项目基于使用STM32的最基本技术,在实验室独自完成的项目,经过细心调试,不断试错改进,使智能小车呈现不同的功能

一,硬件

配置

  1. STM32F103C8T6最小系统板
  2. TB6612FNG电机驱动模块
  3. 智能小车底盘,4个直流电机
  4. 其余螺丝零件等

连接

PB0 ---> BIN2      PB1 ---> BIN1(电机控制模式输入端)

PB13---> AIN1     PB12---> AIN2

BIN2---> BO2      BIN1---> BO1(电机控制模式输出端)

AIN1---> AO1     AIN2---> AO2

 AO1,AO2   --->   CN5,CN8(左轮)

 BO1,BO2--->   CN9,CN10(右轮)

二,环境配置

略,见

三,代码

1.初始化

  • 在main.c中初始化电机对应的GPIO
TB6612_GPIO_Init(); //初始化AIN和BIN的GPIO
  • 原函数的编写
*********************GPIO控制AIN和BIN*******************************
* @brief 初始TB6612的 AIN1 AIN2 BIN1 BIN2
* @brief 连接AIN1--PB13 AIN2-PB12
			 BIN1--PB1  BIN2--PB0
* @param 
* @return 
*/
void TB6612_GPIO_Init(void)
{
 
 GPIO_InitTypeDef  GPIO_InitStructure;
 	
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	 //使能PB,PE端口时钟
	
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_12|GPIO_Pin_1|GPIO_Pin_0;	    		 //LED1-->PE.5 端口配置, 推挽输出
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
 GPIO_Init(GPIOB, &GPIO_InitStructure);	  				 //推挽输出 ,IO口速度为50MHz
 GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_12|GPIO_Pin_1|GPIO_Pin_0); 						 //PE.5 输出高 
}

2.编写PWM函数

  • PWM函数初始化
  • PWM设置占空比函数
//*********************电机驱动*******************************
	TIM3_PWM_Init(999,1439);   //舵机PWM      =====>   转速
	 
	 //72MHZ/(359+1) = 200000HZ
	 //200000/(1999+1) = 100HZ
	 //arr(1999):自动装载值
	 //psc(359):时钟预分频数
	 //将时钟基准除以psc得到频率
	 //计数到1999+1自动归零
	 
	 //举例:(999,719)
	 //72MHZ/(719+1) = 100000HZ
	 //100000HZ/(999+1) = 100HZ
	TIM1_PWM_Init(1999,359); //电机的PWM  =====>   决定了PWM波的一个周期多长
	
	TIM_SetCompare1(TIM1,500);//	      =====>   PWM波控制转速
	TIM_SetCompare4(TIM1,500);//	      =====>   捕获/比较寄存器的值 为 1000*********	 
  • 定时器1的PWM初始化
//TIM1 PWM部分初始化 
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
/**
* @brief 定时器1的PWM初始化 TIM1CH1--PA8 TIM1CH4--PA11
* @param 
* @return 
*/
void TIM1_PWM_Init(u16 arr,u16 psc)
{  
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);	//使能定时器1时钟
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA  | RCC_APB2Periph_AFIO, ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟
	
	//GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射  TIM3_CH2->PB5    
 
   //设置该引脚为复用输出功能,输出TIM1 CH4的PWM脉冲波形	GPIOA.11
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; //TIM_CH4
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
 
	   //设置该引脚为复用输出功能,输出TIM1 CH1的PWM脉冲波形	GPIOA.8
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //TIM_CH1
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
	
	
   //初始化TIM1
	TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
	TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 
	TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
	
	//初始化TIM1 Channel1 PWM模式	 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
	TIM_OC1Init(TIM1, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM1 OC1

	TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);  //使能TIM1在CCR1上的预装载寄存器
	
		//初始化TIM1 Channel4 PWM模式	 
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
	TIM_OC4Init(TIM1, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM1 OC4

	TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);  //使能TIM1在CCR4上的预装载寄存器
 
	TIM_Cmd(TIM1, ENABLE);  //使能TIM1
	TIM_CtrlPWMOutputs(TIM1,ENABLE);        //MOE 主输出使能,高级定时器必须开启这个

}
  •  PWM波控制转速:相当于用TIMx的一个周期的时间减去这个Compare1,

使得TIMx的周期从后面开始的Compare1的时间为TIMx的前部分时间的反向。即若前部分时间为高电平,则Compare1段所在时间为低电平。若前部分时间为低电平,则Compare1段所在时间为高电平

/**
  * @brief  设置 TIMx 捕捉比较 1 寄存器值
  * @param  TIMx:其中 x 可以是 1 到 17(除了 6 和 7)以选择 TIM 外设。
  * @param  Compare1:指定捕捉比较1寄存器的新值。
  * @retval None
  */
void TIM_SetCompare1(TIM_TypeDef* TIMx, uint16_t Compare1)
{
  /* 检查参数 */
  assert_param(IS_TIM_LIST8_PERIPH(TIMx));
  /* 设置捕捉比较 1 寄存器值 */
  TIMx->CCR1 = Compare1;
}

3.编写电机运动驱动函数

 根据线序来编写,左边两个轮子,一样的线序,右边两个轮子,一样的线序

  • 向前无延时
/**
* @brief 向前无延时
* @param 
* @return 
*/
void Forward(void)
{
		AIN1 =1;			// ===> 此处应该指的是:线序 ,不是轮子
		AIN2 =0;
		BIN1 =1;
		BIN2 =0;
		//数字越大,转速越快
		TIM_SetCompare1(TIM1,1500);	 
	    TIM_SetCompare4(TIM1,1500);

}	
  • 向后无延时
/**
* @brief 向后无延时
* @param 
* @return 
*/
void Backward(void)
{
		AIN1 =0;			// ===> 向前的线序,反向线序,就是向后
		AIN2 =1;			// ===> A ---> 左边两个轮子的线序
		BIN1 =0;			// ===> B ---> 右边两个轮子的线序
		BIN2 =1;
		TIM_SetCompare1(TIM1,1500);	 
	  TIM_SetCompare4(TIM1,1500);

}	
  • 向右无延时

右转:相当于左面的两个电机前进,右边的两个电机后退

/**
* @brief 向右无延时
* @param 
* @return 
右转:相当于右面的两个电机前进,左边的两个电机后退 
*******************    前进  后退
*******************    前进  后退
*/
void Rightward(void)
{
		AIN1 =1;			// ===> A ---> 左边两个轮子的线序  ---> 不用改变
		AIN2 =0;			// ===> 前进 的 线序
		BIN1 =0;			// ===> B ---> 右边两个轮子的线序  ---> 改变
		BIN2 =1;			// ===> 后退 的 线序
		TIM_SetCompare1(TIM1,1500);	 
	  TIM_SetCompare4(TIM1,1500);

}	
  • 向左无延时

左转:相当于右面的两个电机前进,左边的两个电机后退

/**
* @brief 向左无延时
* @param 
* @return 
左转:相当于右面的两个电机前进,左边的两个电机后退
*******************    后退   前进
*******************    后退   前进
*/
void Leftward(void)
{
		AIN1 =0;			// ===> A ---> 左边两个轮子的线序  ---> 改变成后退
		AIN2 =1;			// ===> 后退 的 线序
		BIN1 =1;			// ===> B ---> 右边两个轮子的线序  ---> 不用改变
		BIN2 =0;			// ===> 前进 的 线序
		TIM_SetCompare1(TIM1,1500);	 
	  TIM_SetCompare4(TIM1,1500);

}	

:此处还可以 改变占空比 来调节转向

左边轮子速度慢,右边轮子速度快  ===>  实现 左转

右边轮子速度慢,左边轮子速度快  ===>  实现 右转

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
对于STM32智能小车电机驱动模块,通常会使用PWM信号来控制电机的速度和方向。你可以使用STM32的定时器模块来生成PWM信号,然后通过电机驱动模块将PWM信号转换为电机的控制信号。 一种常见的电机驱动模块是L298N模块,它可以控制两个直流电机的速度和方向。你可以将STM32的PWM信号连接到L298N模块的使能引脚,并使用其他几个引脚来控制电机的方向。 具体的连接和控制方式可以参考相关的引脚图和模块手册。在代码方面,你需要配置STM32的定时器和相关引脚,并编写适当的代码来生成PWM信号。 以下是一个简单的示例代码,假设你使用的是STM32Cube HAL库: ```c #include "stm32f4xx_hal.h" // 定义PWM的周期和占空比 #define PWM_PERIOD 1000 #define PWM_DUTY_CYCLE 500 TIM_HandleTypeDef htim; // 定时器句柄 void MX_TIM_Init(void) { TIM_SlaveConfigTypeDef sSlaveConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_OC_InitTypeDef sConfigOC = {0}; htim.Instance = TIM2; htim.Init.Prescaler = 0; htim.Init.CounterMode = TIM_COUNTERMODE_UP; htim.Init.Period = PWM_PERIOD; htim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; if (HAL_TIM_PWM_Init(&htim) != HAL_OK) { Error_Handler(); } sSlaveConfig.SlaveMode = TIM_SLAVEMODE_DISABLE; sSlaveConfig.InputTrigger = TIM_TS_NONE; if (HAL_TIM_SlaveConfigSynchro(&htim, &sSlaveConfig) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim, &sMasterConfig) != HAL_OK) { Error_Handler(); } sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = PWM_DUTY_CYCLE; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; if (HAL_TIM_PWM_ConfigChannel(&htim, &sConfigOC, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } } void HAL_MspInit(void) { __HAL_RCC_TIM2_CLK_ENABLE(); // 启用定时器2的时钟 } int main(void) { HAL_Init(); MX_TIM_Init(); HAL_TIM_PWM_Start(&htim, TIM_CHANNEL_1); // 启动PWM输出 while (1) { // 控制PWM占空比,即电机速度 __HAL_TIM_SET_COMPARE(&htim, TIM_CHANNEL_1, PWM_DUTY_CYCLE); HAL_Delay(1000); // 反转电机方向 // 如果你的电机驱动模块支持方向控制,可以在这里进行相应的操作 } } ``` 以上是一个简单的示例,可以通过改变PWM_DUTY_CYCLE的值来控制电机的速度。你可以根据你所使用的具体电机驱动模块和硬件进行适当的修改。 请注意,这只是一个基本示例,具体的实现可能会因为硬件和电机驱动模块的不同而有所差异。你需要参考相关的文档和资料,以及根据你的具体需求进行适当的配置和调整。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

零零怪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值