1. 程式人生 > >STM32F103移植51超聲波測距

STM32F103移植51超聲波測距

51有很多現有可以使用的例程,但是隨著對微控制器處理效能的提高,需要使用32位的微控制器,把程式移植過來,需要考慮的東西比較多。

超聲波測距原理:

通過ECHO(外部中斷1)引腳被超聲波感測器拉高時自動啟動和關閉定時器得到計時時間,由傳播時間和速度計算出距離。

移植過程:

需要使用到STM32的定時器,選用基本定時器即可。

遇到的問題:

在從51轉換到STM32的問題主要是:

定時器型別多,無從選擇;

定時器設定方法不同。

如果把STM32上的定時器結構搞清楚了,問題迎刃而解。


STM32F103系統一共包含8個定時器和1個系統滴答定時器(SysTick),另外還有1和實時時鐘、2個看門狗定時器。

此處我們使用基本定時器,基本定時器TIM6TIM7各包含一個16位自動裝載計數器,由各自的可程式設計預分頻器驅動,在更新事件(計數器溢位)時產生中斷/DMA請求。

時基單元:

計數器TIMx_CNT

預分頻器TIMx_PSC

自動裝載暫存器TIMx_ARR

三者可由軟體進行讀寫操作,計數器執行期間也可以讀寫。

計時時間計算:(TIM_Prescaler+1) x (TIM_Period+1) /TIMxCLK

u32 SonarRange(void)
{
	//測距準備
	float fDist;//測距值
  u32 T1;	//T1執行時間(單位:機器週期個數)
	//使用基本定時器TIM6
	Timer_Config();
	//配置中斷優先順序
	NVIC_Config();
	
	//觸發超聲測距(高電平持續10us以上,下降沿觸發超聲測距)
	sonar_TRIG_PORT->ODR = 1;//觸發訊號拉高    
  delay_us(20);//保持10us以上    
  sonar_TRIG_PORT->ODR = 0; //觸發訊號拉低
   
	while(!sonar_ECHO_PORT->IDR);//等待ECHO=1,開始計時
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
	while(sonar_ECHO_PORT->IDR);//等待ECHO==0,結束計時
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
	T1=TIM6->CNT;
	
	//超聲測距值換算及有效性校驗
	fDist = (float)T1 * T * 0.17;//先換算成以us為單位的T1執行時間,再換算成以mm為單位的超聲測距值
	if(fDist < RANGE_MIN || fDist > 1000)//無效或不穩定的測距值
		return 0;
	else//有效的測距值
		return (u32)fDist;//測距值取整
}

void Timer_Config()
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	//RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);//開啟TIM6
	TIM_DeInit(TIM6);//復位,使其初始化
	
	//賦初值
	TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);//結構賦預設值
	TIM_TimeBaseStructure.TIM_Period=0;//自動裝載暫存器賦值0
	
	TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);
	TIM_ClearFlag(TIM6, TIM_FLAG_Update);//清除中斷標誌
	TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE);
	TIM_Cmd(TIM6, ENABLE);//使能計時器,並未開始計時
}