STM32 单片机 超声波测距 SR-04 程序 C语言 标准库 超声波模块 程序

原理图:
在这里插入图片描述

代码使用方法:
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);
}



猜你喜欢

转载自blog.csdn.net/x1131230123/article/details/114465362