基于STM32的超声波测距显示系统的Proteus仿真

20 篇文章 3 订阅


一、超声波测距显示系统

1.题目要求

用STM32F103C8单片机和超声波测距模块HC-SR04做一个测量金属厚度的仪器,这里的声速不是固定值,要可以修改,因为不同的物体内的声速是不同的。

这里的显示模块用的是LCD12864,要求要显示中文,具体显示如下:
在这里插入图片描述

另外需要8个按键来进行测试和设置操作等等。

按键功能简单定义如下:

  1. 测量:按下开始进行测量厚度,松开退出测量;
  2. 设置:按下开始设置声速,松开退出设置
  3. 左:向左移动一位
  4. 右:向右移动一位
  5. 上:增大声速值
  6. 下:减小声速值
  7. 存储:保存测得的数据
  8. 调用:选择保存的数据

最后,还需要掉电保存数据,可以选择存单片机内部Flash或者外挂EEPROM芯片。

2.思路

LCD12864要显示中文,这需要用到取模软件,如下所示:
在这里插入图片描述
参数设置为:
在这里插入图片描述
超声波测距模块可以参考我之前的那一篇文章:超声波测距HC-SR04模块的简单应用
在这里插入图片描述

按键大致是这样:

在这里插入图片描述

存储方面一开始打算直接用内部Flash的,但是每次重新仿真数据都会丢,如果不重新跑仿真,只是按RST复位按键使STM32复位,这时候数据不会丢失,所以怀疑是每次重新跑仿真,相当于程序重新加载烧录,这样Flash会被清除掉,所以最后选择用EEPROM芯片AT24C02来进行存储。
在这里插入图片描述

3.仿真图

3.1 初始界面

在这里插入图片描述

3.2 按下测试按键

在这里插入图片描述

3.3 松开测试按键

在这里插入图片描述

3.4 按下设置按键

3.4.1 向左选择数字

在这里插入图片描述

3.4.2 向右选择数字

在这里插入图片描述

3.4.3 增大声速

在这里插入图片描述

3.4.4 减小声速

在这里插入图片描述

3.5 松开设置按键

在这里插入图片描述

3.6 存储选择

在这里插入图片描述

3.7 调用选择(重新上电)

在这里插入图片描述

4.仿真程序

4.1 程序说明

主控芯片:STM32F103C8
HICK:64MHZ
Systick: 10us
测试Led:PC13
Uart1:9600(PA9:tx1,PA10:rx1)

超声波测距HC-SR04:TR(PB15),ECHO(PB14)

显示屏LCD12864:
DB0(PB0)
DB1(PB1)
DB2(PB2)
DB3(PB3)
DB4(PB4)
DB5(PB5)
DB6(PB6)
DB7(PB7)
E(PB8)
RW(PB9)
RS(PB10)
CS2(PB11)
CS1(PB12)
RST(PB13)

KEY按键:
KEY1(PA0)
KEY2(PA1)
KEY3(PA2)
KEY4(PA3)
KEY5(PA4)
KEY6(PA5)
KEY7(PA6)
KEY8(PA7)

EEPROM芯片:
SCL(PA12)
SDA(PA13)

4.2 主函数

/* Includes ------------------------------------------------------------------*/
#include "Drv_UserSystem.h"

/**
  * @brief  main function.
  * @param  none
  * @retval none
  */
int main(void)
{
	UserSystemInit();//用户配置初始化		
	while (1)
	{				
		if (stSysTime.flg._10ms + TEN_MILLISECOND < Time_millis()) //10ms
		{
			stSysTime.flg._10ms = Time_millis();	
			Key_Scan();//按键扫描		
		}
		if (stSysTime.flg._50ms + FIFTY_MILLISECOND < Time_millis()) //50ms
		{
			stSysTime.flg._50ms = Time_millis();	
			Lcd_display();//Lcd显示			
			Measurement_function();//测距函数						
		}
		if (stSysTime.flg._100ms + BEST_MILLISECOND < Time_millis()) //100ms
		{
			stSysTime.flg._100ms = Time_millis();	
			Receive_data_Handel();//数据接收判断	
			IWDG_ReloadCounter();//清开门狗 
		}
		if (stSysTime.flg._1s + THOUSAND_MILLISECOND < Time_millis()) //1s
		{
			stSysTime.flg._1s = Time_millis();	 
			Led_Flicker();//灯光闪烁
	  }
  }
}

4.3 LCD显示函数

