OpenEdv-开源电子网

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

关于 直流无刷电机编码盘 测速的问题

[复制链接]

3

主题

11

帖子

0

精华

新手上路

积分
39
金钱
39
注册时间
2019-7-22
在线时间
10 小时
发表于 2019-12-19 21:42:13 | 显示全部楼层 |阅读模式
10金钱
各位,我最近在写一个PWM控制直流无刷电机 通过编码盘反馈 脉冲从而测 速度 的程序,我现在已经把编码盘测脉冲的程序已经写出来了,但是通过脉冲测速度的程序写不出来,写出来的程序测出的速度也不对。  我用定时器3的编码盘模式来连接电机的AB相,用定时器3的中断测溢出的次数,还写了一个函数来测一段时间内的产生的脉冲数,  用定时器5每隔5ms来运行一次测一段时间产生脉冲的那个函数,顺便把测转速的程序也也写在里面。 希望各位可以教教我如何写测转速的程序,或者指出我程序的错误之处,谢谢。

贴上我的代码: 主函数
u16 Speed=1;
float rpm;

u32 cnt_temp;
int main(void)
{  
  LED_Init();
  delay_init();       //延时函数初始化   
  ENCODE_Init(840,1-1);           //编码器初始化  线速:840/4=210
  TIM4_PWM_Init(9,71);  // PWM:500khz
  
   TIM5_Int_Init(50,7200);                     //72M/7200=10Khz,10Khz/50 = 200hz 5ms
  
   delay_ms(500);
    while(1)
{  
    TIM_SetCompare1(TIM4,Speed);
}  
}


void TIM5_IRQHandler(void)                          //定时器5中断服务函数
{
if(TIM_GetITStatus(TIM5,TIM_IT_Update)==SET)      //溢出中断
{  
  cnt_temp=Read_Encoder(); //5ms 内产生的脉冲数
  
  
  rpm=cnt_temp / 210/0.005 ; //  r/s
  
} TIM_ClearITPendingBit(TIM5,TIM_IT_Update);        //清除中断标志位
}
   编码盘程序

# include "encode.h"
int times=0;                                      //编码器溢出次数
u16 Previous_Count;  
u16 Previous_times;
void ENCODE_Init(u16 arr,u16 psc) //TIM3
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
// TIM_OCInitTypeDef  TIM_OCInitStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;   
NVIC_InitTypeDef  NVIC_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器4时钟
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA  , ENABLE);

  //设置该引脚为功能,   
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO

TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位

TIM_ICInitStructure.TIM_Channel=TIM_Channel_1;                  //选择输入端IC1映射到TI1上
  TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;       //上升沿捕获
  TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;   //映射到TI1上
  TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;             //配置输入分频,不分频
  TIM_ICInitStructure.TIM_ICFilter =6;                            //配置输入滤波器
  TIM_ICInit(TIM3,&TIM_ICInitStructure);

TIM_ICInitStructure.TIM_Channel=TIM_Channel_2;                  //选择输入端IC2映射到TI2上
  TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;       //上升沿捕获
  TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;   //映射到TI2上
  TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;             //配置输入分频,不分频
  TIM_ICInitStructure.TIM_ICFilter=6;                             //配置输入滤波器
  TIM_ICInit(TIM3,&TIM_ICInitStructure);

TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising );//编码器配置(定时器、编码模式、上升沿、上升沿)
  
NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn;                   //定时器3中断分组配置
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;                   //使能
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01;      //抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority =0x02;            //响应优先级2
NVIC_Init(&NVIC_InitStructure);                                 //配置定时器3
  
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);                        //允许定时器3更新中断

// TIM_SetCounter(TIM3,0);

TIM_Cmd(TIM3,ENABLE);   

}
void TIM3_IRQHandler(void)                                        //定时器3中断服务函数
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)                    //溢出中断
{   
  times++;      
}
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);                      //清除中断标志位
}

u16 Current_Count;                                              //当前TIM3->CNT的值
u16 curretly_times;                                       //当前转过的圈速
//u16 times_clare;
u32 Read_Encoder(void)
{
u32 Count;                                                      //一段时间内转过的脉冲数
curretly_times=times;                  
  Current_Count = TIM_GetCounter(TIM3);                           //获得当前TIM3->CNT的值
// times_clare = curretly_times - Previous_times;
//  times=0;                                       //清零,方便下次计算
  Count = (u32)((Current_Count - Previous_Count + (curretly_times - Previous_times) * (4*210)/4));   //计算出一个时间转过的脉冲数
  Previous_Count = Current_Count;  
Previous_times = curretly_times;
  return(Count);
}



正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-27 05:39

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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