OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 23170|回复: 9

STM32光电码盘正交编码测速

[复制链接]

21

主题

59

帖子

0

精华

初级会员

Rank: 2

积分
164
金钱
164
注册时间
2013-4-12
在线时间
0 小时
发表于 2013-8-3 10:34:54 | 显示全部楼层 |阅读模式
最近在做STM32正交编码测速,下载了一个貌似官方提供的一个程序,但是看不懂,希望看到贴的大侠不吝赐教。
s16 ENC_Get_Electrical_Angle(void)//s16 int16_t
{
s32 temp;

temp=(s32)(TIM_GetCounter(ENCODER_TIMER))*(s32)(UINT32_MAX/(4*ENCODER_PPR));//s32 int32_t 
return((s16)(temp/65536)); // s16 result
}
/*******************************************************************************
* Function Name : ENC_Clear_Speed_Buffer
* Description   : Clear speed buffer used for average speed calculation  
* Input         : None
* Output         : None
* Return         : None
*******************************************************************************/
void ENC_Clear_Speed_Buffer(void)
{   
u32 i;

for(i=0;i<SPEED_BUFFER_SIZE;i++)
{
hSpeed_Buffer=0;
}
bIs_First_Measurement = 1;
}
/*******************************************************************************
* Function Name : ENC_Calc_Rot_Speed
* Description   : Compute return latest speed measurement 
* Input         : None
* Output         : s16
* Return         : Return the speed in 0.1 Hz resolution.                    
*******************************************************************************/
s16 ENC_Calc_Rot_Speed(void)//int16_t
{   
s32 wDelta_angle;
u16 hEnc_Timer_Overflow_sample_one, hEnc_Timer_Overflow_sample_two;
u16 hCurrent_angle_sample_one, hCurrent_angle_sample_two;
signed long long temp;
s16 haux;

if(!bIs_First_Measurement)
{
// 1st reading of overflow counter    
hEnc_Timer_Overflow_sample_one=hEncoder_Timer_Overflow; 
// 1st reading of encoder timer counter
hCurrent_angle_sample_one=ENCODER_TIMER->CNT;
// 2nd reading of overflow counter
hEnc_Timer_Overflow_sample_two=hEncoder_Timer_Overflow;  
// 2nd reading of encoder timer counter
hCurrent_angle_sample_two=ENCODER_TIMER->CNT;      

// Reset hEncoder_Timer_Overflow and read the counter value for the next
// measurement
hEncoder_Timer_Overflow=0;
haux=ENCODER_TIMER->CNT;   

if(hEncoder_Timer_Overflow!=0) 
{
haux = ENCODER_TIMER->CNT; 
hEncoder_Timer_Overflow = 0;            
}

if(hEnc_Timer_Overflow_sample_one != hEnc_Timer_Overflow_sample_two)
//Compare sample 1 & 2 and check if an overflow has been generated right 
//after the reading of encoder timer. If yes, copy sample 2 result in 
//sample 1 for next process 
hCurrent_angle_sample_one = hCurrent_angle_sample_two;
hEnc_Timer_Overflow_sample_one = hEnc_Timer_Overflow_sample_two;
}

if ( (ENCODER_TIMER->CR1 & TIM_CounterMode_Down) == TIM_CounterMode_Down)  
{
// encoder timer down-counting
wDelta_angle = (s32)(hCurrent_angle_sample_one - hPrevious_angle - 
(hEnc_Timer_Overflow_sample_one) * (4*ENCODER_PPR));
}
else  
{
//encoder timer up-counting
wDelta_angle = (s32)(hCurrent_angle_sample_one - hPrevious_angle + 
(hEnc_Timer_Overflow_sample_one) * (4*ENCODER_PPR));
}

// speed computation as delta angle * 1/(speed sempling time)
temp = (signed long long)(wDelta_angle*SPEED_SAMPLING_FREQ);
temp *= 10;  // 0.1 Hz resolution
temp /= (4*ENCODER_PPR);

} //is first measurement, discard it
else
{
bIs_First_Measurement = 0;
temp = 0;
hEncoder_Timer_Overflow = 0;
haux = ENCODER_TIMER->CNT;       
// Check if Encoder_Timer_Overflow is still zero. In case an overflow IT 
// occured it resets overflow counter and wPWM_Counter_Angular_Velocity
if (hEncoder_Timer_Overflow != 0) 
{
haux = ENCODER_TIMER->CNT; 
hEncoder_Timer_Overflow = 0;            
}
}

hPrevious_angle = haux;  

