STM32F103VET6超聲波模塊HC-SR04 的測試例程
近來有時間,整理一下資料,自己近十年來,業(yè)余畫了不少的開發(fā)測試板,在淘寶上也買了不少的板子與器件,一直以來,都喜歡DIY,今天整理了一下超聲波模塊HC-SR04的程序,網(wǎng)上資料應(yīng)該不少,自己工作中也接觸過。記錄一下。
超聲波如何設(shè)計的我不太關(guān)心,我只關(guān)心如何使用。這個模塊可以+3.3V供電,四個引腳,使用STM32兩個GPIO引腳控制即可,測試起來,簡單。
超聲波模塊工作的原理:首先需要觸發(fā)trig,就像是打開或是使能的作用,讓超聲波工作起來。然后,超聲波通過echo返回一段高電平,高電平的時間,就是聲音到達障礙物返回的時間,聲速是固定的340m/S,因此,可以求得距離。這里是2倍距離的時間,因此計算公式為:2L = Vt = 340m/S * t,這里t單位為S(秒)。
STM32如何操作超聲波模塊呢?
(1)一個GPIO引腳Trig,用于觸發(fā)。
(2)一個GPIO引腳接Echo,設(shè)置為外部中斷,用來接收觸發(fā)后返回來的高電平。
(3)一個定時器(計數(shù)器),用來測時間。
(4)可以使用另一個定時器,如Systick,隔一段時間用來觸發(fā)一次超聲波模塊,從而不斷獲取當前的距離值。
(5)一個串口,用來打印輸出測量的距離。
驅(qū)動代碼如下:
/********************(C)COPYRIGHT2017**************************
*文件名:Sonic.c
*描述:超聲波模塊測試例程
*實驗平臺:STM32F103VET6
*庫版本:ST3.5.0
*
*編寫日期:2017-04-10
*修改日期:2017-04-14
*作者:
****************************************************************************/
#include"Sonic.h"
/*******************************************************************************
*SonicInit
*******************************************************************************/
u32Distance=0;
u8Done;
u32__IOtime_1ms=0;
voidTIM6_Init(void)
{
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
//NVIC_InitTypeDefNVIC_InitStructure;
/*TIM6clockenable*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE);
/*Timebaseconfiguration*/
TIM_TimeBaseStructure.TIM_Period=0xFFFF;
TIM_TimeBaseStructure.TIM_Prescaler=142;//144分頻,500K的計數(shù)器
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM6,&TIM_TimeBaseStructure);
TIM_ITConfig(TIM6,TIM_IT_Update,DISABLE);
TIM_Cmd(TIM6,DISABLE);
}
voidSonic_Init(void)
{
NVIC_InitTypeDefNVIC_InitStructure;
EXTI_InitTypeDefEXTI_InitStructure;
GPIO_InitTypeDefGPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_AFIO,ENABLE);
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;//PC4Trig
GPIO_Init(GPIOC,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;//PC5Echo
GPIO_Init(GPIOC,&GPIO_InitStructure);
GPIO_WriteBit(GPIOC,GPIO_Pin_4,(BitAction)0);//trig
//EXTI_DeInit();
EXTI_ClearITPendingBit(EXTI_Line5);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);
EXTI_InitStructure.EXTI_Line=EXTI_Line5;
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Rising_Falling;
EXTI_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel=EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
Distance=0;
Done=1;
}
voidSonic_Trig(void)
{
u16i=0;
if((Done==1)&&(time_1ms>100))
{
time_1ms=0;
GPIO_WriteBit(GPIOC,GPIO_Pin_4,(BitAction)1);
for(i=0;i<0xf0;i++);
GPIO_WriteBit(GPIOC,GPIO_Pin_4,(BitAction)0);
Done=0;
}
}
voidEXTI9_5_IRQHandler(void)
{
staticu8flag_Sta=0;
if(EXTI_GetITStatus(EXTI_Line5)!=RESET)
{
EXTI_ClearITPendingBit(EXTI_Line5);
if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)==1)
{
TIM_SetCounter(TIM6,0);
flag_Sta=1;
TIM_Cmd(TIM6,ENABLE);
}
else
{
TIM_Cmd(TIM6,DISABLE);
if(flag_Sta)
{
Distance=TIM_GetCounter(TIM6);
Distance=Distance/29;
if(Distance>300)
Distance=300;
Done=1;
}
flag_Sta=0;