1. 程式人生 > >stm32f103 超聲波 輸入捕獲配置及計算

stm32f103 超聲波 輸入捕獲配置及計算

(1)輸入捕獲用的定時器3的通道3

(2)輸入捕獲配置可按照中文參考手冊進行配置,如下:


(3)每次配置用的超聲波模組如下:


其中

vcc:5v

TRIG觸發控制訊號輸入,ECHO迴響訊號輸出

觸發訊號輸入是指給最少10us的高電平信呈

ECHO就是輸入捕獲了

(4)關於定時器3的中斷服務函式:

這部分自己看看就會懂,其中很難理解的邏輯部分我已經用紅字寫明大笑,我想說的是我的理解是超聲波在觸發訊號輸入後,就會產生高電平,等到超聲波遇到障礙物反射回波的時候,高電平結束。所以這個高電平持續時間有長有短,這個函式主要就是處理高電平時間過長時候時間計算問題以及高電平時間沒有溢位時候的計算

TRIG

入,

ECHO

迴響訊號輸出

/**************************************************************************

函式功能:定時器3通道3輸入捕獲初始化
入口引數:入口引數:arr:自動重灌值  psc:時鐘預分頻數 
返回  值:無
**************************************************************************/
void TIM3_Cap_Init(u16 arr,u16 psc)

RCC->APB1ENR|=1<<1;     //TIM3時鐘使能     
RCC->APB2ENR|=1<<3;    //使能PORTB時鐘    
GPIOB->CRL&=0XFFFFFF00; 
GPIOB->CRL|=0X00000028;//  PB.0 輸入 PB.1輸出

TIM3->ARR=arr;  //設定計數器自動重灌值   

TIM3->PSC=psc;  //預分頻器 

//這裡選擇了通道3

TIM3->CCMR2|=1<<0;//選擇輸入端 
 TIM3->CCMR2|=0<<4; // 配置輸入濾波器 不濾波
 TIM3->CCMR2|=0<<2; //配置輸入分頻,不分頻 



TIM3->CCER|=0<<9; //上升沿捕獲(0是上升沿捕獲)
TIM3->CCER|=1<<8; //允許捕獲計數器的值到捕獲暫存器中


TIM3->DIER|=1<<3;   //允許捕獲中斷
TIM3->DIER|=1<<0;   //允許更新中斷
TIM3->CR1|=0x01;    //使能定時器3
MY_NVIC_Init(1,3,TIM3_IRQn,1);
}
/**************************************************************************
函式功能:超聲波接收回波函式
入口引數:無
返回  值:無
**************************************************************************/
u16 TIM3CH3_CAPTURE_STA,TIM3CH3_CAPTURE_VAL;
void Read_Distane(void)
{   
PBout(1)=1;
delay_us(15);  
PBout(1)=0;
if(TIM3CH3_CAPTURE_STA&0X80)//成功捕獲到了一次高電平
{
Distance=TIM3CH3_CAPTURE_STA&0X3F;
Distance*=65536;       //溢位時間總和
Distance+=TIM3CH3_CAPTURE_VAL;//得到總的高電平時間   ECHO輸出的高電平的時間就是超聲波從發射到返回的時間
Distance=Distance*170/1000;         
//printf("%d \r\n",Distance);
TIM3CH3_CAPTURE_STA=0;//開啟下一次捕獲
}
}
/**************************************************************************
函式功能:超聲波回波脈寬讀取中斷
入口引數:無
返回  值:無
作    者:平衡小車之家
**************************************************************************/
void TIM3_IRQHandler(void)
{        
u16 tsr;
tsr=TIM3->SR;
if((TIM3CH3_CAPTURE_STA&0X80)==0)//還未成功捕獲
{
if(tsr&0X01)//溢位
{   
if(TIM3CH3_CAPTURE_STA&0X40)//已經捕獲到高電平了
{
if((TIM3CH3_CAPTURE_STA&0X3F)==0X3F)//高電平太長了   當TIM3CH3_CAPTURE_STA加到0xff時候這裡就成立了

{
TIM3CH3_CAPTURE_STA|=0X80;//標記成功捕獲了一次
TIM3CH3_CAPTURE_VAL=0XFFFF;
}else TIM3CH3_CAPTURE_STA++;

}
  if(tsr&0x08)//捕獲3發生捕獲事件
   {
if(TIM3CH3_CAPTURE_STA&0X40)//捕獲到一個下降沿  即使TIM3CH3_CAPTURE_STA加到0xfe   它&0x40仍部為0

TIM3CH3_CAPTURE_STA|=0X80;//標記成功捕獲到一次高電平脈寬
TIM3CH3_CAPTURE_VAL=TIM3->CCR3;//獲取當前的捕獲值.
TIM3->CCER&=~(1<<9);//CC1P=0 設定為上升沿捕獲
 }else  //還未開始,第一次捕獲上升沿
  {
TIM3CH3_CAPTURE_STA=0;//清空
TIM3CH3_CAPTURE_VAL=0;
TIM3CH3_CAPTURE_STA|=0X40;//標記捕獲到了上升沿
TIM3->CNT=0; //計數器清空
TIM3->CCER|=1<<9; //CC1P=1 設定為下降沿捕獲
}   
   }         
  }
TIM3->SR=0;//清除中斷標誌位     

}