这是一个本科课程设计,涉及单片机硬件和软件,适合初学Stm32自己独立完成的一个小项目。
-
功能
使用STM32F103C8T6做主控,连接超声波传感器、蓝牙模块、0.96寸OLED、蜂鸣器等模块,实现一定距离的测量,设计报警距离范围,满足报警条件后,蜂鸣器报警。报警距离可调,蜂鸣器报警可以选择开启或者关闭,OLED屏可以选择开启或者熄灭。
2.函数
main.c
主函数
#include "LED.h"
#include "usart.h"
#include "hcsr04.h"
#include "oled_2.h"
#include "beep.h"
/****************************************************
*引脚:OLED SCLK PB6 SDA PB7
* 超声波 TRIG PB11 ECHO PB10
* 蓝牙串口 TX PA9 RX PA10
* 蜂鸣器 BEEP PB12
****************************************************/
extern float LEN=20;
extern float ReportDistence=20;
extern char BeepCmd;
void BeepOn_Off(void);
int main()
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级分组 分2组
OLED_Init();
delay_init();
uart_init(9600);
BEEP_Init();
Hcsr04Init();
Map1();
while(1)
{
OLED_Showdecimal(60,3,LEN,3,1,16);
//BeepOn_Off();
printf("%f",LEN);
delay_ms(1000);
}
}
void BeepOn_Off(void)
{
if(BeepCmd==1)
{
if(LEN<ReportDistence)
TIM_Cmd(TIM2, ENABLE);
else
{
TIM_Cmd(TIM2, DISABLE);
BEEP=0;
}
}
}
hcsr04.c
超声波模块
#include "hcsr04.h"
extern float LEN;
//超声波计数
u16 msHcCount = 0;
//IO口初始化 及其他初始化
void Hcsr04Init()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(HCSR04_CLK, ENABLE);
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);
TIM3_Int_Init(1000-1,72-1);//定时器1000*(1/10^6)=1ms
TIM4_Int_Init(3000-1,7200-1);//0.1s
}
//打开定时器3
static void OpenTimerForHc()
{
TIM_SetCounter(TIM3,0);
msHcCount = 0;
TIM_Cmd(TIM3, ENABLE);
}
//关闭定时器3
static void CloseTimerForHc()
{
TIM_Cmd(TIM3, DISABLE);
}
//定时器3终中断
//1ms计数器+1
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
msHcCount++;
}
}
void TIM4_IRQHandler()
{
if(TIM_GetITStatus(TIM4 , TIM_IT_Update) != RESET) //检查指定的TIM4中断发生与否:TIM 中断源
{
TIM_ClearITPendingBit(TIM4 , TIM_IT_Update ); //清除TIM4的中断待处理位:TIM 中断源
LEN= Hcsr04GetLength();
BeepOn_Off();
}
}
//获取定时器3计数器总的值
u32 GetEchoTimer(void)
{
u32 t = 0;
t = msHcCount*1000;
t += TIM_GetCounter(TIM3);
TIM3->CNT = 0;
delay_ms(50);
return t;
}
//通过定时器3计数器值推算距离
float Hcsr04GetLength(void)
{
u32 t = 0;
int i = 0;
float lengthTemp = 0;
float sum = 0;
while(i!=5)
{
Trig_H;
delay_us(20);
Trig_L;
while(ECHO_Reci == 0);
OpenTimerForHc();
i = i + 1;
while(ECHO_Reci == 1);
CloseTimerForHc();
t = GetEchoTimer();
lengthTemp = ((float)t/58.8);//cm (t/10^6)*(340/2)*100
sum = lengthTemp + sum ;
}
lengthTemp = sum/5.0;
return lengthTemp;
}
超声波模块头文件
hcsr04.h
#ifndef __HCSR04_H
#define __HCSR04_H
#include "sys.h"
#include "delay.h"
#include "time.h"
#include "timer.h"
#include "usart.h"
/***************************
*使用定时器3
*TRIG B11
*ECHO B10
***************************/
#define HCSR04_PORT GPIOB
#define HCSR04_CLK RCC_APB2Periph_GPIOB
#define HCSR04_TRIG GPIO_Pin_11
#define HCSR04_ECHO GPIO_Pin_12
#define Trig_H GPIO_SetBits(GPIOB, GPIO_Pin_11)
#define Trig_L GPIO_ResetBits(GPIOB, GPIO_Pin_11)
#define ECHO_Reci GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12)
float Hcsr04GetLength(void);
void Hcsr04Init(void);
#endif
串口中断服务函数
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) /*返回值是 SET,说明是串口发送完成中断生。
函数返回值为SET或RESET,
即还能判断是否发生了中断。*/
{
Res= USART_ReceiveData(USART1);
USART_SendData(USART1,Res);
if(Res=='2')
ReportDistence+=1;
if(Res=='8')
ReportDistence-=1;
OLED_Float(0,66,ReportDistence,1);
if(Res=='1')
{
if(flag1)
OLED_Display_Off();
else
OLED_Display_On();
flag1=!flag1;
}
if(Res=='4')
{
if(flag2)
{
OLED_ShowCHinese16x16(70,6,7,ziku);
//TIM_Cmd(TIM2, DISABLE);
BeepCmd=0;
BEEP=0;
}
else
{
OLED_ShowCHinese16x16(70,6,6,ziku);
//TIM_Cmd(TIM2, ENABLE);
BeepCmd=1;
}
flag2=!flag2;
}
}
-
现象
测量距离显示在OLED屏上,同时通过蓝牙发送到手机上。手机端可以修改报警距离,可以使能是否需要报警。
PCB有源文件
工程源文件和pcb源文件当然直接拿,当然点个关注更好咯
链接:https://pan.baidu.com/s/1Ih9DljKzPnPdFHgIIh9G-w?pwd=ohn0
提取码:ohn0