第七章-编码器测速 STM32pwm输出 STM32f103c8t6引脚功能 STM32蓝牙通信 STM32 pwm输出 STM32超声波测距 嵌入式软件开发 STM32cubemx 好家伙VCC

avatar
作者
猴君
阅读量:0

标题第七章-编码器测速

7.1-认识编码器

编码器:一般按照电机尾部、用于测量电机转速、方向、位置。
在这里插入图片描述
那么编码器的输出信号具体是什么?我们如何根据输出信号测量转速 和方向?

转速: 单位时间测量到的脉冲数量(比如根据每秒测量到多少个脉冲来计算转速)

旋转方向: 两通道信号的相对电平关系
在这里插入图片描述

7.2单片机定时器的编码器功能

那么我们已经知道编码器输出的波形,我们如何通过单片机读取波形,然后计算出速度那?

这里STM32单片机的定时器和通用定时器具有编码器接口模式、在STM32中文参考手册13章中有详细介绍

STM32中文参考手册-第200页
在这里插入图片描述
STM32中文参考手册-第267页
在这里插入图片描述
STM32中文参考手册-第226页
在这里插入图片描述
这个是计数方向与编码器信号的关系、我们拆开来看

仅在TI1计数、电机正转、对原始数据二倍频
在这里插入图片描述
仅在TI1计数、电机反转、对原始数据二倍频
在这里插入图片描述
在TI1和TI2都计数

可以看到这样就对原始数据四倍频了

在这里插入图片描述
计数方向
在这里插入图片描述

7.3-获得单位时间计数器值变化量

在这里插入图片描述
上一次说的方法:

这次编码器计数值 = 计数器值+计数溢出次数 * 计数最大器计数最大值

计数器两次变化值 = 这次编码器计数值 - 上次编码器计数值

然后根据这个单位变化量计算速度

还有一种方法:

计数器变化量 = 当前计数器值

每次计数值清空

然后根据这个变化量 计算速度

然后我们再看具体到哪一款电机和编码器上如何测速
在这里插入图片描述
在STM32中文参考手册-第119页
在这里插入图片描述
在这里插入图片描述
设置TIM2

在这里插入图片描述
设置ITM2滤波器
在这里插入图片描述
在这里插入图片描述
同理设置TIM4
在这里插入图片描述
设置TIM4滤波器
在这里插入图片描述
在这里插入图片描述
设置引脚上拉
在这里插入图片描述
生成代码
开启定时器和定时中断
在这里插入图片描述

  HAL_TIM_Encoder_Start(&htim2,TIM_CHANNEL_ALL);//开启定时器2   HAL_TIM_Encoder_Start(&htim4,TIM_CHANNEL_ALL);//开启定时器4   HAL_TIM_Base_Start_IT(&htim2);				//开启定时器2 中断   HAL_TIM_Base_Start_IT(&htim4);                //开启定时器4 中断 

在定义两个变量保存计数器值
在这里插入图片描述

short Encoder1Count = 0;//编码器计数器值 short Encoder2Count = 0; 

每2ms读取计数器值->清零计数器
在这里插入图片描述

	Motor_Set(0,0); 	//1.保存计数器值 	Encoder1Count =(short)__HAL_TIM_GET_COUNTER(&htim4); 	Encoder2Count =(short)__HAL_TIM_GET_COUNTER(&htim2); 	//2.清零计数器值 	__HAL_TIM_SET_COUNTER(&htim4,0); 	__HAL_TIM_SET_COUNTER(&htim2,0); 	 	printf("Encoder1Count:%d\r\n",Encoder1Count); 	printf("Encoder2Count:%d\r\n",Encoder2Count);	 	 	HAL_Delay(2); 

接好电池、烧录代码、串口一连接电脑

用手转动电机1或者电机2 、串口助手可以看到输出信息了
在这里插入图片描述

7.4-主函数周期测量转速

上面我们测量出来了溢出值,我们再根据当前计数器值就可以测量出计数器变化量,我们通过单位时间变量就可以计算出转速

下面是电机和编码器的参数
在这里插入图片描述
我们先测试的结论是否有问题?

  1. 编码器计数器会不会在计数时间内溢出?
  2. 车轮旋转一周,单片机编码器计数器计数多少?9.6乘11乘4
  3. 根据计算方法计算电机转速

定义两个float变量
在这里插入图片描述

float Motor1Speed = 0.00; float Motor2Speed = 0.00; 

下面是代码(一定要把主函数没有用的删除掉)
在这里插入图片描述

	//计算速度 	Motor1Speed = (float)Encode1Count*100/9.6/11/4; 	Motor2Speed = (float)Encode2Count*100/9.6/11/4; 	 	printf("Motor1Speed:%.2f\r\n",Motor1Speed); 	printf("Motor2Speed:%.2f\r\n",Motor2Speed); 

编译烧录代码就会输出结果
在这里插入图片描述

7.5-定时器中断定时测量速度

上面我们实现:在主函数周期,读取计数器值然后计算速度,但是如果函数加入其他内容这个周期时间就很难保证。

所以这节我们通过定时器,周期读取计数器,计算速度。复制一份工程开始搞!
在这里插入图片描述
我们先开启定时器、2ms进入一次定时器中断,中断回调函数执行咱们的代码即可。

为什么充分利用单片机 我们使用TIM1

  1. 设置内部时钟源
  2. 使能自动重装载
    在这里插入图片描述
    开启定义更新中断
    在这里插入图片描述
    代码开启定时器1 中断

在这里插入图片描述

  HAL_TIM_Base_Start_IT(&htim1);                //开启定时器1 中断 

定时器回调函数中添加 速度计算内容
在这里插入图片描述

/******************* *  @brief  定时器回调函数 *  @param   *  @return   * *******************/ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { 	if(htim == &htim1)//htim1 500HZ  2ms 中断一次 	{ 		TimerCount++; 		if(TimerCount %5 == 0)//每10ms执行一次 		{ 			Encode1Count = (short)__HAL_TIM_GET_COUNTER(&htim4); 			Encode2Count = (short)__HAL_TIM_GET_COUNTER(&htim2); 			__HAL_TIM_SET_COUNTER(&htim4,0); 			__HAL_TIM_SET_COUNTER(&htim2,0); 			 			Motor1Speed = (float)Encode1Count*100/9.6/11/4; 			Motor2Speed = (float)Encode2Count*100/9.6/11/4;  			TimerCount=0; 		} 	} } 

把之前的变量定义放这里
在这里插入图片描述

short Encode1Count = 0; short Encode2Count = 0; float Motor1Speed = 0.00; float Motor2Speed = 0.00; uint16_t TimerCount=0; 

主函数就输出速度大小就可以了
在这里插入图片描述

	printf("Motor1Speed:%.2f\r\n",Motor1Speed); 	printf("Motor2Speed:%.2f\r\n",Motor2Speed); 

把变量需要声明一下
在这里插入图片描述

extern float Motor1Speed ; extern float Motor2Speed ; 

然后打开串口助手
在这里插入图片描述
注:

根据电机和实际小车调整速度测量与占空比设置函数
在这里插入图片描述
在这里插入图片描述
我们第七章这样就完成了 ,把程序烧录电机就可以完成测速了。
下篇第八章我们讲解 PID速度控制

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!