基于stm32超声波测距手机报警

基于stm32超声波测距手机报警

利用超声波测距,并把实时距离显示在屏幕上,利用手机蓝牙调试助手修改报警距离,并且达到报警距离后向手机端发送报警消息,同是可利用PC端查询实时距离

串口初始化

void uart_init(u32 bound)
{
	//GPIO端口设置
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1,GPIOA时钟

	//USART1_TX   GPIOA.9
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9

	//USART1_RX	  GPIOA.10初始化
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  

	//Usart1 NVIC 配置
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器

	//USART 初始化设置

	USART_InitStructure.USART_BaudRate = bound;//串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式

  USART_Init(USART1, &USART_InitStructure); //初始化串口1
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
  USART_Cmd(USART1, ENABLE);                    //使能串口1 

}


void uart2_init(u32 bound)
{
	//GPIO端口设置
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//使能USART2,GPIOA时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2|RCC_APB2Periph_AFIO, ENABLE);	//使能USART2,GPIOA时钟

	//USART1_TX   GPIOA.9
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.2
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9

	//USART1_RX	  GPIOA.10初始化
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA3
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  

	//Usart1 NVIC 配置
	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3 ;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器

	//USART 初始化设置

	USART_InitStructure.USART_BaudRate = bound;//串口波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式

  USART_Init(USART2, &USART_InitStructure); //初始化串口2
  USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启串口接受中断
  USART_Cmd(USART2, ENABLE);                    //使能串口2

}

中断服务函数

int upLimTemp=50;
int downLimTemp=0;
//float upLimDis=400;
float downLimDis=5;
extern int FLAG;
void distance(void){
	float length;
	length = Hcsr04GetLength();
	printf("距离为:%.3f\n",length);
	printf("\r\n");
}
//当前阈值
void limit(void){
	printf("报警距离:%f",downLimDis);
	printf("\r\n");
}
void USART2_IRQHandler(void) //串口2中断服务程序
{
	if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
		{
		Res = USART_ReceiveData(USART2);	//读取接收到的数据
		if(Res==tr[0]){
			distance();
		}  	
		else if(Res==tr[1]){
		  downLimDis+=1;
	    printf("报警距离:%.3f",downLimDis);
			printf("\r\n");
		}
		else if(Res==tr[2]){
			downLimDis-=1;
			printf("报警距离:%.3f",downLimDis);
			printf("\r\n");
		}
		else if(Res==tr[3]){
			limit();
		}
		else{
			printf("\r\n请输入正确指令\r\n");
		}
		USART_ClearITPendingBit(USART2,USART_IT_RXNE);
    } 
}

Sr04初始化

u16 msHcCount = 0;//ms计数
void hcsr04_NVIC(void);
 
void Hcsr04Init(void)
{  
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;     //生成用于定时器设置的结构体
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(HCSR04_CLK, ENABLE);
     
        //IO初始化
    GPIO_InitStructure.GPIO_Pin =HCSR04_TRIG;       //发送电平引脚
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
    GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);
    GPIO_ResetBits(HCSR04_PORT,HCSR04_TRIG);
     
    GPIO_InitStructure.GPIO_Pin =   HCSR04_ECHO;     //返回电平引脚
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    GPIO_Init(HCSR04_PORT, &GPIO_InitStructure);  
		GPIO_ResetBits(HCSR04_PORT,HCSR04_ECHO);	
	 
			//定时器初始化 使用基本定时器TIM6
		RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);   //使能对应RCC时钟
		//配置定时器基础结构体
		TIM_DeInit(TIM2);
		TIM_TimeBaseStructure.TIM_Period = (1000-1); //设置在下一个更新事件装入活动的自动重装载寄存器周期的值         计数到1000为1ms
		TIM_TimeBaseStructure.TIM_Prescaler =(72-1); //设置用来作为TIMx时钟频率除数的预分频值  1M的计数频率 1US计数
		TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//不分频
		TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
		TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位		 
		
		TIM_ClearFlag(TIM6, TIM_FLAG_Update);   //清除更新中断,免得一打开中断立即产生中断
		TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE);    //打开定时器更新中断
		hcsr04_NVIC();
    TIM_Cmd(TIM6,DISABLE);     
}
 
 
//tips:static函数的作用域仅限于定义它的源文件内,所以不需要在头文件里声明
static void OpenTimerForHc(void)        //打开定时器
{
        TIM_SetCounter(TIM6,0);//清除计数
        msHcCount = 0;
        TIM_Cmd(TIM6, ENABLE);  //使能TIMx外设
}
 
