文章目录
一、超声波测距显示系统
1.题目要求
用STM32F103C8单片机和超声波测距模块HC-SR04做一个测量金属厚度的仪器,这里的声速不是固定值,要可以修改,因为不同的物体内的声速是不同的。
这里的显示模块用的是LCD12864,要求要显示中文,具体显示如下:
另外需要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仿真。
感谢你的观看!