超声波手势识别(STM32四路超声波获取)

c/c++

浏览数:31

2019-10-9

   

       超声波手势识别在市场上已经有见实现,但研究其传感器发现并不是市场上随意可见的,如果暂且考虑成本,该如何入门实现简单的手势识别呢。聊天中老师给出一个很好的提议,就是固定四个超声波,分别为上下左右,然后进行程序上的对应编号,用单片机实现四路超声波的距离数据读取,然后程序分析读取的数据进而判断手势。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*********\r\n");
 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 \r\n",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 \r\n",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 \r\n",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 \r\n",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 ---\r\n");
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("***********************************\r\n");    
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***************\r\n");    
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 ---\r\n");
 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 ---\r\n");
 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("***********************************\r\n");    
 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***************\r\n");    
 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 ---\r\n");
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("***********************************\r\n");    
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***************\r\n");    
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 }

 

作者:东小东