STM 32超音波測距モジュールHCSR-04ドライバ

2855 ワード

超音波測距原理見:超音波測距原理超音波測距モジュール:HC-SR 04タイマー及び外部割り込み方式を採用
/*******************************************************************************
	Driver for HC-SR04 
   :STM32F103ZET6 
   :TRIG--PC0   ECHO--PC1
*******************************************************************************/
#include "sonar_hcsr04.h"
#include "systime.h"

#define SONAR_PORT  GPIOC
#define TRIG_PIN    GPIO_Pin_0
#define ECHO_PIN    GPIO_Pin_1

static volatile uint32_t measurement;


void hcsr04Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;	
	EXTI_InitTypeDef EXTI_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseInitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC , ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = TRIG_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(SONAR_PORT, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = ECHO_PIN;				      
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;		  
	GPIO_Init(SONAR_PORT, &GPIO_InitStructure);	
	GPIO_ResetBits(SONAR_PORT, ECHO_PIN);
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource1);  //  
	
	EXTI_ClearITPendingBit(EXTI_Line1);
	
	EXTI_InitStructure.EXTI_Line = EXTI_Line1;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);		

	/* Enable TIM5 clock */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);

	/* TIME5 base configuration */
	TIM_TimeBaseInitStructure.TIM_Period = 0xFFFF;                   //   65536 
	TIM_TimeBaseInitStructure.TIM_Prescaler = 72-1;                  //  ,F=72MHz/72=1MHz,T=1us
	TIM_TimeBaseInitStructure.TIM_ClockDivision = 0;                 //  , 
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;  //  
	TIM_TimeBaseInit(TIM5, &TIM_TimeBaseInitStructure);              //  TIME5

	TIM_Cmd(TIM5, DISABLE); 
}

/**
 *  
 */
void hcsr04StartRanging(void)
{
	GPIO_SetBits(SONAR_PORT, TRIG_PIN);
    delay_us(20);   //  The width of trig signal must be greater than 10us
	GPIO_ResetBits(SONAR_PORT, TRIG_PIN);
}

/**
 *   
 * @return distance units:cm 
 */
float hcsr04GetDistance(void)
{
	// distance = measurement/2/1000000*340*100 = measurement/59 (cm)  measurement-units:us   
    float distance = measurement / 58.8;   // measurement-units:us
	
    return distance;
}

static void ECHO_EXTI_IRQHandler(void)
{
	if (EXTI_GetITStatus(EXTI_Line1) != RESET) {
		if (GPIO_ReadInputDataBit(SONAR_PORT, ECHO_PIN) != 0) {  //  
			TIM_Cmd(TIM5, ENABLE); 	
		} else {
	 		TIM_Cmd(TIM5, DISABLE);  
			measurement = TIM_GetCounter(TIM5);
			TIM_SetCounter(TIM5, 0); 
		}
	}
    EXTI_ClearITPendingBit(EXTI_Line1);
}

void EXTI1_IRQHandler(void)
{
    ECHO_EXTI_IRQHandler();
}