两路超声波模块代码示例基于stm32f407

两路超声波模块代码示例

US-015.H
#ifndef _US015_H
#define _US015_H
#include "stm32f4xx.h"
#define Echo PAin(2)
#define Trig PAout(4)
#define Trig1 PAout(5)
#define Echo1 PAin(0)

void MY_TIME5_INIT(u32 arr);
void MY_TIME4_INIT(u32 arr);
void Us_015_Init(void);
void Distance_read(void);
void Distance1_read(void);
extern u8 TIM5CH1_CAPTURE_STA;
extern u32 TIM5CH1_CAPTURE_VAL;
extern u32 TIME_us[2];
#endif
US-015.C
#include "my_stm32xx.h"
//#include "led.h"
//u8 TIM5CH1_CAPTURE_STA=0;//用于检测定时器定时是否准确1s自增1
u32 TIM5CH1_CAPTURE_VAL=0;//计时10us用于检测高电平时间
u32 TIM5CH1_CAPTURE_VAL1=0;
u32 TIME_us[2];//用于储存此次高电平持续时间
void MY_TIME5_INIT(u32 arr)
{
	TIM_TimeBaseInitTypeDef	TIM_TimeBaseInitSTRUCT;
	NVIC_InitTypeDef	NVIC_InitSTRUCT;
	GPIO_InitTypeDef	GPIO_InitStruct;
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN;
	GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_2;
	GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_DOWN;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_100MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_OUT;
	GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_4;
	GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_DOWN;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_100MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	TIM_TimeBaseInitSTRUCT.TIM_Period=arr;
	TIM_TimeBaseInitSTRUCT.TIM_Prescaler=83;//1US
	TIM_TimeBaseInitSTRUCT.TIM_CounterMode=TIM_CounterMode_Down;
	TIM_TimeBaseInitSTRUCT.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInit(TIM5,&TIM_TimeBaseInitSTRUCT);
	TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE);
	
	NVIC_InitSTRUCT.NVIC_IRQChannel=TIM5_IRQn;
	NVIC_InitSTRUCT.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitSTRUCT.NVIC_IRQChannelPreemptionPriority=2;
	NVIC_InitSTRUCT.NVIC_IRQChannelSubPriority=2;
	NVIC_Init(&NVIC_InitSTRUCT);
	TIM_Cmd(TIM5,DISABLE);
}
void MY_TIME4_INIT(u32 arr)
{
	TIM_TimeBaseInitTypeDef	TIM_TimeBaseInitSTRUCT;
	NVIC_InitTypeDef	NVIC_InitSTRUCT;
	GPIO_InitTypeDef	GPIO_InitStruct;
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN;
	GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
	GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_DOWN;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_100MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_OUT;
	GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;
	GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_DOWN;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_100MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	TIM_TimeBaseInitSTRUCT.TIM_Period=arr;
	TIM_TimeBaseInitSTRUCT.TIM_Prescaler=83;//1US
	TIM_TimeBaseInitSTRUCT.TIM_CounterMode=TIM_CounterMode_Down;
	TIM_TimeBaseInitSTRUCT.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitSTRUCT);
	TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);
	
	NVIC_InitSTRUCT.NVIC_IRQChannel=TIM4_IRQn;
	NVIC_InitSTRUCT.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitSTRUCT.NVIC_IRQChannelPreemptionPriority=2;
	NVIC_InitSTRUCT.NVIC_IRQChannelSubPriority=1;
	NVIC_Init(&NVIC_InitSTRUCT);
	TIM_Cmd(TIM4,DISABLE);
}
void Distance_read(void)
{
	TIM5CH1_CAPTURE_VAL=0;
	TIM_Cmd(TIM4,DISABLE);
	TIM_ClearFlag(TIM4,TIM_IT_Update);
	TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
	while(Echo==0);
	TIM_Cmd(TIM4,ENABLE);
	while(Echo==1);
	TIM_Cmd(TIM4,DISABLE);
	TIME_us[0]=TIM5CH1_CAPTURE_VAL;
	TIM_ClearFlag(TIM4,TIM_IT_Update);
	TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
}
void Distance1_read(void)
{
	TIM5CH1_CAPTURE_VAL1=0;
	TIM_Cmd(TIM5,DISABLE);
	TIM_ClearFlag(TIM5,TIM_IT_Update);
	TIM_ClearITPendingBit(TIM5,TIM_IT_Update);
	while(Echo1==0);
	TIM_Cmd(TIM5,ENABLE);
	while(Echo1==1);
	TIM_Cmd(TIM5,DISABLE);
	TIME_us[1]=TIM5CH1_CAPTURE_VAL1;
	TIM_ClearFlag(TIM5,TIM_IT_Update);
	TIM_ClearITPendingBit(TIM5,TIM_IT_Update);
}
void TIM5_IRQHandler(void)
{ 	
	if(TIM_GetITStatus(TIM5,TIM_IT_Update)!=RESET)
	TIM5CH1_CAPTURE_VAL1++;
	TIM_ClearITPendingBit(TIM5,TIM_IT_Update);
}
void TIM4_IRQHandler(void)
{ 	
	if(TIM_GetITStatus(TIM4,TIM_IT_Update)!=RESET)
	TIM5CH1_CAPTURE_VAL++;
	TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
}
KALMAN.H
#ifndef _KALMAN_H
#define _KALMAN_H
#include "stm32f4xx.h"
typedef struct{
	float Xk;
	float Xk_1;
	float Dk;
	
	float kg;
	float Pk;
	float Pk_1;
	float R;
	float Cov;
}KALMANDATA;
extern KALMANDATA Kalmandata1[2];
extern KALMANDATA Kalmandata2[2];
extern u16 distance[2];
void kalman_init(KALMANDATA *Kalmandata,float dat,float p,float r);
float kalmanCalc(KALMANDATA *Kalmandata,float dat);
u16 Distance1_CM_get(void);
void Distance_CM_get(void);
#endif
KALMAN.C
#include "kalman.h"
#include "math.h"
#include "us015.h"
#include "delay.h"
KALMANDATA Kalmandata1[2];
KALMANDATA Kalmandata2[2];
u16 distance[2];
void kalman_init(KALMANDATA *Kalmandata,float dat,float p,float r)
{
	Kalmandata->Xk_1=dat;
	Kalmandata->Pk_1=p;
	Kalmandata->R=r*r;
}
float kalmanCalc(KALMANDATA *Kalmandata,float dat)
{
	Kalmandata->Dk=dat;
	Kalmandata->Cov=_sqrt(Kalmandata->Pk_1*Kalmandata->Pk_1+Kalmandata->R);
	Kalmandata->kg=sqrt(Kalmandata->Cov*Kalmandata->Cov/(Kalmandata->Cov*Kalmandata-	>Cov+Kalmandata->R));
	Kalmandata->Pk=sqrt((1-Kalmandata->kg)*Kalmandata->R);
	Kalmandata->Xk=Kalmandata->Xk_1+Kalmandata->kg*(Kalmandata->Dk-Kalmandata->Xk_1);
	
	Kalmandata->Xk_1=Kalmandata->Xk;
	Kalmandata->Pk_1=Kalmandata->Pk;
	return Kalmandata->Xk;
}
void Distance_CM_get(void)
{
		u8 i;
		Distance_read();
		delay_us(500);
		Distance1_read();
		for(i=0;i<2;i++)
		{
			kalmanCalc(&Kalmandata1[i],TIME_us[i]);
			distance[i]=((float)(Kalmandata1[i].Xk*34))/1000;
			kalmanCalc(&Kalmandata2[i],distance[i]);
			distance[i]=Kalmandata2[i].Xk;
		}
}