static void CloseTimerForHc(void)        //关闭定时器
{
        TIM_Cmd(TIM6, DISABLE);  //使能TIMx外设
}
 
 
 //NVIC配置
void hcsr04_NVIC(void)
{
			NVIC_InitTypeDef NVIC_InitStructure;
			NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
			NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn;             //选择串口1中断
			NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //抢占式中断优先级设置为1
			NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;         //响应式中断优先级设置为1
			NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;        //使能中断
			NVIC_Init(&NVIC_InitStructure);
}
 
 
//定时器6中断服务程序
void TIM6_IRQHandler(void)   //TIM3中断
{
        if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
        {
                TIM_ClearITPendingBit(TIM6, TIM_IT_Update  );  //清除TIMx更新中断标志 
                msHcCount++;
        }
}
 
 
//获取定时器时间
u32 GetEchoTimer(void)
{
        u32 t = 0;
        t = msHcCount*1000;//得到MS
        t += TIM_GetCounter(TIM6);//得到US
	      TIM6->CNT = 0;  //将TIM2计数寄存器的计数值清零
				delay_ms(50);
        return t;
}
 
 
//一次获取超声波测距数据 两次测距之间需要相隔一段时间,隔断回响信号
//为了消除余震的影响,取五次数据的平均值进行加权滤波。
float Hcsr04GetLength(void )
{
		u32 t = 0;
		int i = 0;
		float lengthTemp = 0;
		float sum = 0;
		while(i!=5)
		{
		TRIG_Send = 1;      //发送口高电平输出
		delay_us(20);
		TRIG_Send = 0;
		while(ECHO_Reci == 0){};      //等待接收口高电平输出
			OpenTimerForHc();        //打开定时器
			i = i + 1;
			while(ECHO_Reci == 1);
			CloseTimerForHc();        //关闭定时器
			t = GetEchoTimer();        //获取时间,分辨率为1US
			lengthTemp = ((float)t/58.0);//cm
			sum = lengthTemp + sum ;
		
	}
		lengthTemp = sum/5.0;
		return lengthTemp;
}
 

sr04头文件

#ifndef __SR04_H
#define __SR04_H
#include "stm32f10x.h"
#include "delay.h"
#define HCSR04_PORT     GPIOB
#define HCSR04_CLK      RCC_APB2Periph_GPIOB
#define HCSR04_TRIG     GPIO_Pin_1
#define HCSR04_ECHO     GPIO_Pin_2
 
#define TRIG_Send  PBout(1) 
#define ECHO_Reci  PBin(2)
void Hcsr04Init(void);
static void OpenTimerForHc(void);
static void CloseTimerForHc(void);
void hcsr04_NVIC(void);
void TIM6_IRQHandler(void);
u32 GetEchoTimer(void);
float Hcsr04GetLength(void );

#endif

主函数逻辑

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "beep.h"
#include "dht11.h" 
#include "lcd.h"
#include "sr04.h"

extern float downLimDis;
 int main(void)
 {
	float length;	 
	delay_init();	    	 //延时函数初始化	  
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	uart2_init(9600);			//蓝牙模块9600
	uart_init(115200);	 //串口初始化为115200
 	LED_Init();			     //LED端口初始化
	KEY_Init();          //初始化与按键连接的硬件接口
	BEEP_Init();
	LCD_Init();
	Hcsr04Init();
	POINT_COLOR=RED;		//设置字体为红色 
	LCD_ShowString(30,50,200,16,16,"Ultrasonic Ranging");	
	LCD_ShowString(30,70,200,16,16,"NINE  SR04");	
	LCD_ShowString(30,110,200,16,16,"SR04 OK");
	POINT_COLOR=BLUE;//设置字体为蓝色 
 	LCD_ShowString(30,150,200,16,16,"Distance:   cm");	 
// 	LCD_ShowString(30,190,200,16,16,"Humi:  . %");
	LCD_ShowString(30,190,200,16,16,"Distance war:   cm");	
//	LCD_ShowString(30,230,200,16,16,"Distance down:    C");
	dht11_readdata(0);
 	while(1)
	{	
//		dht11_readdata(0);
		length = Hcsr04GetLength();
		if(length<=downLimDis){
			printf("WARING");
			printf("\r\n");
			warning();
		}
		LCD_ShowNum(30+75,150,length,2,16);	//显示温度	   		   
		LCD_ShowNum(30+105,190,downLimDis,2,16);	//显示湿度
	}	 
}
  • 11
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值