源赖氏佐田,哥们说我做的增量尺采集的工装这个采集行程太短了,我想了一下,毕竟16位计数器,一共也就能计数65536个脉冲,一个脉冲5um,一共也就300多厘米,嗯,言之有理。改成F4单片机吧,还得画板发板时间太长了,于是采用计数器级联的方式,增加采集的数值。
首先,思路是这样的:把定时器4设置成主模式,定时器4的从模式设置成编码器模式。负责采集编码器的数值。触发信号选择更新。定时器2设置成从定时器。定时器2的从模式设置成外部1模式。这样4溢出更新,2采集4的溢出值,编码器的最终数值就等于enc=TIM4+(TIM4*TIM2).最终发送到串口,便于观察。开整!
TIM4配置及参数
TIM2配置及参数
串口配置及参数。
时钟树与下载口不在赘述,网上大神各种配置方法都有。
unsigned int enc = 0;//编码器值。
//初始化函数
void App_Init(void)
{
HAL_TIM_Encoder_Start(&htim4,TIM_CHANNEL_ALL); //打开编码器模式接口,AB同时计数。
TIM2 ->CR1 |= 0x01;//开启定时器2
enc = 0;//清空数值
}
//轮询函数
void App_Task(void)
{
int temp = 0;
int temp2 = 0;
int dir=0;
temp = __HAL_TIM_GET_COUNTER(&htim4);//TIM4采集编码器数据
dir = TIM4 ->CR1 &1<<4;//判断主模式运行方向
if(dir)
{
TIM2->CR1 |= (1<<4);//正向
}
else
{
TIM2->CR1 &= (~(1<<4));//反向
}
temp2 = __HAL_TIM_GET_COUNTER(&htim2);//TIM2采集编码器数据
enc = temp + (temp2*(TIM4 ->ARR+1)); //结果=TIM4*(TIM4的溢出值*TIM2)。就是溢出了几次
printf("编码器计数值为:d%",enc);//值发送到串口
}
整完了之后,我发现无论编码器正转、反转,TIM2都是加计数。。。。。
看来事情没那么简单啊。于是在同事的指导下又加了一个判断方向的过程。由于主定时器模式的DIR位只读,而从定时器的DIR位可写,把他俩改成一个方向就好了。
注:
1、写完函数之后,把轮询函数往while(1)里面一丢,初始化函数往主函数一丢,运行一下,效果还行。
2、printf函数可以去网上查询“32单片机重定义串口”
3、初始化函数要放在主函数的外设初始化后面,也就是说要等到所有外设初始化完事了以后,你在去初始化你的函数,要不然人家外设时钟都没开,还初始个啥。。。
4、编码器的值这个变量要放在main函数的上面,或者声明成全局变量在主函数初始化。
5、由于水平有限,含有一部分寄存器操作的代码,但是不影响程序运行,操作寄存器与HAL 库就像用走下地去关闭电视机与用遥控器关闭电视机是一个效果,不必拘泥于这些细节。