/*******************************************************************************
 * 函数名:Lcd_display
 * 描述  :LCD显示函数
 * 输入  :void
 * 输出  :void
 * 调用  :内部调用
 * 备注  :
*******************************************************************************/
void Lcd_display(void)
{
	if(Display_interface == 0)
	{
			//显示金属厚度:000mm		
			printWidthX16(0, 67, 16,  data_ji);
			printWidthX16(0, 83, 16,  data_shu);
			printWidthX16(0, 99, 16,  data_hou);
			printWidthX16(0, 115, 16,  data_du);
			printWidthX16(0, 0, 16,  data_maohao);	
			printWidthX16(0, 17, 8,  data_0);
			printWidthX16(0, 25, 8,  data_0);
			printWidthX16(0, 33, 8,  data_0);	
			printWidthX16(0, 44, 8,  data_m);			
			printWidthX16(0, 54, 8,  data_m);		
		
			//显示声速:000m/s
			printWidthX16(3, 67, 16,  data_sheng);
			printWidthX16(3, 83, 16,  data_su);	
			printWidthX16(3, 99, 16,  data_maohao);		
			printWidthX16(3, 0, 8,  data_0);	
			printWidthX16(3, 8, 8,  data_0);	
			printWidthX16(3, 16, 8,  data_0);		
			printWidthX16(3, 28, 8,  data_m);			
			printWidthX16(3, 36, 8,  data_xiehao);
			printWidthX16(3, 44, 8,  data_s);			
	}
	else if(Display_interface == 1)
	{
			//显示金属厚度:XXXmm
			printWidthX16(0, 67, 16,  data_ji);
			printWidthX16(0, 83, 16,  data_shu);
			printWidthX16(0, 99, 16,  data_hou);
			printWidthX16(0, 115, 16,  data_du);
			printWidthX16(0, 0, 16,  data_maohao);	
			printWidthX16(0, 44, 8,  data_m);			
			printWidthX16(0, 54, 8,  data_m);	

			//显示声速:XXXm/s
			printWidthX16(3, 67, 16,  data_sheng);
			printWidthX16(3, 83, 16,  data_su);	
			printWidthX16(3, 99, 16,  data_maohao);				
			printWidthX16(3, 28, 8,  data_m);			
			printWidthX16(3, 36, 8,  data_xiehao);
			printWidthX16(3, 44, 8,  data_s);		
	}
	else if(Display_interface == 2)
	{
			//显示声速:XXXm/s
			printWidthX16(3, 67, 16,  data_sheng);
			printWidthX16(3, 83, 16,  data_su);	
			printWidthX16(3, 99, 16,  data_maohao);				
			printWidthX16(3, 28, 8,  data_m);			
			printWidthX16(3, 36, 8,  data_xiehao);
			printWidthX16(3, 44, 8,  data_s);	
	}
	else if(Display_interface == 3)
	{
		  //存储选择:
			printWidthX16(0, 67, 16,  data_cun);
			printWidthX16(0, 83, 16,  data_chu2);
			printWidthX16(0, 99, 16,  data_xuan);
			printWidthX16(0, 115, 16,  data_ze);
			printWidthX16(0, 0, 16,  data_maohao);	

			printWidthX16(3, 67, 8,  data_V);		
			printWidthX16(3, 75, 8,  data_0);	
			printWidthX16(3, 83, 8,  data_1);	
			printWidthX16(3, 91, 8,  data_denghao);			
		
			printWidthX16(3, 8, 8,  data_V);		
			printWidthX16(3, 16, 8,  data_0);	
			printWidthX16(3, 24, 8,  data_2);	
			printWidthX16(3, 32, 8,  data_denghao);			
		
			printWidthX16(6, 67, 8,  data_V);		
			printWidthX16(6, 75, 8,  data_0);	
			printWidthX16(6, 83, 8,  data_3);	
			printWidthX16(6, 91, 8,  data_denghao);		

			printWidthX16(6, 8, 8,  data_V);		
			printWidthX16(6, 16, 8,  data_0);	
			printWidthX16(6, 24, 8,  data_4);	
			printWidthX16(6, 32, 8,  data_denghao);		
	}
	else if(Display_interface == 4)
	{
		  //调用选择:
			printWidthX16(0, 67, 16,  data_diao);
			printWidthX16(0, 83, 16,  data_yong);
			printWidthX16(0, 99, 16,  data_xuan);
			printWidthX16(0, 115, 16,  data_ze);
			printWidthX16(0, 0, 16,  data_maohao);

			printWidthX16(3, 67, 8,  data_V);		
			printWidthX16(3, 75, 8,  data_0);	
			printWidthX16(3, 83, 8,  data_1);	
			printWidthX16(3, 91, 8,  data_denghao);		
		
			printWidthX16(3, 8, 8,  data_V);		
			printWidthX16(3, 16, 8,  data_0);	
			printWidthX16(3, 24, 8,  data_2);	
			printWidthX16(3, 32, 8,  data_denghao);				
		
			printWidthX16(6, 67, 8,  data_V);		
			printWidthX16(6, 75, 8,  data_0);	
			printWidthX16(6, 83, 8,  data_3);	
			printWidthX16(6, 91, 8,  data_denghao);		

			printWidthX16(6, 8, 8,  data_V);		
			printWidthX16(6, 16, 8,  data_0);	
			printWidthX16(6, 24, 8,  data_4);	
			printWidthX16(6, 32, 8,  data_denghao);				
	}		
}

4.4 测距函数

/*******************************************************************************
 * 函数名:Measurement_function
 * 描述  :HCSR04测距函数
 * 输入  :void
 * 输出  :void
 * 调用  :内部调用
 * 备注  :
 *******************************************************************************/
void Measurement_function(void)
{
		Trig_Out_High();  
		Delay_20us();
		Trig_Out_Low();	
		while(Read_Echo_Level()==0);//等待低电平结束
				ditance_count = 0;	
		while(Read_Echo_Level()==1);//等待高电平结束	
				ditance_flag = 1;	
		if(ditance_count < Overtime)//小于超时时间 38ms
		{
			 MM_ditance = ((ditance_count * Sound_velocity_value)/2)/88;//单位毫米
		}
		if(KeyState.Press1)
		{
		    Distance_Conversion();
			  printf("MM_ditance = %d\r\n",MM_ditance);		
		}
		if((KeyState.Press1) || (KeyState.Press2))
		{		
		    Sound_Conversion();
		}
		if((KeyState.Press7) || (KeyState.Press8))
		{			
			  Data_Display();
				Stores_Sound1_Variables();
				Stores_Sound2_Variables();
				Stores_Sound3_Variables();
				Stores_Sound4_Variables();
		}
}

二、总结

今天主要讲了基于STM32的超声波测距显示系统的Proteus仿真。

感谢你的观看!

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiaobuding_QAQ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值