单片机/MCU论坛
直播中

武瑭

6年用户 29经验值
擅长:控制/MCU
私信 关注
[讨论]

基于STM32,使用霍尔传感器测量两次脉冲之间的时间,怎么都测不准,打印出来的时间跟实际时间相差很远

本帖最后由 wooten_2017 于 2018-1-25 11:39 编辑

#include "public.h"
#include "Systick.h"
#include "led.h"
#include "usart.h"
#include "inputcapture.h"
#include "ADC.h"


extern float bohelunzhuansu;


//extern u32 timer_times;//定时器溢出次数
//extern u16 BOHELUN_PI_STA;                                         
//extern u32        BOHELUN_PI_VAL[2];       




int main()
{
        u8 i=0;


  SysTick_Init(72);//初始化时钟源               
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级分组
        LED_Init();
  USART1_Init(9600);
        TIM3_Cap_Init(1000,71);    //定时器周期ARR=1000,时钟频率1MHZ,一个更新中断周期1ms


        while(1)
         {
                 printf("转一圈时间 %.2fsrn",bohelunzhuansu);
                   if(i%20==0)
                         {
                         led1=!led1;
                         }
                         delay_ms(500);


         }
                 
}






#include "inputcapture.h"
//采用定时器5的通道1进行输入捕获
float bohelunzhuansu=0;
//int gedaosudu=0;
//int jiaolongzhuansu=0;


u32 timer_times;//定时器溢出次数
u16 BOHELUN_PI_STA;                                         
u32        BOHELUN_PI_VAL;       




TIM_ICInitTypeDef  TIM3_ICInitStructure;
void TIM3_Cap_Init(u16 arr,u16 psc)
{         
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  NVIC_InitTypeDef NVIC_InitStructure;


        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);         //使能定时器3
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //设置端口时钟,对时钟使能,根据原理图可以发现TIM3_CH1对应的是PA6管脚
       
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_6;            //设置端口   +
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;          //设置GPIO输出模式为上拉输入,这样默认电平是高电平,当传感器接收到信号后变成低电平。||*****************************此处需要根据霍尔传感器的特性决定
        GPIO_Init(GPIOA, &GPIO_InitStructure);                 //初始化  
        GPIO_ResetBits(GPIOA,GPIO_Pin_6);                      //既然是上拉输入,那么先把电压置1
  
//  GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;  
//        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
//        GPIO_Init(GPIOB, &GPIO_InitStructure);
//        GPIO_ResetBits(GPIOB,GPIO_Pin_0);       
       


        TIM_TimeBaseStructure.TIM_Period = arr;            //定时器周期
        TIM_TimeBaseStructure.TIM_Prescaler =psc;                 //分频系数
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;  //时钟分频,1分频,没有滤波作用
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数功能
        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);                   //初始化定时器
  
//设置TIM3_CH1的输入捕获功能         
        TIM3_ICInitStructure.TIM_Channel = TIM_Channel_1;           //通道1   
        TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;         //下降沿捕获       
        TIM3_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //直接映射到TI1,因为根据手册200页的框图,IC1会被映射到TI1和TI2,所以需选择
        TIM3_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;           //不分频       
        TIM3_ICInitStructure.TIM_ICFilter = 0x00;                      //无滤波       
        TIM_ICInit(TIM3, &TIM3_ICInitStructure);                          //完成TIM3_CH1初始化配置
       
//        TIM3_ICInitStructure.TIM_Channel = TIM_Channel_2;
//        TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;       
//        TIM3_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
//        TIM3_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;         
//        TIM3_ICInitStructure.TIM_ICFilter = 0x00;
//        TIM_ICInit(TIM3, &TIM3_ICInitStructure);
       
//        TIM3_ICInitStructure.TIM_Channel = TIM_Channel_3;
//        TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;       
//        TIM3_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
//        TIM3_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;          
//        TIM3_ICInitStructure.TIM_ICFilter = 0x00;
//        TIM_ICInit(TIM3, &TIM3_ICInitStructure);




        //NVIC结构体初始化,初始化结构体成员   
        NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;  
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);  
       
        TIM_ITConfig(TIM3,TIM_IT_Update|TIM_IT_CC1,ENABLE);          //开启定时器溢出计数的更新中断和通道1的输入捕获中断,这个根据200页的原理图可以看出,每一个输入捕获寄存器可以对应4个中断通道       
       
   TIM_Cmd(TIM3,ENABLE );                                 //使能定时器
}



void TIM3_IRQHandler(void)//测频率,对应3路PI
{
        if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)     //当更新中断产生,继续下面操作
                {       
                        TIM_ClearITPendingBit(TIM3, TIM_IT_Update);        //清除更新中断标志
      timer_times++;                                           //产生更新中断的次数加1
                        BOHELUN_PI_STA++;                                  //拨禾轮状态参数加1
//                        GEDAO_PI_STA++;
//                        JIAOLONG_PI_STA++;
                       
                        if(BOHELUN_PI_STA>=2000)//转速太低,小于30r/min         //如果拨禾轮在两次下降沿捕获之间的更新中断次数大于200,也就是意味着两次霍尔开关打开的时间过长,那么就可以认为拨禾轮转速为0
                        {
                                bohelunzhuansu=0;
                        }
//                        if(GEDAO_PI_STA>=200)//转速太低,小于30r/min
//                        {
//                                gedaosudu=0;
//                        }
//                        if(JIAOLONG_PI_STA>=200)//转速太低,小于30r/min
//                        {
//                                jiaolongzhuansu=0;
//                        }
                }


        if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)           //如果产生下降沿捕获,那么继续下列操作
                {
                        TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);             //清空下降沿捕获标志
                        BOHELUN_PI_STA=0;                                     //清空拨禾轮状态标志
                        BOHELUN_PI_VAL=timer_times*1000+TIM_GetCounter(TIM3);//计算此次拨禾轮转一圈所需时间,单位us
                        bohelunzhuansu=(BOHELUN_PI_VAL/1000000);            //计算出拨禾轮转一圈时间,单位s
                }       
               
//        if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)
//                {
//                        TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);  
//                        GEDAO_PI_STA=0;
//                        GEDAO_PI_VAL[0]=GEDAO_PI_VAL[1];       
//                        GEDAO_PI_VAL[1]=timer_times*10000+TIM_GetCounter(TIM3);
//                        gedaosudu=1000000*60/(GEDAO_PI_VAL[1]-GEDAO_PI_VAL[0]);   
//                }
//        if (TIM_GetITStatus(TIM3, TIM_IT_CC3) != RESET)
//                {
//                        TIM_ClearITPendingBit(TIM3, TIM_IT_CC3);  
//                        JIAOLONG_PI_STA=0;
//                        JIAOLONG_PI_VAL[0]=JIAOLONG_PI_VAL[1];       
//                        JIAOLONG_PI_VAL[1]=timer_times*10000+TIM_GetCounter(TIM3);
//                        jiaolongzhuansu=1000000*60/(JIAOLONG_PI_VAL[1]-JIAOLONG_PI_VAL[0]);   
//                }               
}

更多回帖

发帖
×
20
完善资料,
赚取积分