• 输入捕获:神舟IV实验


    完全照搬正点原子的实验:http://openedv.com/posts/list/11885.htm

    我使用的库函数

    下面我们介绍输入捕获的配置步骤:

    1)开启TIM5时钟,配置PA0为下拉输入。

    要使用TIM5,我们必须先开启TIM5的时钟(通过APB1ENR设置)。这里我们还要配置PA0为下拉输入,因为我们要捕获TIM5_CH1上面的高电平脉宽,而TIM5_CH1是连接在PA0上面的。

    2)设置TIM5的ARR和PSC

    在开启了TIM5的时钟之后,我们要设置ARR和PSC两个寄存器的值来设置输入捕获的自动重装载值和计数频率。

    3)设置TIM5的CCMR1

    TIM5_CCMR1寄存器控制着输入捕获1和2的模式,包括映射关系,滤波和分频等。这里我们需要设置通道1为输入模式,且IC1映射到TI1(通道1)上面,并且不使用滤波(提高响应速度)器。

    4)设置TIM5的CCER,开启输入捕获,并设置为上升沿捕获。

    TIM5_CCER寄存器是定时器的开关,并且可以设置输入捕获的边沿。只有TIM5_CCER寄存器使能了输入捕获,我们的外部信号,才能被TIM5捕获到,否则一切白搭。同时要设置好捕获边沿,才能得到正确的结果。

    5)设置TIM5的DIER,使能捕获和更新中断,并编写中断服务函数

    因为我们要捕获的是高电平信号的脉宽,所以,第一次捕获是上升沿,第二次捕获时下降沿,必须在捕获上升沿之后,设置捕获边沿为下降沿,同时,如果脉宽比较长,那么定时器就会溢出,对溢出必须做处理,否则结果就不准了。这两件事,我们都在中断里面做,所以必须开启捕获中断和更新中断。

    设置了中断必须编写中断函数,否则可能导致死机。我们需要在中断函数里面完成数据处理和捕获设置等关键操作,从而实现高电平脉宽统计。

    6)设置TIM5的CR1,使能定时器

    最后,必须打开定时器的计数器开关,通过设置TIM5_CR1的最低位为1,启动TIM5的计数器,开始输入捕获。

    通过以上6步设置,定时器5的通道1就可以开始输入捕获了,同时因为还用到了串口输出结果,所以还需要配置一下串口。

    TIM5_Cap_Init
    TIM5_IRQHandler

    TIM5_IRQHandler是TIM5的中断服务函数,该函数用到了两个全局变量,用于辅助实现高电平捕获。其中TIM5CH1_CAPTURE_STA,是用来记录捕获状态,该变量类似我们在usart.c里面自行定义的USART_RX_STA寄存器。TIM5CH1_CAPTURE_STA各位描述如表15.3.1所示:

    TIM5CH1_CAPTURE_STA

    bit7

    bit6

    bit5~0

    捕获完成标志

    捕获到高电平标志

    捕获高电平后定时器溢出的次数

    表15.3.1 TIM5CH1_CAPTURE_STA各位描述

           另外一个变量TIM5CH1_CAPTURE_VAL,则用来记录捕获到下降沿的时候,TIM5_CNT的值。

           现在我们来介绍一下,捕获高电平脉宽的思路:首先,设置TIM5_CH1捕获上升沿,这在TIM5_Cap_Init函数执行的时候就设置好了,然后等待上升沿中断到来,当捕获到上升沿中断,此时如果TIM5CH1_CAPTURE_STA的第6位为0,则表示还没有捕获到新的上升沿,就先把

    TIM5CH1_CAPTURE_STA、TIM5CH1_CAPTURE_VAL和TIM5->CNT等清零,然后再设置TIM5CH1_CAPTURE_STA的第6位为1,标记捕获到高电平,最后设置为下降沿捕获,等待下降沿到来。如果等待下降沿到来期间,定时器发生了溢出,就在TIM5CH1_CAPTURE_STA里面对溢出次数进行计数,当最大溢出次数来到的时候,就强制标记捕获完成(虽然此时还没有捕获到下降沿)。当下降沿到来的时候,先设置TIM5CH1_CAPTURE_STA的第7位为1,标记成功捕获一次高电平,然后读取此时的定时器值到TIM5CH1_CAPTURE_VAL里面,最后设置为上升沿捕获,回到初始状态。

           这样,我们就完成一次高电平捕获了,只要TIM5CH1_CAPTURE_STA的第7位一直为1,那么就不会进行第二次捕获,我们在main函数处理完捕获数据后,将TIM5CH1_CAPTURE_STA置零,就可以开启第二次捕获

         

           下面看下main函数:

          

    main
     1 extern u8  TIM5CH1_CAPTURE_STA;        //输入捕获状态                            
     2 extern u16    TIM5CH1_CAPTURE_VAL;    //输入捕获值
     3 /**
     4   * @brief  Main program.
     5   * @param  None
     6   * @retval None
     7   */
     8 int main(void)
     9 {
    10           u32 temp=0; 
    11 //省略不少其他硬件配置代码
    12          TIM5_Cap_Init(0XFFFF,72-1);    //以1Mhz的频率计数 
    13          while(1)
    14          {
    15             if(TIM5CH1_CAPTURE_STA&0X80)//成功捕获到了一次上升沿
    16             {
    17                 temp=TIM5CH1_CAPTURE_STA&0X3F;
    18                 temp*=65536;//溢出时间总和
    19                 temp+=TIM5CH1_CAPTURE_VAL;//得到总的高电平时间
    20                 printf("HIGH:%d us\r\n",temp);//打印总的高点平时间
    21                 TIM5CH1_CAPTURE_STA=0;//开启下一次捕获
    22             }
    23 
    24 
    25          }
    26 }

    实验OK

     修改一下,在TIM5中断函数中直接输出捕获值,将main函数中代码屏蔽

    TIM5_IRQHandler 新
     1 u8  TIM5CH1_CAPTURE_STA=0;    //输入捕获状态                            
     2 u16    TIM5CH1_CAPTURE_VAL;    //输入捕获值
     3 void TIM5_IRQHandler(void)
     4 {   u32 temp=0;
     5      if((TIM5CH1_CAPTURE_STA&0X80)==0)//还未成功捕获    
     6     {      
     7         if (TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET)
     8          
     9         {        
    10             if(TIM5CH1_CAPTURE_STA&0X40)//已经捕获到高电平了
    11             {
    12                 if((TIM5CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
    13                 {
    14                     TIM5CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次
    15                     TIM5CH1_CAPTURE_VAL=0XFFFF;
    16 
    17                     temp=TIM5CH1_CAPTURE_STA&0X3F;
    18                     temp*=65536;//溢出时间总和
    19                     temp+=TIM5CH1_CAPTURE_VAL;//得到总的高电平时间
    20                     printf("HIGH:%d us\r\n",temp);//打印总的高点平时间
    21                     TIM5CH1_CAPTURE_STA=0;//开启下一次捕获
    22                 }else TIM5CH1_CAPTURE_STA++;
    23             }     
    24         }
    25     if (TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET)//捕获1发生捕获事件
    26         {    
    27             if(TIM5CH1_CAPTURE_STA&0X40)        //捕获到一个下降沿         
    28             {                  
    29                 TIM5CH1_CAPTURE_STA|=0X80;        //标记成功捕获到一次上升沿,finish 
    30                 TIM5CH1_CAPTURE_VAL=TIM_GetCapture1(TIM5);
    31                    TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获
    32 
    33                 temp=TIM5CH1_CAPTURE_STA&0X3F;
    34                 temp*=65536;//溢出时间总和
    35                 temp+=TIM5CH1_CAPTURE_VAL;//得到总的高电平时间
    36                 printf("HIGH:%d us\r\n",temp);//打印总的高点平时间
    37                 TIM5CH1_CAPTURE_STA=0;//开启下一次捕获
    38             }else                                  //还未开始,第一次捕获上升沿    ,CNT,VAL开始 count
    39             {
    40                 TIM5CH1_CAPTURE_STA=0;            //清空
    41                 TIM5CH1_CAPTURE_VAL=0;
    42                  TIM_SetCounter(TIM5,0);
    43                 TIM5CH1_CAPTURE_STA|=0X40;        //标记捕获到了上升沿
    44                    TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling);        //CC1P=1 设置为下降沿捕获
    45             }            
    46         }                                                
    47      }
    48  
    49     TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位
    50 
    51 }
  • 相关阅读:
    2013年noip第三题货车运输truck(树链剖分LCA+最大生成树)
    hdu1754线段树入门
    《Spring1之第六次站立会议》
    《Spring1之第五次站立会议》
    《Spring1之第四次站立会议》
    《Spring1之第三次站立会议》
    《 找水王》
    《 Spring1之第二次站立会议(重发)》
    《Spring1之 第一次站立会议(重发)》
    《 第二次站立会议》
  • 原文地址:https://www.cnblogs.com/wwjdwy/p/2964222.html
Copyright © 2020-2023  润新知