HC_SR04.c如下
#include "HC_SR04.h"
#include "delay.h"
extern uint32_t HS_count_us;
/**
* 功能:超声波模块(HC_SR04)初始化函数
* 参数:None
* 返回值:None
*/
void HC_SR04_init(void)
{
GPIO_InitTypeDef HC_SR04_GPIO_Init_Structure;
TIM_TimeBaseInitTypeDef Timer4_Init_Structure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
//配置Trig(PB11)初始化结构体
HC_SR04_GPIO_Init_Structure.GPIO_Mode = GPIO_Mode_Out_PP;
HC_SR04_GPIO_Init_Structure.GPIO_Speed = GPIO_Speed_50MHz;
HC_SR04_GPIO_Init_Structure.GPIO_Pin = GPIO_Pin_11;
GPIO_Init(GPIOB, &HC_SR04_GPIO_Init_Structure);
//配置Echo(PB10)初始化结构体
HC_SR04_GPIO_Init_Structure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
HC_SR04_GPIO_Init_Structure.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOB, &HC_SR04_GPIO_Init_Structure);
Timer4_Init_Structure.TIM_ClockDivision = TIM_CKD_DIV1; //设置分频系数,通常默认不分频
Timer4_Init_Structure.TIM_CounterMode = TIM_CounterMode_Up; //设置计数模式为向上计数
Timer4_Init_Structure.TIM_Period = 1000-1; //设置重装载值为1000(计数周期为1毫秒)
Timer4_Init_Structure.TIM_Prescaler = 72-1; //设置初始化与分频值为72
TIM_TimeBaseInit(TIM4, &Timer4_Init_Structure);
TIM_Cmd(TIM4, DISABLE); //失能定时器4
}
/**
* 功能:打开定时器4函数
* 参数:None
* 返回值:None
*/
void open_timer4(void)
{
TIM_SetCounter(TIM4, 0);
HS_count_us=0;
TIM_Cmd(TIM4, ENABLE);
}
/**
* 功能:关闭定时器4函数
* 参数:None
* 返回值:None
*/
void close_timer4(void)
{
TIM_Cmd(TIM4, DISABLE);
}
/**
* 功能:获取Echo引脚电平
* 参数:None
* 返回值:Echo_Value:高电平 or 低电平
*/
int Get_HS_Echo_Value(void)
{
uint16_t Echo_Value;
Echo_Value = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_10);
return Echo_Value;
}
/**
* 功能:获取高电平持续时间
* 参数:None
* 返回值:HS_Timer高电平持续时间
*/
int Get_HS_Time_Value(void)
{
uint32_t HS_Timer = 0;
HS_Timer = HS_count_us*1000;
HS_Timer += TIM_GetCounter(TIM4);
TIM4 -> CNT = 0; //清除计数器寄存器的值
delay_ms(50);
return HS_Timer;
}
/**
* 功能:获取距离
* 参数:None
* 返回值:length :距离
*/
float Get_HS_Length_Value(void)
{
uint32_t time = 0;
uint16_t i;
float length = 0;
float sum =0 ;
for(i=0;i<5;i++)
{
HC_SR04_Trig_H();
delay_us(20);
HC_SR04_Trig_L();
while(Get_HS_Echo_Value() == 0);
open_timer4();
while(Get_HS_Echo_Value() == 1);
close_timer4();
time=Get_HS_Time_Value();
length = ((float)time/58.0);
sum = sum + length;
}
length=sum/5.0;
return length;
}
/**
* 功能:初始化定时器4中断
* 参数:None
* 返回值:None
*/
void init_timer4_exti(void)
{
TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
}
/**
* 功能:定时器4中断服务函数
* 参数:None
* 返回值:None
*/
void TIM4_IRQHandler(void)
{
if(TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
{
HS_count_us++;
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);//清除中断标志位
}
}
HC_SR04.h如下
#ifndef __HC_SR04_H
#define __HC_SR04_H
#include "stm32f10x.h"
#define HC_SR04_GPIO_PORT GPIOB
#define HC_SR04_GPIO_CLK RCC_APB2Periph_GPIOB
//Trig 发送引脚 PB11
#define HC_SR04_Trig_GPIO_PIN GPIO_Pin_11
//Echo 接收引脚 PB10
#define HC_SR04_Echo_GPIO_PIN GPIO_Pin_10
#define HC_SR04_Trig_H() GPIO_SetBits(HC_SR04_GPIO_PORT,HC_SR04_Trig_GPIO_PIN) //拉高Trig
#define HC_SR04_Trig_L() GPIO_ResetBits(HC_SR04_GPIO_PORT,HC_SR04_Trig_GPIO_PIN) //拉低Trig
void HC_SR04_init(void);
void open_timer4(void);
void close_timer4(void);
int Get_HS_Echo_Value(void);
int Get_HS_Time_Value(void);
float Get_HS_Length_Value(void);
void init_timer4_exti(void);
void TIM4_IRQHandler(void);
#endif /* __HC_SR04_H */
NVIC.c如下
#include "NVIC.h"
#include <stdio.h>
/**
* 功能:初始化NVIC,初始化内容包括:分配优先级分组号,分配对应中断优先级
* 参数:NVIC_PriorityGroup : 设置优先级分组号
* 参数值:NVIC_PriorityGroup_x
* 返回值:None
*/
void initNVIC(u32 NVIC_PriorityGroup)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup); //中断分组
setNVIC(TIM4_IRQn,1,2,ENABLE); //配置定时器4中断1优先级
// setNVIC(TIM2_IRQn,1,2,ENABLE); //配置定时器2中断1优先级
// setNVIC(USART1_IRQn,1,2,ENABLE); //配置串口1中断1抢占优先级
// setNVIC(EXTI2_IRQn,1,1,ENABLE); //配置外部中1抢占优先级
// setNVIC(EXTI3_IRQn,1,2,ENABLE); //配置外部中断1抢占优先级
}
/**
* 功能:设置对应外设中断
* 参数:InterruptNum: 对应中断的中断编号
* PreemptionPriority:指定抢占优先级
* SubPriority:指定子优先级
* NVIC_Sta:使能或者失能中断
* 返回值:None
*/
void setNVIC(u8 InterruptNum, u8 PreemptionPriority, u8 SubPriority, FunctionalState NVIC_Sta)
{
NVIC_InitTypeDef NVIC_InitStructure; //定义NVIC初始化结构体
NVIC_InitStructure.NVIC_IRQChannel = InterruptNum; //指定配置的中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PreemptionPriority; //设置抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = SubPriority; //设置子优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = NVIC_Sta; //使/失能中断
NVIC_Init(&NVIC_InitStructure); //设置生效
}
NVIC.h如下
#ifndef __NVIC_H
#define __NVIC_H
#include "stm32f10x.h"
void initNVIC(u32 NVIC_PriorityGroup);
void setNVIC(u8 InterruptNum, u8 PreemptionPriority, u8 SubPriority, FunctionalState NVIC_Sta);
#endif
main.c使用如下
#include "stm32f10x.h"
#include "delay.h"
#include "usart.h"
#include "HC_SR04.h"
#include "NVIC.h"
int main()
{
usart_init();
initSysTick();
HC_SR04_init();
init_timer4_exti();
initNVIC(NVIC_PriorityGroup_2);
while(1)
{
float distance = 0;
distance = Get_HS_Length_Value();
printf("distance = %f\n",distance);
}
}