原理图:
代码使用方法:
1 需要初始化引脚:init_sr04_pin();
2 在循环中,不断调用 distance_sr04=get_distance();
获得距离。单位是毫米。
注意:超声波两次读取间隔应该大于75ms,好像以前在超声波模块说明书里见过如此的说明。
注意:代码里用了TIM3定时器。
代码:
unsigned int distance_sr04; /* 距离 单位是毫米 */
char over_flow_sr04 = 0; /* 溢出 */
#define trig PBout( 3 ) /* trig ouput */
#define echo GPIO_ReadInputDataBit( GPIOB, GPIO_Pin_4 ) /* echo input */
void TIM3_Int_Init( u16 arr, u16 psc )
{
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM3, ENABLE ); /* TIM4时钟使能 */
/* 定时器TIM3初始化 */
TIM_TimeBaseStructure.TIM_Period = arr; /* 设置在下一个更新事件装入活动的自动重装载寄存器周期的值 */
TIM_TimeBaseStructure.TIM_Prescaler = psc; /* 设置用来作为TIMx时钟频率除数的预分频值 */
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; /* 设置时钟分割:TDTS = Tck_tim */
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; /* TIM向上计数模式 */
TIM_TimeBaseInit( TIM3, &TIM_TimeBaseStructure ); /* 根据指定的参数初始化TIMx的时间基数单位 */
TIM_ITConfig( TIM3, TIM_IT_Update, ENABLE ); /* 使能指定的TIM4中断,允许更新中断 */
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; /* 抢占优先级2 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; /* 子优先级2 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; /* IRQ通道使能 */
NVIC_Init( &NVIC_InitStructure ); /* 根据指定的参数初始化VIC寄存器 */
}
/* 定时器3中断服务程序 */
void TIM3_IRQHandler( void )
{
if ( TIM_GetITStatus( TIM3, TIM_IT_Update ) != RESET ) /* 是更新中断 */
{
over_flow_sr04 = 1;
TIM_ClearITPendingBit( TIM3, TIM_IT_Update ); /* 清除TIM3更新中断标志 */
TIM_Cmd( TIM3, DISABLE ); /* 关闭TIM3 */
}
}
void init_sr04_pin( void )
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); /* 使能PC端口时钟 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; /* trig */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /* 推挽输出 */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /* IO口速度为50MHz */
GPIO_Init( GPIOB, &GPIO_InitStructure ); /* 根据设定参数初始化PC13 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; /* ECHO */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; /* 设置成下拉输入 */
GPIO_Init( GPIOB, &GPIO_InitStructure ); /* 初始化GPIO */
trig = 0; /* 低电平 */
TIM3_Int_Init( 50000, 71 ); /* 1MHZ 50ms*/
}
unsigned int get_distance( void )
{
unsigned int time1;
unsigned int distance; /* 毫米单位 */
trig = 1;
delay_us( 20 );
trig = 0;
while ( echo == 0 )
;
TIM3->CNT = 0;
TIM_Cmd( TIM3, ENABLE ); /* 开启定时器3 */
over_flow_sr04 = 0; /* 没有溢出 */
while ( echo == 1 )
{
if ( over_flow_sr04 == 1 )
{
break;
}
}
time1 = TIM3->CNT;
TIM_Cmd( TIM3, DISABLE ); /* 关闭定时器3 */
distance = time1 * 0.17; /* 单位是毫米 */
return(distance);
}