STM32F103C8T6 HAL库——从零开始的制作平衡小车生活

文章目录

    • 第一步:让小车的轮子转起来
    • 第二步:用编码器测出小车的速度
    • 第三步:读取MPU6050的数据值
    • 第四步:PID
  • 最近在做智能采摘机器人 有时间一定接着更!

最近买了个平衡小车,为了圆我PID梦,买来玩玩,废话不多说,直接开搞

第一步:让小车的轮子转起来

我用的电机是TB6612FNG,想详细了解的话直接去搜手册,给他输出两路PWM还要两个引脚进行高低电平的转换就可以设置前进或者后退了,规则如下
STM32F103C8T6 HAL库——从零开始的制作平衡小车生活_第1张图片
看一下引脚图吧
STM32F103C8T6 HAL库——从零开始的制作平衡小车生活_第2张图片
引脚连接:

PWMA PA11
PWMB PA8
AIN1 PB13
AIN2 PB12
BIN1 PB14
BIN2 PB15

下面开始配置CUBE
首先是SYS:
STM32F103C8T6 HAL库——从零开始的制作平衡小车生活_第3张图片
其次是时钟:
STM32F103C8T6 HAL库——从零开始的制作平衡小车生活_第4张图片
STM32F103C8T6 HAL库——从零开始的制作平衡小车生活_第5张图片

下面开始引脚的设置:
STM32F103C8T6 HAL库——从零开始的制作平衡小车生活_第6张图片
用定时器1,10Hz就够了
STM32F103C8T6 HAL库——从零开始的制作平衡小车生活_第7张图片
生成:
STM32F103C8T6 HAL库——从零开始的制作平衡小车生活_第8张图片

代码部分:
main.h

/* USER CODE BEGIN Private defines */
#define AIN2_Pin GPIO_PIN_12
#define AIN2_GPIO_Port GPIOB
#define AIN1_Pin GPIO_PIN_13
#define AIN1_GPIO_Port GPIOB

#define BIN2_Pin GPIO_PIN_14
#define BIN2_GPIO_Port GPIOB
#define BIN1_Pin GPIO_PIN_15
#define BIN1_GPIO_Port GPIOB
/* USER CODE END Private defines */

main.c

/* USER CODE BEGIN 2 */
	HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);//开启TIM1_CH1
  	HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_4);//开启TIM1_CH4
	HAL_GPIO_WritePin(AIN1_GPIO_Port,AIN1_Pin,GPIO_PIN_RESET);//AIN1为0
	HAL_GPIO_WritePin(AIN2_GPIO_Port,AIN2_Pin,GPIO_PIN_SET);//AIN2位1,反转
	HAL_GPIO_WritePin(BIN1_GPIO_Port,BIN1_Pin,GPIO_PIN_RESET);//BIN1为0
	HAL_GPIO_WritePin(BIN2_GPIO_Port,BIN2_Pin,GPIO_PIN_SET);//BIN2位1,反转
  /* USER CODE END 2 */
 /* USER CODE BEGIN 3 */
		HAL_GPIO_WritePin(AIN1_GPIO_Port,AIN1_Pin,GPIO_PIN_RESET);
		HAL_GPIO_WritePin(AIN2_GPIO_Port,AIN2_Pin,GPIO_PIN_SET);
		HAL_GPIO_WritePin(BIN1_GPIO_Port,BIN1_Pin,GPIO_PIN_RESET);
		HAL_GPIO_WritePin(BIN2_GPIO_Port,BIN2_Pin,GPIO_PIN_SET);
		for(int i=0;i<7100;i++)
		{
			__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_4,i);//让轮子转起来
			HAL_Delay(1);
		}
		for(int j=7100;j>0;j--)
		{
			__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_4,j);
			HAL_Delay(1);
		}
		for(int i=0;i<7100;i++)
		{
			__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,i);
			HAL_Delay(1);
		}
		for(int j=7100;j>0;j--)
		{
			__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,j);
			HAL_Delay(1);
		}
  }
  /* USER CODE END 3 */

第二步:用编码器测出小车的速度