MAIN.C
#include "us015.h"
#include "led.h"
#include "lcd.h"
#include "kalman.h"
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "kalman.h"
#include "my_tim.h"
#include "my_usart.h"
#include "my_math.h"
u16 distance_line[100]={0};
int main(void)
{ 
 	u16 x=0;
	u8 lcd_id[12];//存放LCD ID字符串
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
	delay_init(168);      //初始化延时函数
	uart_init(115200);		//初始化串口波特率为115200
	MY_TIME4_INIT(1);
	MY_TIME5_INIT(1);//2us定时
	MY_TIME3_INIT(9);//定时1ms
	LED_Init();					  //初始化LED
 	LCD_Init();           //初始化LCD FSMC接口
	POINT_COLOR=RED;      //画笔颜色:红色
	sprintf((char*)lcd_id,"LCD ID:%04X",lcddev.id);//将LCD ID打印到lcd_id数组。
	Distance_CM_get();
	kalman_init(&Kalmandata1[0],distance[0],4,3);	
	kalman_init(&Kalmandata2[0],2,4,3);
	kalman_init(&Kalmandata1[1],distance[1],4,3);	
	kalman_init(&Kalmandata2[1],2,4,3);
  	while(1) 
	{	
		x++;
		LCD_DrawRectangle(28,35,228,65);
		LCD_ShowString(30,40,210,24,24,"Liu Wei's Car");
		LCD_ShowString(30,70,90,16,16,"Time_us:");		
		LCD_ShowNum(110,70,TIME_us[0],num_len_get(TIME_us[0]),16); 
		LCD_ShowString(30,90,90,16,16,"Distance:");	
		LCD_ShowNum(110,90,distance[0],num_len_get(distance[0]),16); 	
		LCD_ShowString(30,110,90,16,16,"Time_us[1]:");		
		LCD_ShowNum(115,110,TIME_us[1],num_len_get(TIME_us[1]),16); 
		LCD_ShowString(30,130,90,16,16,"Distance[1]:");	
		LCD_ShowNum(115,130,distance[1],num_len_get(distance[1]),16); 			
 		//LCD_ShowString(30,110,200,16,16,lcd_id);		//显示LCD ID	      					 	
		Distance_CM_get();
		//distance1=Distance1_CM_get();
		VisualScope_Output(distance[0],distance[1],0,0);
		if(x==5){LCD_Clear(WHITE);x=0;}
	} 
}
注意事项:两个超声波模块的测量要分两次进行,两次之间要有一定的延时
注:
void MY_TIME3_INIT(u16 arr)//arr=9
{
	TIM_TimeBaseInitTypeDef	TIM_TimeBaseInitSTRUCT;
	NVIC_InitTypeDef	NVIC_InitSTRUCT;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	TIM_TimeBaseInitSTRUCT.TIM_Period=arr;
	TIM_TimeBaseInitSTRUCT.TIM_Prescaler=8400-1;
	TIM_TimeBaseInitSTRUCT.TIM_CounterMode=TIM_CounterMode_Down;
	TIM_TimeBaseInitSTRUCT.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitSTRUCT);
	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
	
	NVIC_InitSTRUCT.NVIC_IRQChannel=TIM3_IRQn;
	NVIC_InitSTRUCT.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitSTRUCT.NVIC_IRQChannelPreemptionPriority=2;
	NVIC_InitSTRUCT.NVIC_IRQChannelSubPriority=2;
	NVIC_Init(&NVIC_InitSTRUCT);
	TIM_Cmd(TIM3,ENABLE);
}
void TIM3_IRQHandler()
{
	static u16 TIM3_count,TIM3_count1;
	if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET)
	{
		TIM3_count++;
		TIM3_count1++;
		if(TIM3_count==1){
			Trig=1;
			delay_us(15);
			Trig=0;
		}
		if(TIM3_count==10)
		{
			Trig1=1;
			delay_us(15);
			Trig1=0;
		}
		else {Trig=0;Trig1=0;}
		if(TIM3_count==70)TIM3_count=0;//70ms发送一次
		if(TIM3_count1==1000){LED1=!LED1;TIM3_count1=0;}
		}
		TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
}
  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
