设计一款基于STM32F103C8T6的超声波模拟雷达,搭配C8T6最小系统板、标准固件库和1.8寸TFT-LCD屏幕,打造出高品质的产品。
前言:
之前为做毕设一直在网上浏览关于STM32单片机的DIY项目,大多数设计都是关于智能家居方面的应用,通过浏览不同平台的内容发现了一个采用超声波测距并通过屏幕反馈障碍物位置的模拟雷达设计,感觉很有创意,但网上关于此项目的内容大多都是采用arduino开发,不符合我的主控要求。
在查询资料的过程中发现了一篇大佬混分巨兽龙某某写的文章:基于STM32的超声波雷达项目【可拟合构建平面地图】(代码开源)_混分巨兽龙某某的博客-CSDN博客_基于stm32的超声雷达设计https://blog.csdn.net/black_sneak/article/details/127050718 他的雷达设计是基于STM32F103ZET6主控,采用HAL库开发,搭配2.4寸TFT-LCD屏反馈信息。我有一块ST7735驱动的1.8'TFT-LCD屏,就在之前的屏幕例程里进行改动,并复刻了大佬的UI设计,改为采用标准外设库开发,主控用了比较经济的C8T6最小系统板。
由于本人也是一名小白,发表此博客仅用于分享基于该平台的超声波模拟雷达程序,设计原理建议参考上面我分享的这位博主的文章,写的非常全面与详细。
制作超声波模拟雷达的硬件清单:
超声波模拟雷达硬件列表:
(1)STM32F103C8T6最小系统板 X1
(2)1.8'TFT-LCD屏 X1
(3)SG90舵机 X1
(4)HC-SR04超声波模块 X1
(5)超声波模块支架 X1
(6)面包板/洞洞板及排线等
实物效果图:
接线指引:
TFT-LCD接口:
外设↓ 主控↓
GND 地
VCC 3.3V/5V
SCL PA5
SDA PA7
RST PB0
DC PB1
CS PA4
BLK PB10
HC-SR04接口:
外设↓ 主控↓
VCC 5V
Trig PA0
Echo PA1GND 地
SG90接口:
外设↓ 主控↓
VCC 5V
信号 PB6
GND 地
整体设计流程:
主要程序:
主函数(main.c)
#include "stm32f10x.h"
#include "delay.h"
#include "QDTFT_demo.h"
#include "Lcd_Driver.h"
#include "GUI.h"
#include "HCSR04.h"
#include "tim.h"
#include "radar.h"
#include "servo.h"
int main(void)
{
int i=50;
SystemInit(); //System init.
delay_init(72);//Delay init.
Timer_Init(); //初始化定时器
Lcd_Init(); //LCD屏初始化
HC_SR04_Init(); //初始化超声波测距模块
TIM4_CH1_PWM_Init(2000,720);//PWM频率=72000000/2000/720=50hz=20ms
LCD_LED_SET; //通过IO控制背光亮
Lcd_Clear(BLACK);
//画雷达图
radar_picture();
while(1)
{
//TIM_SetCompare1(TIM4,250); // 250/2000*20ms=2.5ms
int a=0;
int d=0;
int Distance_mm=0;
if(i==50) //0-180°循环
{
for(i=50;i<250;i++)
{
Distance_mm=sonar_mm(); //获取超声波数据
LCD_ShowNum(37,114,Distance_mm,3); //显示距离值
TIM_SetCompare1(TIM4,i); //控制舵机变化
a=(i-50)*180/200; //角度随舵机变化
LCD_ShowNum(37,2,a,3); //显示角度值
if(Distance_mm>500)
{Distance_mm=0;} //限制测距最大值
d=Distance_mm*0.19; //通过测距判断障碍物方位
Radarline2(a,d); //显示障碍物方位(打点模拟)
delay_ms(100);
}
}
if(i==250) //180-0°循环
{
for(i=250;i>50;i--)
{
Distance_mm=sonar_mm();
LCD_ShowNum(37,114,Distance_mm,3);
TIM_SetCompare1(TIM4,i);
a=(i-50)*180/200;
LCD_ShowNum(36,2,a,3);
if(Distance_mm>500)
{Distance_mm=0;}
d=Distance_mm*0.19;
Radarline2(a,d);
delay_ms(100);
}
Lcd_Clear(BLACK); //清屏
radar_picture(); //刷新雷达图
}
}
}
雷达UI(radar.c)
#include "stm32f10x.h"
#include "Lcd_Driver.h"
#include "GUI.h"
#include "delay.h"
#include "bmp.h"
#include "math.h"
#include "radar.h"
void Radarline(double k,int r) //画斜线:(角度,长度)
{
double x,y;
x=80+r*(double)cos(k/180*3.1415926);
y=108-r*(double)sin(k/180*3.1415926);
Gui_DrawLine(80,108,x,y,GREEN); //原点坐标
}
void Radarline2(double k,int r)
{
double x,y;
x=80+r*(double)cos(k/180*3.1415926);
y=108-r*(double)sin(k/180*3.1415926);
LCD_DrawPoint2(x,y,RED);
}
void radar_picture()//雷达图
{
//画圆:(圆心坐标,半径,颜色)
Gui_Circle(80,108,76,GREEN);
Gui_Circle(80,108,57,GREEN);
Gui_Circle(80,108,38,GREEN);
Gui_Circle(80,108,19,GREEN);
//画斜线:(角度,长度)
Radarline(30,85);
Radarline(60,85);
Radarline(90,85);
Radarline(120,85);
Radarline(150,85);
//画矩形:目的是覆盖掉圆的下半部分
rectangle(0,108,160,128,BLACK); //(起点坐标,终点坐标,颜色)
Gui_DrawLine(0,108,160,108,GREEN); //画横坐标轴
//数据信息
/*字库采用甲乙丙丁代表显示不同位置的°(度)*/
Gui_DrawFont_GBK16(0,112,GREEN,BLACK,"距离");
Gui_DrawFont_GBK16(30,112,GREEN,BLACK,":");
Gui_DrawFont_GBK16(0,0,GREEN,BLACK,"角度");
Gui_DrawFont_GBK16(30,0,GREEN,BLACK,":");
Gui_DrawFont_GBK16(61,110,GREEN,BLACK,"mm");
Gui_DrawFont_GBK16(61,0,GREEN,BLACK,"乙"); //显示°
LCD_ShowNum(0,46,150,3); //150°数值
Gui_DrawFont_GBK16(18,32,GREEN,BLACK,"甲"); //150°符号
LCD_ShowNum(38,22,120,3); //120°数值
Gui_DrawFont_GBK16(56,8,GREEN,BLACK,"甲"); //120°符号
LCD_ShowNum(83,20,90,2); //90°数值
Gui_DrawFont_GBK16(97,18,GREEN,BLACK,"乙"); //90°符号
LCD_ShowNum(124,32,60,2); //60°数值
Gui_DrawFont_GBK16(133,17,GREEN,BLACK,"甲"); //60°符号
LCD_ShowNum(140,49,30,2); //30°数值
Gui_DrawFont_GBK16(141,34,GREEN,BLACK,"丁"); //30°符号
Gui_DrawFont_GBK16(80,0,GREEN,BLACK,"超声波雷达");
}
雷达UI(radar.h)
#ifndef __RADAR_H
#define __RADAR_H
void Radarline(double k,int r);
void Radarline2(double k,int r);
void radar_picture();
#endif
本人接触STM32平台也不久,一些地方写的可能不完善,欢迎各位大佬批评指正。大家也可以点赞支持一下本博主,如果有需要私信我分享出完整工程 。