先看原理图
STM32F103C8T6 HAL库——从零开始的制作平衡小车生活_第9张图片
PA0和PA1,PA6和PA7分别是小车的编码器引脚,所以我们在cunbe中将这四个引脚设置为Encoder模式
STM32F103C8T6 HAL库——从零开始的制作平衡小车生活_第10张图片
在cube中设置好编码器之后,我们再设置好串口,异步通信,再打开中断
STM32F103C8T6 HAL库——从零开始的制作平衡小车生活_第11张图片
首先开启编码器

void Encoder_Start(void)   //启动两个编码器. 而编码器初始化HAL_TIM_Encoder_Init()和HAL_TIM_Encoder_MspInit()在main()函数中调用的MX_TIM2_Init()中。
{
	__HAL_TIM_SET_COUNTER(&htim2,0);   //用带参宏设置编码器的初始值为0(涉及正反转的需要)
	__HAL_TIM_SET_COUNTER(&htim3,0);

	HAL_TIM_Encoder_Start_IT(&htim2,TIM_CHANNEL_ALL);   //开启编码器的中断模式,两个定时器通道TI1和TI2是每个编码器的两个信号采集通道.
	HAL_TIM_Encoder_Start_IT(&htim3,TIM_CHANNEL_ALL);

	HAL_TIM_Encoder_Start(&htim2,TIM_CHANNEL_ALL);  //开启两个编码器
	HAL_TIM_Encoder_Start(&htim3,TIM_CHANNEL_ALL);
	
}

读取编码器速度值

int Read_Speed(int TIMx)
{
	int Encoder_Value = 0;
	switch(TIMx)
	{
		case 2: 
			Encoder_Value =(short) __HAL_TIM_GET_COUNTER(&htim2);     //保存编码器计数器的值
			__HAL_TIM_SET_COUNTER(&htim2,0);                   //保存之后要清零,以便下次继续读取.另外每次清零后采样值减0,直接用单位时间的话就可以得出速度信息了.不要麻烦还要减去初值了.
			break;

		case 3: 
			Encoder_Value =(short) __HAL_TIM_GET_COUNTER(&htim3);
			__HAL_TIM_SET_COUNTER(&htim3,0);
			break;
		
		default:
			Encoder_Value = 0;
	}	
	return Encoder_Value;
}

这里是主函数,记得定义encoder2和encoder3

  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
	encoder2=Read_Speed(2);
	encoder3=Read_Speed(3);
	printf("A轮=%d,B轮=%d\n",encoder2,encoder3);
  }
}

输出结果,因为是拿手转的,只能一只手转轮子:
STM32F103C8T6 HAL库——从零开始的制作平衡小车生活_第12张图片

第三步:读取MPU6050的数据值

接下来就是最难的MPU6050了,我这里就不详细讲了,因为我自己对底层也不是很了解

左边我们可以看到XYZ的加速度,和XYZ陀螺仪数值,他们经过ADC转换后的数值通过IIC可以直接输出,但是数值就是纯数值,并不是角度值,然后就去DMP了,DMP在输出去FIMO,我理解就是,可以把MPU6050读取的这些东西,变成四元数,然后再通过IIC输出,就可以变成角度值了

STM32F103C8T6 HAL库——从零开始的制作平衡小车生活_第13张图片
首先我们在CUBE中配置好IIC的SDA线和SCL线
STM32F103C8T6 HAL库——从零开始的制作平衡小车生活_第14张图片
STM32F103C8T6 HAL库——从零开始的制作平衡小车生活_第15张图片
MPU6050的读写程序我就不展示了,因为这些从网络上都能找到,我用的是正点原子的,需要注意的就是我这里用的是硬件的HAL库IIC,之前我们老师说硬件的IIC有点bug,让我们用软件的,但是我试了试硬件的IIC,发现也挺好用的,就不用软件的了

读取结果:
STM32F103C8T6 HAL库——从零开始的制作平衡小车生活_第16张图片
可以看到欧拉角的角度值,这样就可以去调整小车的姿态了

第四步:PID

最近在做智能采摘机器人 有时间一定接着更!

你可能感兴趣的:(stm32,单片机,生活)