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


一、超声波测距显示系统

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仿真。

感谢你的观看!

在这里插入图片描述

电子乐屋Proteus是一款集成电路设计与仿真软件,可以帮助电子工程师进行电路设计和虚拟仿真。其中,Proteus超声波测距仿真模块是该软件中一个重要的功能模块。 超声波测距技术利用超声波在空气中传播速度较快的特性,通过发送超声波信号并接收回波的方式,计算出目标物体与传感器之间的距离。这种技术在许多领域被广泛应用,如自动停车系统、无人机避障等。 Proteus超声波测距仿真模块能够帮助工程师在虚拟环境中进行超声波测距系统的设计和仿真。首先,用户可以在Proteus中选择合适的超声波传感器模型,并设置其工作参数,如发送信号频率和接收灵敏度等。然后,用户可以将该模型与其他电路组件进行连接,构建完整的测距系统。 一旦完成了超声波测距系统的建模,用户就可以通过Proteus仿真功能来验证其性能。Proteus提供了详细的波形图分析和测距算法仿真工具,可以帮助用户评估系统的准确性和稳定性。此外,Proteus还支持用户设计并调试其他相关电路功能模块,如信号处理电路和显示电路等。 总体而言,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、付费专栏及课程。

余额充值