zoukankan      html  css  js  c++  java
  • 超声波手势识别(STM32四路超声波获取)

       

           超声波手势识别在市场上已经有见实现,但研究其传感器发现并不是市场上随意可见的,如果暂且考虑成本,该如何入门实现简单的手势识别呢。聊天中老师给出一个很好的提议,就是固定四个超声波,分别为上下左右,然后进行程序上的对应编号,用单片机实现四路超声波的距离数据读取,然后程序分析读取的数据进而判断手势。STM32单片机有多个定时器,每个定时器接入一个超声波,分别接入四个,定时器分别开始工作以计数,将得到的距离信息一次性发送四个方向的值到串口,串口连接到PC机,PC机获取到四组值,然后进行分析解释。下面将实现第一步,STM32 实现四路超声波获取。

    实现效果:

    Python的串口程序上每次从串口获取到上下左右四组值,并输出在控制台,相关的串口实现可以参考:Python的串口通信(pyserial)

    超声波模块:HC-SR04

    单片机:stm32f103c8t6

    注意:程序正常工作的前提是必须按复位键

    获取值【上,下,左,右】

    对应echo的IO【PA0   ,   PA11   ,   PA7   ,   PB6】

    对应trig 的IO【PB12   ,   PB13   ,   PB14   ,   PB15】

    对应定时器【定时器2通道1,高级定时器1通道4,定时器3通道2,定时器4通道1】

    串口1:A9为TX    A10为RX

    超声波使用基本介绍:

    (1)采用IO口TRIG触发测距,给至少10us的高电平信号;

    (2)模块自动发送8个40khz的方波,自动检测是否有信号返回;

    (3)有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S)) (未实现)

    超声波时序:

    主函数代码:

      1 #include "stm32f10x.h" //STM32头文件
      2 #include "sys.h"
      3 #include "delay.h"
      4 #include "usart.h"
      5 #include "timex.h"
      6 #include "trig.h"
      7 
      8 extern u8  TIM3CH1_CAPTURE_STA;        //输入捕获状态                            
      9 extern u16    TIM3CH1_CAPTURE_VAL;    //输入捕获值    
     10 extern u8  TIM3CH2_CAPTURE_STA;        //输入捕获状态                            
     11 extern u16    TIM3CH2_CAPTURE_VAL;    //输入捕获值    
     12 extern u8  TIM2CH1_CAPTURE_STA;        //输入捕获状态                            
     13 extern u16    TIM2CH1_CAPTURE_VAL;    //输入捕获值
     14 extern u8  TIM4CH1_CAPTURE_STA;        //输入捕获状态                            
     15 extern u16    TIM4CH1_CAPTURE_VAL;    //输入捕获值
     16 extern u8  TIM1CH4_CAPTURE_STA;        //输入捕获状态                            
     17 extern u16    TIM1CH4_CAPTURE_VAL;    //输入捕获值
     18 int main (void){//主程序
     19 u32 temp1=0; 
     20 //u32 temp2=0; 
     21 u32 temp3=0; 
     22 u32 temp4=0; 
     23 u32 temp24=0;
     24 RCC_Configuration(); //时钟设置
     25 TR_Init(); //输出初始化
     26 
     27 USART1_Init(115200);
     28 
     29 TIM3_Cap_Init(0XFFFF,72-1);    //以1Mhz的频率计数       //打印总的高点平时间
     30 TIM2_Cap_Init(0XFFFF,72-1);    //以1Mhz的频率计数       //打印总的高点平时间
     31 TIM4_Cap_Init(0XFFFF,72-1);    //以1Mhz的频率计数       //打印总的高点平时间
     32 TIM1_Cap_Init(0XFFFF,72-1);    //以1Mhz的频率计数       //打印总的高点平时间
     33 delay_s(1);
     34 printf("********** INIT ALL 11*********
    ");
     35 PBout(12)=1;
     36 delay_us(13);
     37 PBout(12)=0;
     38 
     39 PBout(14)=1;
     40 delay_us(13);
     41 PBout(14)=0;
     42 
     43 PBout(15)=1;
     44 delay_us(13);
     45 PBout(15)=0;
     46 
     47 PBout(13)=1;
     48 delay_us(13);
     49 PBout(13)=0;
     50 
     51 while(1){
     52 //定时器2通道1 
     53 if(TIM2CH1_CAPTURE_STA&0X80)//成功捕获到了一次上升沿
     54         {
     55             temp1=TIM2CH1_CAPTURE_STA&0X3F;
     56             temp1*=65536;//溢出时间总和
     57             temp1+=TIM2CH1_CAPTURE_VAL;//得到总的高电平时间
     58             printf("time2-----:%d 
    ",temp1);//打印总的高点平时间
     59             TIM2CH1_CAPTURE_STA=0;//开启下一次捕获
     60             PBout(12)=1;
     61             delay_us(13);
     62             PBout(12)=0;
     63         }
     64 
     65 //定时器1通道4 
     66 if(TIM1CH4_CAPTURE_STA&0X80)//成功捕获到了一次上升沿
     67         {
     68             temp24=TIM1CH4_CAPTURE_STA&0X3F;
     69             temp24*=65536;//溢出时间总和
     70             temp24+=TIM1CH4_CAPTURE_VAL;//得到总的高电平时间
     71             printf("time14-----:%d 
    ",temp24);//打印总的高点平时间
     72             TIM1CH4_CAPTURE_STA=0;//开启下一次捕获
     73             PBout(13)=1;
     74             delay_us(13);
     75             PBout(13)=0;
     76         }
     77 //定时器3通道2
     78 if(TIM3CH2_CAPTURE_STA&0X80)//成功捕获到了一次上升沿
     79         {
     80             temp3=TIM3CH2_CAPTURE_STA&0X3F;
     81             temp3*=65536;//溢出时间总和
     82             temp3+=TIM3CH2_CAPTURE_VAL;//得到总的高电平时间
     83             printf("time32----:%d 
    ",temp3);//打印总的高点平时间
     84             TIM3CH2_CAPTURE_STA=0;//开启下一次捕获
     85             PBout(14)=1;
     86             delay_us(13);
     87             PBout(14)=0;
     88         }
     89 //定时器4通道1 
     90 if(TIM4CH1_CAPTURE_STA&0X80)//成功捕获到了一次上升沿
     91         {
     92             temp4=TIM4CH1_CAPTURE_STA&0X3F;
     93             temp4*=65536;//溢出时间总和
     94             temp4+=TIM4CH1_CAPTURE_VAL;//得到总的高电平时间
     95             printf("time4-----:%d 
    ",temp4);//打印总的高点平时间
     96             TIM4CH1_CAPTURE_STA=0;//开启下一次捕获
     97             PBout(15)=1;
     98             delay_us(13);
     99             PBout(15)=0;
    100         }
    101 
    102 //发送最终结果------------------------------------
    103 if((temp1 >0)&&(temp24 >0)&&(temp3 >0)&&(temp4 >0)){
    104 
    105           printf("[%d,%d,%d,%d]",temp1,temp24,temp3,temp4);
    106           temp1=temp24=temp3=temp4=0;
    107           PBout(0)=1;
    108 }
    109 
    110 }
    111     }

    定时器2通道1代码实现:

     1 #include"timex.h"
     2 #include "usart.h"
     3 
     4 //定时器3通道1输入捕获配置
     5 
     6 TIM_ICInitTypeDef  TIM2_ICInitStructure;
     7 
     8 void TIM2_Cap_Init(u16 arr,u16 psc)
     9 {     
    10 
    11 
    12       GPIO_InitTypeDef GPIO_InitStructure;
    13       TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    14       NVIC_InitTypeDef NVIC_InitStructure;
    15       printf("---time 22222  1111 ---
    ");
    16       RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);    //使能TIM2时钟
    17       RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //使能GPIOA时钟
    18     
    19       GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;  //PA0清除之前设置  
    20       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 输入  
    21       GPIO_Init(GPIOA, &GPIO_InitStructure);
    22       GPIO_ResetBits(GPIOA,GPIO_Pin_0);                         //PA0下拉
    23     
    24       //初始化定时器5 TIM5     
    25       TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器自动重装值 
    26       TIM_TimeBaseStructure.TIM_Prescaler =psc;     //预分频器   
    27       TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
    28       TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
    29       TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
    30   
    31       //初始化TIM5输入捕获参数
    32       TIM2_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01     选择输入端 IC1映射到TI1上
    33       TIM2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;    //上升沿捕获
    34       TIM2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
    35       TIM2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;     //配置输入分频,不分频 
    36       TIM2_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波
    37       TIM_ICInit(TIM2, &TIM2_ICInitStructure);
    38     
    39       //中断分组初始化
    40       NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  //TIM3中断
    41       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  //先占优先级2级
    42       NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级0级
    43       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
    44       NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 
    45       //printf("***********************************
    ");    
    46       TIM_ITConfig(TIM2,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新中断 ,允许CC1IE捕获中断    
    47     
    48       TIM_Cmd(TIM2,ENABLE );     //使能定时器5
    49    
    50 
    51 
    52 }
    53 
    54 u8  TIM2CH1_CAPTURE_STA=0;    //输入捕获状态                            
    55 u16 TIM2CH1_CAPTURE_VAL;    //输入捕获值
    56  
    57 //定时器5中断服务程序     
    58 void TIM2_IRQHandler(void)
    59 { 
    60      //printf("********************222222***************
    ");    
    61      if((TIM2CH1_CAPTURE_STA&0X80)==0)//还未成功捕获    
    62     {      
    63         if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
    64          
    65         {        
    66             if(TIM2CH1_CAPTURE_STA&0X40)//已经捕获到高电平了
    67             {
    68                 if((TIM2CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
    69                 {
    70                     TIM2CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次
    71                     TIM2CH1_CAPTURE_VAL=0XFFFF;
    72                 }else TIM2CH1_CAPTURE_STA++;
    73             }     
    74         }
    75     if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)//捕获1发生捕获事件
    76         {    
    77             if(TIM2CH1_CAPTURE_STA&0X40)        //捕获到一个下降沿         
    78             {                  
    79                 TIM2CH1_CAPTURE_STA|=0X80;        //标记成功捕获到一次高电平脉宽
    80                 TIM2CH1_CAPTURE_VAL=TIM_GetCapture1(TIM2);
    81                 TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获
    82             }else                                  //还未开始,第一次捕获上升沿
    83             {
    84                 TIM2CH1_CAPTURE_STA=0;            //清空
    85                 TIM2CH1_CAPTURE_VAL=0;
    86                 TIM_SetCounter(TIM2,0);
    87                 TIM2CH1_CAPTURE_STA|=0X40;        //标记捕获到了上升沿
    88                 TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Falling);        //CC1P=1 设置为下降沿捕获
    89             }            
    90         }                                                
    91      }
    92 
    93     TIM_ClearITPendingBit(TIM2, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位
    94  
    95 }

     定时器1通道4实现:

      1 #include"timex.h"
      2 #include "usart.h"
      3 
      4 
      5 
      6 TIM_ICInitTypeDef  TIM1_ICInitStructure;
      7 
      8 void TIM1_Cap_Init(u16 arr,u16 psc)
      9 {  
     10      
     11       GPIO_InitTypeDef GPIO_InitStructure;
     12       TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
     13       NVIC_InitTypeDef NVIC_InitStructure;
     14       printf("---time 11111  4444 ---
    ");
     15       RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);    //使能时钟
     16       RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  
     17     
     18       GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_8|GPIO_Pin_11;  //清除之前设置  
     19       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; // 输入  
     20       GPIO_Init(GPIOA, &GPIO_InitStructure);
     21       GPIO_ResetBits(GPIOA,GPIO_Pin_8|GPIO_Pin_11);                         //下拉
     22     
     23       //初始化定时器1     
     24       TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器自动重装值 
     25       TIM_TimeBaseStructure.TIM_Prescaler =psc;     //预分频器   
     26       TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
     27       TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
     28       TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
     29   
     30      //初始化TIM1
     31       TIM1_ICInitStructure.TIM_Channel = TIM_Channel_4; //CC1S=01     选择输入端 IC1映射到TI1上
     32       TIM1_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;    //上升沿捕获
     33       TIM1_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
     34       TIM1_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;     //配置输入分频,不分频 
     35       TIM1_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波
     36       TIM_ICInit(TIM1, &TIM1_ICInitStructure);
     37     
     38       //中断分组初始化
     39       // Device header
     40       NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;  //中断
     41       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  //先占优先级2级
     42       NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级0级
     43       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
     44       NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 
     45     
     46       TIM_ITConfig(TIM1,TIM_IT_CC4|TIM_IT_Update,ENABLE);//允许更新中断 ,允许CC1IE捕获中断    
     47     
     48       TIM_Cmd(TIM1,ENABLE );     //使能定时器1
     49  
     50 }
     51 
     52 
     53  u8  TIM1CH4_CAPTURE_STA=0;    //输入捕获状态                            
     54 int    TIM1CH4_CAPTURE_VAL_0,TIM1CH4_CAPTURE_VAL;    //输入捕获值
     55 //定时器5中断服务程序     
     56 void TIM1_UP_IRQHandler(void)
     57 {
     58 
     59     if((TIM1CH4_CAPTURE_STA&0X80)==0)//还未成功捕获    
     60     {      
     61         if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)
     62          
     63         {         
     64             if(TIM1CH4_CAPTURE_STA&0X40)//已经捕获到高电平了
     65             {
     66                 if((TIM1CH4_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
     67                 {
     68                     TIM1CH4_CAPTURE_STA|=0X80;//标记成功捕获了一次
     69                     TIM1CH4_CAPTURE_VAL=0XFFFF;
     70                 }else TIM1CH4_CAPTURE_STA++;
     71             }     
     72         }
     73      }
     74  
     75     TIM_ClearITPendingBit(TIM1, TIM_IT_Update); //清除中断标志位
     76 
     77 
     78 
     79 }
     80 void TIM1_CC_IRQHandler(void)
     81 {     
     82     if((TIM1CH4_CAPTURE_STA&0X80)==0)//还未成功捕获    
     83     {      
     84       if (TIM_GetITStatus(TIM1, TIM_IT_CC4) != RESET)//捕获1发生捕获事件
     85         {    
     86             if(TIM1CH4_CAPTURE_STA&0X40)        //捕获到一个下降沿         
     87             {                  
     88                 TIM1CH4_CAPTURE_STA|=0X80;        //标记成功捕获到一次上升沿
     89                 TIM1CH4_CAPTURE_VAL=TIM_GetCapture4(TIM1)-TIM1CH4_CAPTURE_VAL_0;
     90                 TIM_OC4PolarityConfig(TIM1,TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获
     91             }else                                  //还未开始,第一次捕获上升沿
     92             {
     93                  TIM1CH4_CAPTURE_STA=0;            //清空
     94                  TIM1CH4_CAPTURE_VAL_0=TIM_GetCapture4(TIM1);//!!!!!!!!!!!!!!!!!!!!!!!
     95                  //TIM_SetCounter(TIM1,0);
     96                  TIM1CH4_CAPTURE_STA|=0X40;        //标记捕获到了上升沿
     97                  TIM_OC4PolarityConfig(TIM1,TIM_ICPolarity_Falling);        //CC1P=1 设置为下降沿捕获
     98             }            
     99         }                    
    100      }
    101  
    102     TIM_ClearITPendingBit(TIM1, TIM_IT_CC1); //清除中断标志位
    103  
    104 }

    定时器3通道2代码实现:

      1  #include"timex.h"
      2     #include "usart.h"
      3 
      4 //定时器3通道1输入捕获配置
      5 
      6 TIM_ICInitTypeDef  TIM3_ICInitStructure;
      7 TIM_ICInitTypeDef  TIM3_ICInitStructure1;
      8 void TIM3_Cap_Init(u16 arr,u16 psc)
      9 {     
     10 
     11       GPIO_InitTypeDef GPIO_InitStructure;
     12       TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
     13       NVIC_InitTypeDef NVIC_InitStructure;
     14  
     15       printf("---time 33333  2222 ---
    ");
     16       RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);    //使能时钟
     17       RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  
     18     
     19       GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_6|GPIO_Pin_7;  //清除之前设置  
     20       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //输入  
     21       GPIO_Init(GPIOA, &GPIO_InitStructure);
     22       GPIO_ResetBits(GPIOA,GPIO_Pin_6 | GPIO_Pin_7);                         //下拉
     23     
     24       //初始化定时器5 TIM5     
     25       TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器自动重装值 
     26       TIM_TimeBaseStructure.TIM_Prescaler =psc;     //预分频器   
     27       TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
     28       TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
     29       TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
     30   
     31       //初始化TIM5输入捕获参数
     32       TIM3_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01     选择输入端 IC1映射到TI1上
     33       TIM3_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;    //上升沿捕获
     34       TIM3_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
     35       TIM3_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;     //配置输入分频,不分频 
     36       TIM3_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波
     37       TIM_ICInit(TIM3, &TIM3_ICInitStructure);
     38     
     39       //初始化TIM5输入捕获参数
     40       TIM3_ICInitStructure1.TIM_Channel = TIM_Channel_2; //CC1S=01     选择输入端 IC1映射到TI1上
     41       TIM3_ICInitStructure1.TIM_ICPolarity = TIM_ICPolarity_Rising;    //上升沿捕获
     42       TIM3_ICInitStructure1.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI2上!!!!!!!!!!!!!!     !!!!!
     43       TIM3_ICInitStructure1.TIM_ICPrescaler = TIM_ICPSC_DIV1;     //配置输入分频,不分频 
     44       TIM3_ICInitStructure1.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波
     45       TIM_ICInit(TIM3, &TIM3_ICInitStructure1);
     46 
     47 
     48 
     49 
     50       //中断分组初始化
     51       NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
     52       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先占优先级2级
     53       NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级0级
     54       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
     55       NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 
     56       //printf("***********************************
    ");    
     57       TIM_ITConfig(TIM3,TIM_IT_Update|TIM_IT_CC1|TIM_IT_CC2,ENABLE);//允许更新中断 ,允许CC1IE捕获中断    
     58     
     59       TIM_Cmd(TIM3,ENABLE );     //使能定时器5
     60    
     61 
     62 
     63 }
     64 
     65 u8  TIM3CH1_CAPTURE_STA=0;    //输入捕获状态                            
     66 u16    TIM3CH1_CAPTURE_VAL;    //输入捕获值
     67 
     68 u8  TIM3CH2_CAPTURE_STA=0;    //输入捕获状态                            
     69 u16    TIM3CH2_CAPTURE_VAL;    //输入捕获值
     70  
     71  void TIM3_IRQHandler(void)
     72 { 
     73      //printf("********************222222***************
    ");    
     74        
     75         if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
     76          
     77         {    
     78             if((TIM3CH1_CAPTURE_STA&0X80)==0)//还未成功捕获    
     79         {    
     80             if(TIM3CH1_CAPTURE_STA&0X40)//已经捕获到高电平了
     81             {
     82                 if((TIM3CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
     83                 {
     84                 
     85                     TIM3CH1_CAPTURE_VAL=0XFFFF;
     86                     TIM3CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次
     87                 }else TIM3CH1_CAPTURE_STA++;
     88             }    
     89         }
     90         
     91             
     92             if((TIM3CH2_CAPTURE_STA&0X80)==0)//还未成功捕获    
     93         {
     94                 if(TIM3CH2_CAPTURE_STA&0X40)//已经捕获到高电平了
     95             {
     96                 if((TIM3CH2_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
     97                 {
     98                 
     99                     TIM3CH2_CAPTURE_VAL=0XFFFF;
    100                     TIM3CH2_CAPTURE_STA|=0X80;//标记成功捕获了一次
    101                 }else TIM3CH2_CAPTURE_STA++;
    102             } 
    103 
    104         } 
    105         }else{
    106 
    107 
    108 
    109 
    110     if((TIM3CH1_CAPTURE_STA&0X80)==0)//还未成功捕获    
    111 {
    112     if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)//捕获1发生捕获事件
    113         {
    114             
    115             if(TIM3CH1_CAPTURE_STA&0X40)        //捕获到一个下降沿         
    116             {                  
    117                 TIM3CH1_CAPTURE_STA|=0X80;        //标记成功捕获到一次高电平脉宽
    118                 TIM3CH1_CAPTURE_VAL=TIM_GetCapture1(TIM3);
    119                 TIM_OC1PolarityConfig(TIM3,TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获
    120             }else                                  //还未开始,第一次捕获上升沿
    121             {
    122                 TIM3CH1_CAPTURE_STA=0;            //清空
    123                 TIM3CH1_CAPTURE_VAL=0;
    124                 TIM_SetCounter(TIM3,0);
    125                 
    126                 TIM_OC1PolarityConfig(TIM3,TIM_ICPolarity_Falling);        //CC1P=1 设置为下降沿捕获
    127                 TIM3CH1_CAPTURE_STA|=0X40;        //标记捕获到了上升沿
    128             }            
    129         }
    130         }
    131 
    132 
    133 
    134 
    135 if((TIM3CH2_CAPTURE_STA&0X80)==0)//还未成功捕获    
    136     {
    137     if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)//捕获1发生捕获事件
    138         {    
    139             if(TIM3CH2_CAPTURE_STA&0X40)        //捕获到一个下降沿         
    140             {                  
    141                  TIM3CH2_CAPTURE_STA|=0X80;        //标记成功捕获到一次高电平脉宽
    142                  TIM3CH2_CAPTURE_VAL=TIM_GetCapture2(TIM3);
    143                  TIM_OC2PolarityConfig(TIM3,TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获
    144             }else                                  //还未开始,第一次捕获上升沿
    145             {
    146                  TIM3CH2_CAPTURE_STA=0;            //清空
    147                  TIM3CH2_CAPTURE_VAL=0;
    148                  TIM_SetCounter(TIM3,0);
    149             
    150                  TIM_OC2PolarityConfig(TIM3,TIM_ICPolarity_Falling);        //CC1P=1 设置为下降沿捕获
    151                  TIM3CH2_CAPTURE_STA|=0X40;        //标记捕获到了上升沿
    152             }            
    153         }
    154         
    155     }}    
    156 //    TIM_SetCounter(TIM3,0);    
    157     TIM_ClearITPendingBit(TIM3, TIM_IT_CC1|TIM_IT_Update|TIM_IT_CC2); //清除中断标志位
    158  
    159 }

    定时器4通道1代码实现:

     1 #include"timex.h"
     2 #include "usart.h"
     3 
     4 //定时器4通道1输入捕获配置
     5 
     6 TIM_ICInitTypeDef  TIM4_ICInitStructure;
     7 
     8 void TIM4_Cap_Init(u16 arr,u16 psc)
     9 {     
    10 
    11 
    12        GPIO_InitTypeDef GPIO_InitStructure;
    13        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    14        NVIC_InitTypeDef NVIC_InitStructure;
    15        printf("---time 44444  1111 ---
    ");
    16        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);    //使能TIM4时钟
    17        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);  //使能GPIOB时钟
    18     
    19        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_6;  //清除之前设置  
    20        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //输入  
    21        GPIO_Init(GPIOB, &GPIO_InitStructure);
    22        GPIO_ResetBits(GPIOB,GPIO_Pin_6);                         // 下拉
    23     
    24       //初始化定时器5 TIM5     
    25        TIM_TimeBaseStructure.TIM_Period = arr; //设定计数器自动重装值 
    26        TIM_TimeBaseStructure.TIM_Prescaler =psc;     //预分频器   
    27        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
    28        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
    29        TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
    30   
    31        //初始化TIM5输入捕获参数
    32        TIM4_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01     选择输入端 IC1映射到TI1上
    33        TIM4_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;    //上升沿捕获
    34        TIM4_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
    35        TIM4_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;     //配置输入分频,不分频 
    36        TIM4_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波
    37        TIM_ICInit(TIM4, &TIM4_ICInitStructure);
    38     
    39       //中断分组初始化
    40       NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;  //TIM3中断
    41       NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  //先占优先级2级
    42       NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级0级
    43       NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
    44       NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 
    45       //printf("***********************************
    ");    
    46       TIM_ITConfig(TIM4,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新中断 ,允许CC1IE捕获中断    
    47     
    48       TIM_Cmd(TIM4,ENABLE );     //使能定时器5
    49    
    50 
    51 
    52 }
    53 
    54 u8  TIM4CH1_CAPTURE_STA=0;    //输入捕获状态                            
    55 u16    TIM4CH1_CAPTURE_VAL;    //输入捕获值
    56  
    57 //定时器5中断服务程序     
    58 void TIM4_IRQHandler(void)
    59 { 
    60      //printf("********************222222***************
    ");    
    61      if((TIM4CH1_CAPTURE_STA&0X80)==0)//还未成功捕获    
    62     {      
    63         if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
    64          
    65         {        
    66             if(TIM4CH1_CAPTURE_STA&0X40)//已经捕获到高电平了
    67             {
    68                 if((TIM4CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
    69                 {
    70                     TIM4CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次
    71                     TIM4CH1_CAPTURE_VAL=0XFFFF;
    72                 }else TIM4CH1_CAPTURE_STA++;
    73             }     
    74         }
    75     if (TIM_GetITStatus(TIM4, TIM_IT_CC1) != RESET)//捕获1发生捕获事件
    76         {    
    77             if(TIM4CH1_CAPTURE_STA&0X40)        //捕获到一个下降沿         
    78             {                  
    79                  TIM4CH1_CAPTURE_STA|=0X80;        //标记成功捕获到一次高电平脉宽
    80                  TIM4CH1_CAPTURE_VAL=TIM_GetCapture1(TIM4);
    81                  TIM_OC1PolarityConfig(TIM4,TIM_ICPolarity_Rising); //CC1P=0 设置为上升沿捕获
    82             }else                                  //还未开始,第一次捕获上升沿
    83             {
    84                  TIM4CH1_CAPTURE_STA=0;            //清空
    85                  TIM4CH1_CAPTURE_VAL=0;
    86                  TIM_SetCounter(TIM4,0);
    87                  TIM4CH1_CAPTURE_STA|=0X40;        //标记捕获到了上升沿
    88                  TIM_OC1PolarityConfig(TIM4,TIM_ICPolarity_Falling);        //CC1P=1 设置为下降沿捕获
    89             }            
    90         }                                                
    91      }
    92 
    93     TIM_ClearITPendingBit(TIM4, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位
    94  
    95 }

  • 相关阅读:
    Sql 中取小数点后面两位小数
    常用SQL时间格式SQLServer中文版的默认的日期字段datetime格式是yyyy-mm-d
    sql server 2008 R2连接失败 错误:18456
    SQl server 2008 附加数据库失败,错误:5120
    sql server 2008 R2无法连接127.0.0.1报错 Server error:40(错误:53)
    SQL Server 2008的MSSQLSERVER 请求失败或服务未及时响应
    查看系统事件日志
    ssh-keygen公钥进行免登
    docker命令
    maven将依赖的jar包复制到指定位置
  • 原文地址:https://www.cnblogs.com/dongxiaodong/p/10134873.html
Copyright © 2011-2022 走看看