基於STM32的超聲波HC-SR04歷程
阿新 • • 發佈:2018-12-27
我有一些巨集定義沒有貼出來,引腳自己安排就可以,如果有問題可以評論留言
HC-SR04基本工作原理:
(1)採用IO口TRIG觸發測距,給最少10us的高電平信呈。(2)模組自動傳送8個40khz的方波,自動檢測是否有訊號返回;
(3)有訊號返回, 通過IO口ECHO輸出一個高電平, 高電平持續的時間就是超聲波從發射到返回的時間。 測試距離=(高電平時間*聲速(340M/S))/2。程式編寫思路是:1、配置好使用到的GPIO以及定時器;2、給模組TRIG埠傳送大於10us的高電平訊號,當收、收到ECHO迴響訊號是,開啟定時器開始定時;3、當迴響訊號消失,關閉定時器;4、通過定時器定時時間來確定距離。
/*Systick延時函式 Systick 延時初始化*/ void SysTick_Delay_Us( unsigned int us) //1微妙延時 { uint32_t i; SysTick_Config(SystemCoreClock/1000000); for(i=0;i<us;i++) { //當計數器的值減小到0的時候,CRTL暫存器的為16置1,當置1的時候該位清0 while( !((SysTick->CTRL)&(1<<16)) ); } // 關閉定時器 SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk; } //1毫秒延時 void SysTick_Delay_Ms( unsigned int ms) { uint32_t i; SysTick_Config(SystemCoreClock/1000); for(i=0;i<ms;i++) { while( !((SysTick->CTRL)&(1<<16)) ); } SysTick->CTRL &=~ SysTick_CTRL_ENABLE_Msk; } /*TIM2定時器初始化 一些巨集定義再次不多過說明 */ void Timer_Config() { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructer; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_DeInit(TIM2); TIM_TimeBaseInitStructer.TIM_Period=65535;//定時週期 這裡沒開啟定時中斷,這個週期最大到2米距離 TIM_TimeBaseInitStructer.TIM_Prescaler=72-1; // 分頻係數 TIM_TimeBaseInitStructer.TIM_ClockDivision=TIM_CKD_DIV1;//不分頻 TIM_TimeBaseInitStructer.TIM_CounterMode=TIM_CounterMode_Up; /*定時器初始化完成*/ TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructer);. TIM_ClearFlag(TIM2, TIM_FLAG_Update); TIM_Cmd(TIM2,DISABLE);//¹關閉定時器使能 } /*超聲波距離函式*/ #include "Chao.h" #include "Systick.h" extern char dis[]; //儲存轉換後的值 int Val=0; extern int Length; /*初始化超聲波IO*/ void HS_GPIO_Config() { GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE); //´ò¿ªGPIOʱÖÓ //Trig GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Pin = Trig; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(HC_SR04_Port,&GPIO_InitStruct ); //Echo GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStruct.GPIO_Pin = Echo; GPIO_Init(HC_SR04_Port,&GPIO_InitStruct ); } char *Convert() //將整型資料轉換後儲存到字元數組裡 { int tmp=0,i=0; Length=0; //資料長度 Val=UltraSonic(); //Val=26; tmp=Val; while(tmp) { tmp=tmp/10; Length++; } for(i=Length-1;i>=0;i--) { dis[i]=Val%10+'0'; Val=Val/10; } return dis; } int UltraSonic() //超聲波距離 { unsigned int length=0; GPIO_ResetBits(HC_SR04_Port, Trig); //先拉低 GPIO_SetBits(HC_SR04_Port, Trig); //拉高電平訊號 SysTick_Delay_Us(20); //拉高電平超過10US GPIO_ResetBits(HC_SR04_Port, Trig); //拉高夠了就拉低 /*等待迴響訊號*/ while(GPIO_ReadInputDataBit(HC_SR04_Port,Echo)==0); //高電平就是接收到了 TIM_Cmd(TIM2,ENABLE);//使能TIM2定時器 while(GPIO_ReadInputDataBit(HC_SR04_Port,Echo)==1);//迴響訊號消失了 TIM_Cmd(TIM2,DISABLE);//關閉定時器 length=TIM_GetCounter(TIM2)/58; if(length<=0) length=0; TIM_SetCounter(TIM2,0); //取出TIM2定時器counter暫存器裡的值 SysTick_Delay_Ms(200); return length; } /* 主函式 */ #include "stm32f10x.h" #include "Chao.h" #include "Systick.h" #include "Timer.h" int distence = 0; char dis[4]; int Length=0; int main() { char *Tmp; HS_GPIO_Config(); Timer_Config(); while(1) { Tmp=Convert(); Speed_Arr(Tmp); Speed_Byte(' '); Speed_Byte('C'); Speed_Byte('M'); Speed_Byte('\n'); SysTick_Delay_Ms(300); } }