设为首页收藏本站

arduino 单片机机器人爱好者之家

 找回密码
 立即注册

QQ登录

只需一步,快速开始

楼主: aosini

编码器速度和方向检测,371电机方向与速度检测,stm32编码器接口模式

  [复制链接]

该用户从未签到

发表于 2015-12-14 00:24:14 来自手机 | 显示全部楼层
你好,刚用您的例程测试了一下,反转的时候有读数,但是数字跨越太大了(-165,-45,0,-456),改为正转的时候读数全部都是0,调试好久了,还请楼主指点,,,(没有用您的pwm做控制,直接接的电源,程序里面屏蔽了的)
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2015-12-14 00:29:04 来自手机 | 显示全部楼层
本帖最后由 Damon93 于 2015-12-14 00:44 编辑

没有使用您的pwm控制,直接5v电源,调试了很久也没有找到问题,挺急的还请您多多指教
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2015-12-14 00:30:19 来自手机 | 显示全部楼层
我用的是stm32f103
回复 支持 反对

使用道具 举报

签到天数: 63 天

[LV.6]常住居民II

 楼主| 发表于 2015-12-15 09:20:01 | 显示全部楼层

您好,PWM调节的是电机转速,直接加固定电压也是可以的。是STM32F103系列,直接移植应该是没有问题的。
//读计数个数
int TIM2_Encoder_Read(void)
{
    TIM2_Encoder_Write(0);        //计数器清0
        delay_ms(10);          //检测时间,可调节
    return (int)((s16)(TIM2->CNT));           //数据类型转换
                             //记录边沿变化次数(一个栅格被记录4次)
}
我是使用的延时来读取计数值的。
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2015-12-17 00:41:33 来自手机 | 显示全部楼层
aosini 发表于 2015-12-15 09:20
您好,PWM调节的是电机转速,直接加固定电压也是可以的。是STM32F103系列,直接移植应该是没有问题的。
...

您好,通过这几天的调试确实是我理解的问题,现在已经能读取数据了,我推导出了一个公式您给看看,(400线,延时t秒读取出数值为n) 400线得出每条线的间隔为0.9度    角速度=n*0.9/4/t/360   (单位 r/s)  对这个式子拿捏的不是太准,您给看看
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2015-12-17 00:42:50 来自手机 | 显示全部楼层
还有我要实现指定角度旋转,这方面实在没有经验,大致的想法是这样的   在TIM2_Encoder_Init函数里加入计数中断,设置一个计数值,超过这个值时进入中断,关闭PWM使能端。 但是这个计数中断怎么写在函数里面一点头绪都没有,您能给写一个参考吗,麻烦您了
回复 支持 反对

使用道具 举报

签到天数: 63 天

[LV.6]常住居民II

 楼主| 发表于 2015-12-17 08:04:02 | 显示全部楼层
Damon93 发表于 2015-12-17 00:42
还有我要实现指定角度旋转,这方面实在没有经验,大致的想法是这样的   在TIM2_Encoder_Init函数里加入计数 ...

公式应该是对的。
您可以通过定时中断来读计算寄存器TIM2->CNT的值。当TIM2->CNT的值达到您想要的值时,就执行关闭PWM使能。
回复 支持 反对

使用道具 举报

该用户从未签到

发表于 2015-12-17 09:04:38 来自手机 | 显示全部楼层
aosini 发表于 2015-12-17 08:04
公式应该是对的。
您可以通过定时中断来读计算寄存器TIM2->CNT的值。当TIM2->CNT的值达到您想要的值时, ...

谢谢您的回复,定时中断按一定时间去刷新读取cnt的值,我想过,但是这个略有误差,即如果刷新读取的间隔太大,电机停止位置就会有偏差,而且会占用一个定时器,能否用计数溢出中断?这种中断不知是否可行?一直想这么写但不知道如何编程
回复 支持 反对

使用道具 举报

签到天数: 63 天

[LV.6]常住居民II

 楼主| 发表于 2015-12-19 14:18:25 | 显示全部楼层
Damon93 发表于 2015-12-17 09:04
谢谢您的回复,定时中断按一定时间去刷新读取cnt的值,我想过,但是这个略有误差,即如果刷新读取的间隔 ...
您好,是可以的,在编码器时,使用计数器溢出中断。给个参考程序,您试一下。
[AppleScript] 纯文本查看 复制代码
//TIM2_Encoder_Init,Tim2_CH1(PA0);Tim2_CH2(PA1)
//arr:自动重装值 0XFFFF
//psc:时钟预分频数        ,不分频
void TIM2_Encoder_Init_1(u16 arr,u16 psc)
{
    RCC->APB1ENR|=1<<0;       //TIM2时钟使能
        RCC->APB2ENR|=1<<2;       //使能PORTA时钟
        
    GPIOA->CRL&=0XFFFFFF00;   //PA0、PA1 清除之前设置
    GPIOA->CRL|=0X00000044;   //PA0、PA1 浮空输入
            
    TIM2->ARR=arr;            //设定计数器自动重装值 
    TIM2->PSC=psc;            //预分频器

        TIM2->CCMR1 |= 1<<0;          //输入模式,IC1FP1映射到TI1上
        TIM2->CCMR1 |= 1<<8;          //输入模式,IC2FP2映射到TI2上
        TIM2->CCER |= 0<<1;                  //IC1不反向
        TIM2->CCER |= 0<<5;           //IC2不反向
    TIM2->SMCR |= 3<<0;                  //所用输入均在上升沿或下降沿有效
        TIM2->DIER|=1<<0;   //允许更新中断                                
        TIM2->DIER|=1<<6;   //允许触发中断
        TIM2->CR1 |= 1<<0;                  //使能计数器
         MY_NVIC_Init(1,3,TIM2_IRQChannel,2);//抢占1,子优先级3,组2        
}
//定时器2中断服务程序         
void TIM2_IRQHandler(void)
{                                                          
        if(TIM2->SR&0X0001)//溢出中断
        {                
                Motor_Speed_Control( 0);//刹车                                                                                                                        
        }                                   
        TIM2->SR&=~(1<<0);//清除中断标志位             
}

初始化void TIM2_Encoder_Init_1(u16 arr,u16 psc);这条语句。
例:初始化TIM2_Encoder_Init_1(1360, 0);340线,一圈检测到*4=1360个脉冲,也就是电机转一圈,然后刹车停止。
但是,这直流电机定位不准确,除非电机转动很慢的状况下才能实现,不然由于惯性,电机还是不能停在设定位置,建议直接使用步进电机,定位更加准确。
回复 支持 反对

使用道具 举报

签到天数: 27 天

[LV.4]偶尔看看III

发表于 2016-1-24 18:04:52 | 显示全部楼层
请问这是虾米电机?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|联系我们|YFRobot ( 苏ICP备13017135  

GMT+8, 2018-12-11 02:25 , Processed in 0.163214 second(s), 19 queries .

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表