新手上路
- 积分
- 39
- 金钱
- 39
- 注册时间
- 2019-7-22
- 在线时间
- 10 小时
|
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);
}
|
|