基于STM32的超声波HC-SR04历程

我有一些宏定义没有贴出来,引脚自己安排就可以,如果有问题可以评论留言

HC-SR04基本工作原理:

(1)采用IO口TRIG触发测距,给最少10us的高电平信呈。
(2)模块自动发送8个40khz的方波,自动检测是否有信号返回;
(3)有信号返回, 通过IO口ECHO输出一个高电平, 高电平持续的时间就是超声波从发射到返回的时间。 测试距离=(高电平时间*声速(340M/S))/2。
程序编写思路是:1、配置好使用到的GPIO以及定时器;
2、给模块TRIG端口发送大于10us的高电平信号,当收、收到ECHO回响信号是,打开定时器开始定时;
3、当回响信号消失,关闭定时器;
4、通过定时器 定时时间来确定距离。
/*Systick延时函数

  Systick 延时初始化*/

void SysTick_Delay_Us( unsigned int us)   //1微妙延时
{
	uint32_t i;
	SysTick_Config(SystemCoreClock/1000000);
	for(i=0;i<us;i++)
	{
	       //当计数器的值减小到0的时候,CRTL寄存器的为16置1,当置1的时候该位清0
		while( !((SysTick->CTRL)&(1<<16)) );
	}
	// 关闭定时器
	SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk;
}


//1毫秒延时
void SysTick_Delay_Ms( unsigned int  ms)
{
	uint32_t i;	
	SysTick_Config(SystemCoreClock/1000);
	for(i=0;i<ms;i++)
	{
		while( !((SysTick->CTRL)&(1<<16)) );
	}
	SysTick->CTRL &=~ SysTick_CTRL_ENABLE_Msk;
}

/*TIM2定时器初始化

    一些宏定义再次不多过说明 */

void Timer_Config()
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructer;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);   
	TIM_DeInit(TIM2);
	TIM_TimeBaseInitStructer.TIM_Period=65535;//定时周期  这里没开启定时中断,这个周期最大到2米距离
	TIM_TimeBaseInitStructer.TIM_Prescaler=72-1; //  分频系数
	TIM_TimeBaseInitStructer.TIM_ClockDivision=TIM_CKD_DIV1;//不分频
	TIM_TimeBaseInitStructer.TIM_CounterMode=TIM_CounterMode_Up;
		/*定时器初始化完成*/
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructer);.
	TIM_ClearFlag(TIM2, TIM_FLAG_Update);
	TIM_Cmd(TIM2,DISABLE);//¹关闭定时器使能


}


/*超声波距离函数*/

#include "Chao.h"

#include "Systick.h"
extern char dis[];    //存储转换后的值
int Val=0;
extern int Length;

/*初始化超声波IO*/
void HS_GPIO_Config()
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE);  //´ò¿ªGPIOʱÖÓ
	//Trig
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;  
	GPIO_InitStruct.GPIO_Pin = Trig;   
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(HC_SR04_Port,&GPIO_InitStruct );

	//Echo
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_InitStruct.GPIO_Pin = Echo; 
	GPIO_Init(HC_SR04_Port,&GPIO_InitStruct );
	
}

char  *Convert()  //将整型数据转换后存储到字符数组里
{
	int tmp=0,i=0;
	Length=0;   //数据长度
	Val=UltraSonic();
	//Val=26;
	tmp=Val;
	while(tmp)
	{
	 tmp=tmp/10;
	 Length++;
	}

	for(i=Length-1;i>=0;i--)
	{
		dis[i]=Val%10+'0';
		Val=Val/10;
	}
	
	return dis;
}

int UltraSonic()   //超声波距离
{
		unsigned int length=0;
		GPIO_ResetBits(HC_SR04_Port, Trig);  //先拉低
		GPIO_SetBits(HC_SR04_Port, Trig);  //拉高电平信号
		SysTick_Delay_Us(20);   //拉高电平超过10US
		GPIO_ResetBits(HC_SR04_Port, Trig); //拉高够了就拉低
	      /*等待回响信号*/
		while(GPIO_ReadInputDataBit(HC_SR04_Port,Echo)==0);  //高电平就是接收到了
		TIM_Cmd(TIM2,ENABLE);//使能TIM2定时器
		while(GPIO_ReadInputDataBit(HC_SR04_Port,Echo)==1);//回响信号消失了
		TIM_Cmd(TIM2,DISABLE);//关闭定时器
		length=TIM_GetCounter(TIM2)/58;
		if(length<=0) length=0;
	       TIM_SetCounter(TIM2,0);  //取出TIM2定时器counter寄存器里的值
		SysTick_Delay_Ms(200);  
		return length;
	
}

/*    主函数  */

#include "stm32f10x.h"
#include "Chao.h"
#include "Systick.h"
#include "Timer.h"

int distence = 0;   
char dis[4];    
int Length=0;
int main()
{
	char *Tmp;
	HS_GPIO_Config();   
	Timer_Config();      
	while(1)
	{
		Tmp=Convert();
		Speed_Arr(Tmp);
		Speed_Byte(' ');
		Speed_Byte('C');
		Speed_Byte('M');
		Speed_Byte('\n');
		SysTick_Delay_Ms(300);
	}
				
	
}

猜你喜欢

转载自blog.csdn.net/qq1294272813/article/details/80354830