你好!基于STM32F407的超声波测距是一种常见的应用,可以用于测量物体与传感器之间的距离。下面是一个简单的步骤指导来实现这个功能: 1. 硬件准备: - STM32F407开发板和USB线 - 超声波传感器模块(比如HC-SR04) - 杜邦线若干 2. 连接电: - 将超声波传感器的VCC引脚连接到STM32F407的3.3V电源引脚 - 将超声波传感器的GND引脚连接到STM32F407的GND引脚 - 将超声波传感器的Trig引脚连接到STM32F407的一个GPIO引脚(比如GPIOA0) - 将超声波传感器的Echo引脚连接到STM32F407的另一个GPIO引脚(比如GPIOA1) 3. 编写代码: - 使用STM32CubeMX来配置引脚和时钟设置 - 在生成的代码中,找到main.c文件 - 在main函数中初始化GPIO引脚和定时器 - 编写一个函数来发送超声波信号,并计算返回的脉冲宽度来计算距离 - 在main函数中循环调用该函数并输出测量结果 4. 编译和烧录: - 使用STM32CubeIDE或其他开发环境编译代码 - 将生成的二进制文件烧录到STM32F407开发板中 5. 测试: - 连接STM32F407开发板到电脑上,并打开串口终端软件 - 在终端上观察到测量到的距离值 这只是一个简单的示例,具体的实现可能因为不同的开发环境和超声波传感器模块而有所不同。你可以根据自己的需求和具体的硬件来进行相应的调整和扩展。希望对你有所帮助!如有更多问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值