zoukankan      html  css  js  c++  java
  • 输入捕获实验

    这个实验的效果是:按住按钮,然后放开,串口会打印按住的时间.

    捕获原理如图。计数器有捕获功能。没有捕获的时候,定时器也可以在工作。设置为上升沿捕获,有上升沿的时候,会触发中断进入中断函数。

    先把定时器清零。然后在捕获期间,定时器会溢出,要计算溢出的次数。同时在中断函数中,已经修改为下降沿捕获了。

    在下降沿捕获的时候,读取当时的计数器的值。这样再加上溢出的次数,就能算出总时间了。

    中断函数的流程图如下:

    函数代码如下:

    
    

    #include "stm32f4xx.h"
    #include "gpio_config.h"
    #include "delay.h"
    #include "usart.h"

    
    

    // GPIO基本配置
    // GPIO的AF映射
    // 中断配置
    // 计时器的基本配置
    // 计时器的捕获配置
    NVIC_InitTypeDef NVIC_InitStructure;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_ICInitTypeDef TIM5_ICInitStructure;
    u8 TIM5CH1_CAPTURE_STA=0;
    u32 TIM5CH1_CAPTURE_VAL;
    int main(void)
    {
    long long temp=0;
    /* Clock Enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE); // enable TIM5 clock

    /* UART1 and delay init */
    delay_init();
    uart_init(115200);

    /* GPIO init */
    GPIO_Init(GPIOA,GpioPortAMode);
    GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_TIM5); //PA0 AF to TIM5

    
    

    /*nvic init */
    NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//
    NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;//
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //
    NVIC_Init(&NVIC_InitStructure); //
    TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新和捕获中断

    /* TIM5 init */
    // 定时器的时钟源有4个,最常用的就是内部时钟源CK_INT。经过选择器以后的时钟,叫做CK_PSC.
    //如果选择了CK_INT做时钟源,CK_INT=CK_PSC
    TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; //即fDTS,是CK_INT与数字滤波器之间的分频比,和计数器的计数频率没关系
    TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数
    TIM_TimeBaseStructure.TIM_Period=0XFFFFFFFF; //就是计数溢出值,也是自动重载值
    TIM_TimeBaseStructure.TIM_Prescaler=83; //计数器的预分频,具体的频率为CK_PSC/(TIM_Perscaler+1)
    TIM_TimeBaseInit(TIM5,&TIM_TimeBaseStructure);

    
    

    /* catch init */
    TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1; //CCER寄存器,是通道选择,TIM5有4个通道
    TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获
    TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //见通用定时器框图,是TI1/2和IC1/2时间的映射关系
    TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //类似捕获滤波,如高电平捕获,可以设置抓到1个高电平就捕获,还是连续8个高电平才捕获
    TIM5_ICInitStructure.TIM_ICFilter = 0x00;//滤波器采样频率
    TIM_ICInit(TIM5, &TIM5_ICInitStructure); //
    TIM_Cmd(TIM5,ENABLE ); //使能定时器5

    
    
    
    
    

    while(1)
    {

    
    

    delay_nms(300);

    if(TIM5CH1_CAPTURE_STA&0x80)
    {
    temp=TIM5CH1_CAPTURE_STA&0X3F;
    temp=temp*0xFFFFFFFF;
    temp+=TIM5CH1_CAPTURE_VAL;
    printf("HIGH:%lld us ",temp);
    TIM5CH1_CAPTURE_STA=0;
    }


    }

    
    


    }

    //捕获状态 TIM5CH1_CAPTURE_STA的定义
    //[7]:0,没有成功的捕获;1,成功捕获到一次.
    //[6]:0,还没捕获到低电平;1,已经捕获到低电平了.
    //[5:0]:捕获低电平后溢出的次数(对于32位定时器来说,1us计数器加1,溢出时间:4294秒)

    void TIM5_IRQHandler(void)
    {

    if((TIM5CH1_CAPTURE_STA&0X80)==0)
    {
    if(TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET) //判断是溢出中断
    {
    if(TIM5CH1_CAPTURE_STA==0x40) //是否已经捕获
    {if((TIM5CH1_CAPTURE_STA&0X3F)==0X3F) //是否溢出太多
    {
    TIM5CH1_CAPTURE_STA=0x80; //溢出次数太多,捕获时间太长,算一次成功捕获。
    TIM5CH1_CAPTURE_VAL=0xFFFFFFFF;
    }
    else TIM5CH1_CAPTURE_STA++; //溢出次数没有太多,溢出次数加1
    }
    }

    if(TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET)  //捕获中断
    {
    if(TIM5CH1_CAPTURE_STA==0x40) //是否已经捕获到高电平
    {
    TIM5CH1_CAPTURE_STA|=0x80; //刚才已经捕获到高电平,这次又捕获,说明捕获到低电平了,就是一次成功的捕获了
    TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); //为下一次捕获做准备
    TIM5CH1_CAPTURE_VAL=TIM_GetCapture1(TIM5); //读取当前计数器的值
    }
    else  //第一次捕获,说明是高电平捕获
    {TIM5CH1_CAPTURE_STA=0x0; 
    TIM5CH1_CAPTURE_VAL=0x0; //计数器清零
    TIM5CH1_CAPTURE_STA|=0x40;
    TIM_Cmd(TIM5,ENABLE );
    TIM_SetCounter(TIM5,0);
    TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling); // 配置为低电平捕获
    TIM_Cmd(TIM5,ENABLE );
    }

    }

    }
    TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update);

    }

    
    
    
    
    








    
    
    
    
    
  • 相关阅读:
    How to build Linux system from kernel to UI layer
    Writing USB driver for Android
    Xposed Framework for Android 8.x Oreo is released (in beta)
    Linux Smartphone Operating Systems You Can Install Today
    Librem 5 Leads New Wave of Open Source Mobile Linux Contenders
    GUADEC: porting GNOME to Android
    Librem 5 – A Security and Privacy Focused Phone
    GNOME and KDE Join Librem 5 Linux Smartphone Party
    Purism计划推出安全开源的Linux Librem 5智能手机
    国产系统之殇:你知道的这些系统都是国外的
  • 原文地址:https://www.cnblogs.com/nasduc/p/4862405.html
Copyright © 2011-2022 走看看