【单片机开发】智能小车工程 (超声波测距HC-SR04)

项目相关链接:
1.智能小车L298N驱动
2.智能小车寻迹驱动
3.智能小车蓝牙模块驱动
4.智能小车超声波测距驱动

【单片机开发】智能小车工程 (超声波测距HC-SR04)_第1张图片
测距原理:PA5 trig 产生超声波
PA4 ECHO 记录从发出到接收的时间
思路1 采用定时器的输入捕获
思路2 在trig=1 时人为打开定时器 收到后关闭定时器

我们看思路2 //参照野火例程

length.h

#ifndef __LENGTH_H
#define	__LENGTH_H

#include "stm32f10x.h"
#include 
void Distance_Config();    //测距用到的引脚初始化
#endif 
#include

length.c

//ECHO PA4
//TRIG PA5
void Distance_Config()
{
    GPIO_InitTypeDef GPIO_InitStructure;
    
	  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  //开启IO口对应的时钟
	  
	  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;
	 // GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;  //引脚的模式设置为浮空输入模式
		GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;
	  GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
	  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //配置为通用推挽输出模式
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	
	  GPIO_Init(GPIOA,&GPIO_InitStructure);
}

tick.h

//配置时钟
#ifndef __TIM3TICK_H
#define	__TIM3TICK_H

#include "stm32f10x.h"
#include "misc.h"
#include "stm32f10x_tim.h"
//#include 

void Tim3_Config();  //配置定时器TIM3
static void NVIC_Configuration();  //配置定时器中断,当计数时间到时触发中断

#endif /* __USART1_H */

tick.c

#include"tick.h"

void Tim3_Config()
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	  NVIC_Configuration();  //配置中断函数
	  //使能TIM3时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	  
	 
    
	  TIM_TimeBaseStructure.TIM_Period =49999;
	  TIM_TimeBaseStructure.TIM_Prescaler=71;  //设置分频系数为71
	  TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
	  TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;  //设置为向上计数模式
	
	  TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
	
	 // TIM_ARRPreloadConfig(TIM3,ENABLE);  //使能TIM3重载寄存器
	  TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);  //注意这里函数的意思是打开中断,溢出中断
	  
}

static void NVIC_Configuration()
{
  NVIC_InitTypeDef NVIC_InitStructure;
  
  /* Configure one bit for preemption priority */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  
  /* 配置中断源 */
  NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

main.c

#include "stm32f10x.h"
#include "usart.h"
#include "length.h"
#include "tick.h"
//注意这里的超声波模块的VCC必须是+5V,如果是+3V的话会导致测距不准
#define CLI()      __set_PRIMASK(1)		/* 关闭总中断 */  
#define SEI() __set_PRIMASK(0)		/*开总中断*/

void Delay(unsigned short int time);  //粗略的延时函数
float ChangeDistance(unsigned int cout1);  //时间转为距离函数
//ECHO PA4
//TRIG PA5
int main(void)
{
	  unsigned int count=0;
	  float distance=0;
	  float distancebuf[]={0};
      uart_init(9600);
    Distance_Config();  //测距模块对应的引脚初始化
    CLI() ;//关闭总中断
	  SEI(); //开总中断
	  Tim3_Config();  //定时器的初始化
	
	  
	  GPIO_ResetBits(GPIOA,GPIO_Pin_5);  //先拉低电平
	
	  while(1)
		{
      //  printf("测距开始\n");
			  GPIO_SetBits(GPIOA,GPIO_Pin_5);  //拉高电平
			  Delay(30);  //延时20个微秒
			//  Delay(20);
			//  Delay(20);
			 GPIO_ResetBits(GPIOA,GPIO_Pin_5); 

       TIM3->CNT=0;  //TIM3的计数器清0

       while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4) == 0); //等待ECHO的高电平
		

       TIM_Cmd(TIM3,ENABLE);  //运行TIM3进行计时
       
			while((GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4) == 1) && (TIM3->CNT < TIM3->ARR-10));
			 
			  TIM_Cmd(TIM3,DISABLE);  
       		
        count=TIM3->CNT;

        printf("count=%d",count);			
			  distance=ChangeDistance(count);
			  printf(" 当前距离为:%f\n",distance);
			  Delay(20000); 
				Delay(20000); 
			  while(1);
				
     }
}

void Delay(unsigned short int time)  //粗略的延时函数
{
    unsigned char i=0;
	  while(time--)
		{
        i=10;
			  while(i--);
    }
}

float ChangeDistance(unsigned int cout1)
{
    float distance=0;
	  printf("cou1=%d\n",cout1);
	  distance=cout1/58.0;
	
	  return distance;
}

最后一部分关于测速的程序经过无数次尝试仍然没有调通,各位大哥要是有的话跟小弟分享一下感激不尽。

你可能感兴趣的:(STM32开发技术总结)