目录
一、主要功能
1、超声波距离检测,LCD1602显示模块显示距离值
2、当测量距离低于设置阈值,启动声光警报
3、当测量距离高于设置阈值,关闭声光警报
4、距离阈值设置
5、声光警报
二、使用步骤
系统运行后,LCD1602显示超声波传感器测量出来的距离值;
当测量距离低于设置阈值,启动声光警报。
当测量距离高于设置阈值,关闭声光警报。
三、硬件资源
1、32单片机核心模块
2、按键模块
3、超声波传感器模块
4、蜂鸣器模块
5、LCD1602显示模块
四、软件设计
#include "exti.h"
#include "key.h"
#include "delay.h"
#include "usart.h"
#include "1602.h"
extern u8 Set_num; //设置标志位
extern u16 length_L; //阈值
//外部中断0服务程序
void EXTIX_Init(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
KEY_Init(); // 按键端口初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能复用功能时钟
//GPIOB13 中断线以及中断初始化配置 下降沿触发
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource13);
EXTI_InitStructure.EXTI_Line=EXTI_Line13; //KEY1
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //使能按键KEY1所在的外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00; //抢占优先级0,
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; //子优先级0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure);
//GPIOB14 中断线以及中断初始化配置 下降沿触发 //KEY2
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);
EXTI_InitStructure.EXTI_Line=EXTI_Line14;
EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //使能按键KEY2所在的外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01; //抢占优先级1,
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01; //子优先级1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure);
//GPIOB15 中断线以及中断初始化配置 下降沿触发 //KEY3
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource15);
EXTI_InitStructure.EXTI_Line=EXTI_Line15;
EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //使能按键KEY3所在的外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01; //抢占优先级1,
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01; //子优先级1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure);
}
//外部中断
void EXTI15_10_IRQHandler(void)
{
delay_ms(50);
if(KEY1 == 0)
{
Set_num++;//设置位增加
// TIM_ITConfig( TIM2,TIM_IT_Update,DISABLE );//关闭定时器2
if(Set_num>1)
{
// TIM_ITConfig( TIM2,TIM_IT_Update,ENABLE );//打开定时器2
Set_num=0;
}
while(KEY1 == 0);
}
if(KEY2 == 0)
{
if(Set_num==1)//设置阈值
{
if(length_L<100)
length_L++;
LcdWriteCom(0x80+0x40+9); //第二行
LcdWriteData(length_L/100+0x30);
LcdWriteData(length_L%100/10+0x30);
LcdWriteData(length_L%10+0x30);
LcdWriteCom(0x80+0x40+11); //第二行
LcdWriteCom(0x0f); // 光标闪烁
}
while(KEY2 == 0);
}
if(KEY3 == 0)
{
if(Set_num==1)//设置阈值
{
if(length_L>0)
length_L--;
LcdWriteCom(0x80+0x40+9); //第二行
LcdWriteData(length_L/100+0x30);
LcdWriteData(length_L%100/10+0x30);
LcdWriteData(length_L%10+0x30);
LcdWriteCom(0x80+0x40+11); //第二行
LcdWriteCom(0x0f); // 光标闪烁
}
while(KEY3 == 0);
}
if(EXTI_GetITStatus(EXTI_Line13) != RESET)//判断中断标志线是否13
{
EXTI_ClearITPendingBit(EXTI_Line13); //清除LINE13上的中断标志位
}
if(EXTI_GetITStatus(EXTI_Line14) != RESET)//判断中断标志线是否14
{
EXTI_ClearITPendingBit(EXTI_Line14); //清除LINE14上的中断标志位
}
if(EXTI_GetITStatus(EXTI_Line15) != RESET)//判断中断标志线是否15
{
EXTI_ClearITPendingBit(EXTI_Line15); //清除LINE15上的中断标志位
}
}
#include "delay.h"
#include "sys.h"
#include "1602.h"
#include "exti.h"
#include "key.h"
#include "Tool.h"
#include "hc.h"
u16 length_L=20; //距离阈值
u16 length;
u8 Set_num=0; //设置标志位
void Delay(int num)
{
while(num--) ;
}
void display_data(void)///显示
{
LcdWriteCom(0x0C); //取消光标闪烁
LcdWriteCom(0x80+7); //第一行
LcdWriteData(length%1000/100+0x30);
LcdWriteData(length%100/10+0x30);
LcdWriteData(length%10+0x30);
LcdWriteCom(0x80+0x40+9); //第二行
LcdWriteData(length_L%1000/100+0x30);
LcdWriteData(length_L%100/10+0x30);
LcdWriteData(length_L%10+0x30);
}
void Alarm(void)//警报函数
{
if(length<length_L)
LED = BEEP = 0;//开灯
else
LED =BEEP = 1;//关灯
}
int main()
{
delay_init(); //延时函数初始化
LCD1602_Init(); //lcd函数初始化
NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
EXTIX_Init();//外部中断初始化
Hcsr04Init();
TOOL_Init(); //工具初始化
while(1)
{
length = Hcsr04GetLength();
switch(Set_num)
{
case 0:display_data();Alarm();//警报函数
break;
case 1:
BEEP=1;LED=1;//设置阈值关闭警报
LcdWriteCom(0x80+0x40+11); //第二行
LcdWriteCom(0x0f); // 光标闪烁
break;//阈值
}
}
}
五、实验现象
演示视频:
【STM32单片机-A004】【Proteus仿真】超声波测距系统