return((s16) temp);
}
/*******************************************************************************
* Function Name : ENC_Calc_Average_Speed
* Description   : Compute smoothed motor speed based on last SPEED_BUFFER_SIZE
                   informations and store it variable  
* Input         : None
* Output         : s16
* Return         : Return rotor speed in 0.1 Hz resolution. This routine 
                   will return the average mechanical speed of the motor.
*******************************************************************************/
void ENC_Calc_Average_Speed(void)
{   
s32 wtemp;
u32 i;

wtemp = ENC_Calc_Rot_Speed();

/* Compute the average of the read speeds */  
hSpeed_Buffer[bSpeed_Buffer_Index] = (s16)wtemp;
bSpeed_Buffer_Index++;

if (bSpeed_Buffer_Index == SPEED_BUFFER_SIZE) 
{
bSpeed_Buffer_Index = 0;
}

wtemp=0;

for (i=0;i<SPEED_BUFFER_SIZE;i++)
{
wtemp += hSpeed_Buffer;
}
wtemp /= SPEED_BUFFER_SIZE;

hRot_Speed = ((s16)(wtemp));
}
/*******************************************************************************
* Function Name : TIM4_IRQHandler
* Description   : This function handles TIMx Update interrupt request.
                   Encoder unit connected to TIM4
* Input         : None
* Output         : None
* Return         : None
*******************************************************************************/
void TIM4_IRQHandler(void)
{  
/* Clear the interrupt pending flag */
TIM_ClearFlag(ENCODER_TIMER, TIM_FLAG_Update);

if (hEncoder_Timer_Overflow != UINT16_MAX )  
{
hEncoder_Timer_Overflow++;
}
}

自由的代价永远是警惕!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2234
金钱
2234
注册时间
2012-4-30
在线时间
7 小时
发表于 2013-8-3 10:37:46 | 显示全部楼层
回复 支持 反对

使用道具 举报

21

主题

59

帖子

0

精华

初级会员

Rank: 2

积分
164
金钱
164
注册时间
2013-4-12
在线时间
0 小时
 楼主| 发表于 2013-8-3 10:45:54 | 显示全部楼层
回复【2楼】lsj9383:
---------------------------------
temp=(s32)(TIM_GetCounter(ENCODER_TIMER))*(s32)(UINT32_MAX/(4*ENCODER_PPR));//s32 int32_t 
return((s16)(temp/65536)); // s16 result
这个怎么理解,看的一头雾水。
自由的代价永远是警惕!
回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2234
金钱
2234
注册时间
2012-4-30
在线时间
7 小时
发表于 2013-8-3 13:26:21 | 显示全部楼层
回复【3楼】西北风:
---------------------------------
没看过这个。
这个自己写吧,不难的。
回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2234
金钱
2234
注册时间
2012-4-30
在线时间
7 小时
发表于 2013-8-3 13:31:52 | 显示全部楼层
你只需要开一个定时器,周期性获得定时器值,将t时刻的定时器值cnt(t), 减去t-1时刻的定时器值cnt(t-1),变可以得到该时间内定时器值的改变量delta cnt, delta cnt可以转换成变换角度delta degree。
改变的角度/采样周期T,便可以得到两点的斜率( (t, cnt(t)) 和 (t, cnt(t-1)) 这两点的斜率),当采样周期足够短,便可近似看成角度函数的微分值,也就是对应的角速度。
回复 支持 反对

使用道具 举报

21

主题

59

帖子

0

精华

初级会员

Rank: 2

积分
164
金钱
164
注册时间
2013-4-12
在线时间
0 小时
 楼主| 发表于 2013-8-3 17:40:35 | 显示全部楼层
回复【5楼】lsj9383:
---------------------------------
好吧,我先琢磨琢磨那个,然后在试这个吧,看了几天了,不想半途而废,谢谢。
自由的代价永远是警惕!
回复 支持 反对

使用道具 举报

21

主题

59

帖子

0

精华

初级会员

Rank: 2

积分
164
金钱
164
注册时间
2013-4-12
在线时间
0 小时
 楼主| 发表于 2013-8-5 06:47:27 | 显示全部楼层
回复【5楼】lsj9383:
---------------------------------
如何将delta cnt转换成变换角度delta degree?
自由的代价永远是警惕!
回复 支持 反对

使用道具 举报

108

主题

1433

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2234
金钱
2234
注册时间
2012-4-30
在线时间
7 小时
发表于 2013-8-5 09:10:08 | 显示全部楼层
回复【7楼】西北风:
---------------------------------
一圈脉冲数是x,
你感觉现在的脉冲改变为delta x
怎么转换成变化的角度delta degree?
回复 支持 反对

使用道具 举报

13

主题

51

帖子

0

精华

初级会员

Rank: 2

积分
143
金钱
143
注册时间
2014-12-12
在线时间
4 小时
发表于 2014-12-29 15:19:45 | 显示全部楼层
新手,学习了!
回复 支持 反对

使用道具 举报

5

主题

46

帖子

0

精华

初级会员

Rank: 2

积分
94
金钱
94
注册时间
2015-4-30
在线时间
2 小时
发表于 2015-5-25 10:52:50 | 显示全部楼层
新手。。。。正在学习。。。。
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-22 06:41

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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