STM32F103移植51超聲波測距
阿新 • • 發佈:2019-01-04
51有很多現有可以使用的例程,但是隨著對微控制器處理效能的提高,需要使用32位的微控制器,把程式移植過來,需要考慮的東西比較多。
超聲波測距原理:
通過ECHO(外部中斷1)引腳被超聲波感測器拉高時自動啟動和關閉定時器得到計時時間,由傳播時間和速度計算出距離。
移植過程:
需要使用到STM32的定時器,選用基本定時器即可。
遇到的問題:
在從51轉換到STM32的問題主要是:
定時器型別多,無從選擇;
定時器設定方法不同。
如果把STM32上的定時器結構搞清楚了,問題迎刃而解。
STM32F103系統一共包含8個定時器和1個系統滴答定時器(SysTick),另外還有1和實時時鐘、2個看門狗定時器。
此處我們使用基本定時器,基本定時器TIM6和TIM7各包含一個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);//使能計時器,並未開始計時 }