(1)輸入捕獲用的定時器3的通道3
(2)輸入捕獲配置可按照中文參考手冊進行配置,如下:
(3)每次配置用的超聲波模塊如下:
其中
vcc:5v
TRIG觸發(fā)控制信號輸入,ECHO回響信號輸出
觸發(fā)信號輸入是指給最少10us的高電平信呈
ECHO就是輸入捕獲了
(4)關于定時器3的中斷服務函數(shù):
這部分自己看看就會懂,其中很難理解的邏輯部分我已經用紅字寫明,我想說的是我的理解是超聲波在觸發(fā)信號輸入后,就會產生高電平,等到超聲波遇到障礙物反射回波的時候,高電平結束。所以這個高電平持續(xù)時間有長有短,這個函數(shù)主要就是處理高電平時間過長時候時間計算問題以及高電平時間沒有溢出時候的計算
TRIG觸發(fā)控制信號輸入,ECHO回響信號輸出
/**************************************************************************
函數(shù)功能:定時器3通道3輸入捕獲初始化
入口參數(shù):入口參數(shù):arr:自動重裝值 psc:時鐘預分頻數(shù)
返回 值:無
**************************************************************************/
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; //設定計數(shù)器自動重裝值
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;//允許捕獲計數(shù)器的值到捕獲寄存器中
TIM3->DIER|=1<<3; //允許捕獲中斷
TIM3->DIER|=1<<0; //允許更新中斷
TIM3->CR1|=0x01; //使能定時器3
MY_NVIC_Init(1,3,TIM3_IRQn,1);
}
/**************************************************************************
函數(shù)功能:超聲波接收回波函數(shù)
入口參數(shù):無
返回 值:無
**************************************************************************/
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輸出的高電平的時間就是超聲波從發(fā)射到返回的時間
Distance=Distance*170/1000;
// printf("%d rn",Distance);
TIM3CH3_CAPTURE_STA=0;//開啟下一次捕獲
}
}
/**************************************************************************
函數(shù)功能:超聲波回波脈寬讀取中斷
入口參數(shù):無
返回 值:無
作 者:平衡小車之家
**************************************************************************/
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發(fā)生捕獲事件
{
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; //計數(shù)器清空
TIM3->CCER|=1<<9;//CC1P=1 設置為下降沿捕獲
}
}
}
TIM3->SR=0;//清除中斷標志位
}