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);
}
}