超聲波手勢識別(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*********\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 }

 


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM