搜索

编码器溢出怎么解决hal库

[复制链接]
广西科技2 发表于 2022-4-23 09:52:48 | 显示全部楼层 |阅读模式
广西科技2
2022-4-23 09:52:48 4 0 看全部
  void TIM4_Init(u16 arr,u16 psc)
  {   ? ? ? ? TIM4_Handler.Instance=TIM4;   ? ? ? ? TIM4_Handler.Init.Prescaler=psc;? ?//分频系数电位器的相关问题可以到网站了解下,我们是业内领域专业的平台,您如果有需要可以咨询,相信可以帮到您,值得您的信赖!   ? ? ? ? TIM4_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;? ? //向上计数器   ? ? ? ? TIM4_Handler.Init.Period=arr;? ?//自动装载值   ? ? ? ? TIM4_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;//时钟分频因子   ? ? ? ?   ? ? ? ? TIM4_Encoder_Handler.EncoderMode=TIM_ENCODERMODE_TI12;   ? ? ? ? TIM4_Encoder_Handler.IC1Filter=0;   ? ? ? ? TIM4_Encoder_Handler.IC1Polarity=TIM_ICPOLARITY_RISING;   ? ? ? ? TIM4_Encoder_Handler.IC1Prescaler=TIM_ICPSC_DIV1;   ? ? ? ? TIM4_Encoder_Handler.IC1Selection=TIM_ICSELECTION_DIRECTTI;   ? ? ? ? ? ? ? ?   ? ? ? ? TIM4_Encoder_Handler.IC2Filter=0;   ? ? ? ? TIM4_Encoder_Handler.IC2Polarity=TIM_ICPOLARITY_RISING;   ? ? ? ? TIM4_Encoder_Handler.IC2Selection=TIM_ICSELECTION_DIRECTTI;   ? ? ? ? TIM4_Encoder_Handler.IC2Prescaler=TIM_ICPSC_DIV1;   ? ? ? ? HAL_TIM_Encoder_Init(&TIM4_Handler,&TIM4_Encoder_Handler);   ? ? ? ?   ? ? ? ? HAL_TIM_Encoder_Start(&TIM4_Handler,TIM_CHANNEL_ALL);   ? ? ? ? HAL_TIM_Encoder_Start_IT(&TIM4_Handler,TIM_CHANNEL_ALL);//开启中断   ? ? ? ? TIM4->CNT=1000;   ? ? __HAL_TIM_ENABLE_IT(&TIM4_Handler,TIM_IT_UPDATE);? ?//使能更新中断   ? ? __HAL_TIM_ENABLE(&TIM4_Handler);   }   在这里我们配置编码器模式,开启时钟和溢出中断   //回调函数,定时器中断服务函数调用   void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)   {   ? ? ? ? if(htim==(&TIM4_Handler))   ? ? ? ? {   ? ? ? ? ? ? ? ? if ( (TIM4->CR1&0x0010) == 0 )//向上计数溢出 ? ? ? ? ? ? ? {   ? ? ? ? ? ? ? ? ? ? ? ? Interupt_Num++ ;   ? ? ? ? ? ? ? ? }   ? ? ? ? ? ? ? ? else //向下计数溢出   ? ? ? ? ? ? ? ? {   ? ? ? ? ? ? ? ? ? ? ? ? Interupt_Num-- ;   ? ? ? ? ? ? ? ? }? ? ? ? ? ? ? ?   ? ? ? ? }   }   在中断回调函数里,我们将TIM4->CR1的第5位不变,假如第五位是0,应选择递增计数,我们让计数器增加1。(0x0010==0000 0000 0001 0000)这里的次数我们是在计算溢出次数。要注意我们在TIM4_Init()?是把计数器CNT的值设为了1000,而ARR设置成了2000,这样计数器每次开始工作都是从1000->2000,0->2000,0->2000这样循环,Interupt_Num的值就是我们记录的溢出总数,而最开始的一次溢出是从1000开始,所以总的脉冲数就是 (溢出总数-1)*2000+1000(最开始的1000)+ CNT(计数器内未达到2000的值),之所以用溢出总数-1是因为我们总的脉冲数里把最开始1000->2000的值加进去了,所以要减去1000->2000的一次溢出次数。   TIM4_Init(2000,3);在主函数内初始化TIM4时设置了ARR为2000。   void Circle_Print()   {? ? ? ?   ? ? ? ? AAA =Pulse_Num;   ? ? ? ? if (Interupt_Num ==0 )? ? ? ? ? ? ? ? ? ? ? ? //CNT从1000开始,刚开始的时候计算脉冲的方法   ? ? ? ? ? ? ? ? Pulse_Num = TIM4->CNT-1000 ;   ? ? ? ? else   ? ? ? ? {   ? ? ? ? ? ? ? ? Pulse_Num = 1000 + (Interupt_Num - 1) *2000 +TIM4->CNT ; //在第一圈完成之后,计算脉冲数多的方法   ? ? ? ? }   ? ? ? ? speed =(Pulse_Num-AAA);//每100ms转过的脉冲,近似看成速度了   ? ? ? ? Circle_NUm =Pulse_Num/1560.0f? ? ? ? ? ? ? ? ; ? ? ? ? ? ? ? ? //所有人脉冲除以细分数就可以得到转的圈数(正负之分)   ? ? ? ? printf("Interupt_Num的值是:%ld--捕获到的总数是%ld*****转过的圈数是%f*****本次脉冲为%f\r   " , Interupt_Num, Pulse_Num , Circle_NUm ,speed );   }   AAA是我设置用来计算速度的变量。在每次最开始调用Circle_Print()的时候我们首先把测过的总的脉冲数赋给变量AAA,此时AAA=0,,然后在Pulse_Num = 1000 + (Interupt_Num - 1) *2000 +TIM4->CNT ; //在第一圈完成之后,计算脉冲数多的方法这一句计算总的脉冲数,计算原理我们已经在上一条说过了。然后在这一句speed =(Pulse_Num-AAA);我们用至今为此总的脉冲数减去AAA即为每两次调用Circle_Print()的脉冲差,而我们在主函数中使用一个100ms的延时,所以时间差为100ms,脉冲反映小车路程,可以得到速度。   ***硬件***   我使用的编码器(6线,分AB相,客服叫做13相?不太懂)转一圈是390个脉冲,使用四倍频,转一圈即为1560个脉冲。用总脉冲数除以1560即为至今为止转过的圈数。   小车直径为6.3cm(没找到参数,手动测量的0.0),周长约为0.204m.   ***下载验证***   ?可以看到,第一个返回总的溢出数,第二个为总圈数,第三个为速度。   因为在主函数中使用一个100ms的延时,每0.1秒转过的脉冲数为160左右,约为0.1圈,每秒转过1圈。   ***tips***   在@北名茗水 的中断回调函数程序里有一句PB0!=PB0;而我的电机一IN1接的就是PB0,我改的时候忘记删掉了这句,然后我的第一个轮子(编码器接的第二个轮子)就一会转一会不转0.0   在文件中写入了函数之后要在头文件和主函数里添加初始化,否则不会识别。   TIM4_Init(2000,3);在主函数内初始化TIM4时设置了ARR为2000。   欢迎批评斧正。   ?   89MVP0O2BU~@CJ){Y]]`JD2.png?(39.54 KB, 下载次数: 5)   ?   
  • 您可能感兴趣
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则 返回列表

查看:4 | 回复:0

巩义百姓在线信息网的使命是整合所有巩义本地资源, 通过网络联系起生活在巩义的每一个人,为人们的沟通、信息和服务的获取创造更加便利的平台.
关于我们
公司简介
发展历程
联系我们
本站站务
友情链接
新手指南
内容审核
商家合作
广告合作
商家入驻
新闻合作

官方微信

手机版

手机APP

Archiver| 手机版| 小黑屋| 巩义百姓在线信息门户网
免责申明:本站所有信息均由网友自由发布,本站不承担由于内容的合法性及真实性所引起的一切争议和法律责任。
Copyright © 2011-2023 Comsenz Inc. All Rights Reserved.   巩义百姓在线 GYBXZX.COM     ICP备案号: ( 豫ICP备15027797号-4 )
快速回复 返回顶部 返回列表