STM32F407开发板使用库函数编程超声波测距

超声波采用HC-SR04

下面是代码,如有错误请指出,学的不是很好!

#include "ultrasonic.h"
#include "SysTick.h"

#define GPIO_TRIG GPIO_Pin_0
#define GPIO_ECHO GPIO_Pin_1


void ultrasonic_init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	//使能端口B、端口E的硬件时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE );
	
	//PF3为输出模式,因为该引脚连接到Trig
	GPIO_InitStructure.GPIO_Pin  = GPIO_TRIG;//指定第3根引脚 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT ;//配置为输出模式
	GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz ;//配置引脚的响应时间=1/100MHz .
	//从高电平切换到低电平1/100MHz,速度越快,功耗会越高
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP ;//推挽的输出模式,增加输出电流和灌电流的能力
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL ;//不使能内部上下拉电阻
	GPIO_Init(GPIOF ,&GPIO_InitStructure);	
	
	//PF4为输入模式,因为要检测ECHO输出高电平的持续时间
	GPIO_InitStructure.GPIO_Pin  = GPIO_ECHO;//指定第4根引脚 
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN ;//配置为输出模式
	GPIO_InitStructure.GPIO_Speed =GPIO_Speed_50MHz ;//配置引脚的响应时间=1/100MHz .
	//从高电平切换到低电平1/100MHz,速度越快,功耗会越高
	//GPIO_InitStructure.GPIO_OType = GPIO_OType_PP ;//推挽的输出模式,增加输出电流和灌电流的能力
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL ;//不使能内部上下拉电阻
	GPIO_Init(GPIOF ,&GPIO_InitStructure);		
	
	//PF3引脚初始状态为低电平,根据时序图可以了解到
	GPIO_ResetBits(GPIOF,GPIO_TRIG);
}

u32 ultrasonic_test_distance(void)
{
	uint32_t t=0;

	//PF3输出高电平
	GPIO_SetBits(GPIOF,GPIO_TRIG);
	
	//延时10us
	Delay_us(10);

	//PF3输出低电平
	GPIO_ResetBits(GPIOF,GPIO_TRIG);
	
	//PF4要等待高电平出现
	while(GPIO_ReadInputDataBit(GPIOF, GPIO_ECHO)==0);
	
	
	//测量高电平的持续时间
	while(GPIO_ReadInputDataBit(GPIOF, GPIO_ECHO)==1)
	{
	
		t++;
		Delay_us(9);//超声波每传输9us时间,距离为3mm
	
	}
	
	//因为该时间是包含发射和返回的时间,需要除以2
	t/=2;

	return t*3;
}

uint32_t Time=0;
void Timer2_Init()
{
	Time = 0;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);	//选择APB1总线下的定时器Timer2
	
	TIM_InternalClockConfig(TIM2);		//TIM2使用内部时钟
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;		//计数模式,此处为向上计数
	TIM_TimeBaseInitStructure.TIM_Period = 8399;		//ARR 1 = 0.0001S  0.1ms
	TIM_TimeBaseInitStructure.TIM_Prescaler = 0;		//PSC
	//TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;		//高级计时器特有,重复计数
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
	
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);		//使能中断
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;		//中断通道选择
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;		//优先级,同上
	
	NVIC_Init(&NVIC_InitStructure);
	
	TIM_Cmd(TIM2, ENABLE);		//打开定时器
}

void TIM2_IRQHandler()		//定时器2的中断函数
{
	if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
	{
		if (GPIO_ReadInputDataBit(GPIOF, GPIO_ECHO) == 1)
		{
			Time ++; //超声波计数	
		}
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);		//清空标志位
	}
}


void HCSR04_Start()
{
	GPIO_SetBits(GPIOF, GPIO_TRIG);
	Delay_us(45);
	GPIO_ResetBits(GPIOF, GPIO_TRIG);
	//Timer2_Init();
	Time=0;
}

uint32_t HCSR04_GetValue()
{
	HCSR04_Start();
	Delay_ms(200);
	return ((Time * 0.0001) * 34000) / 2;
//	return Time;
}
#ifndef __ULTRASONIC_H
#define __ULTRASONIC_H
#include "stm32f4xx.h"



void ultrasonic_init(void);

u32 ultrasonic_test_distance(void);

void Timer2_Init(void);
uint32_t HCSR04_GetValue(void);
//extern uint16_t Time;
#endif /* __ULTRASONIC_H */



#include "stm32f4xx.h"
#include "beep.h"
#include "SysTick.h"//里面写了一个延时函数,不重要,因此不上传该部分的代码
#include "stdio.h"
#include "usart.h"
#include "ultrasonic.h"

void delay(uint32_t a)
{
	while(a--);
}

int main(void)
{
		NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
		SysTick_Init();
		ultrasonic_init();
		usart1_init(115200);
		Timer2_Init();
		u32 t1=0;
		u32 t2=0;
		while(1)
		{
			t1=HCSR04_GetValue();
			t2=ultrasonic_test_distance();
			printf("距离:%dcm %dmm\r\n",t1,t2);
			Delay_ms(1000);
		}
}