当前位置: 首页 > ops >正文

基于STM32的超声波模拟雷达设计

一、雷达概述

        雷达(Radio Detection and Ranging,无线电探测与测距)是一种利用电磁波探测目标位置、速度等信息的主动式传感器系统。其基本原理是发射电磁波并接收目标反射的回波,通过分析回波的时间差、频率变化等参数,实现对目标的探测、跟踪和识别。

军用雷达:预警雷达(如远程防空)、火控雷达(导弹制导)、侦察雷达。

民用雷达:气象雷达(降水监测)、航空管制雷达、汽车防撞雷达、地质探测雷达

应用领域:

军事:防空系统(如爱国者导弹)、战斗机火控、舰船导航。

航空:机场空中交通管制(ATC)、飞机防撞系统(TCAS)。

气象:监测风暴、降水、风场(如多普勒天气雷达)。

交通:汽车自动驾驶(毫米波雷达)、铁路障碍物检测。

科研:天文观测(射电望远镜)、行星探测(如火星雷达)。

二、制作目标

        以STM32F103C8T6单片机为主控,使用cubemx平台开发,SG90舵机+HC-SR04超声波模块往复转动180度扫描周围的物体,在2.4寸TFT-LCD(320×240)屏显示雷达图,检测到周围的物体后,在LCD屏雷达图画点显示物体的位置角度和距离,模拟真实雷达的工作原理。

三、实物效果

四、物料清单

1、SG90+超声波+云台支架全套

商品详情

2、2.4寸TFT液晶屏ILI9341驱动240*320模块LCD触摸SPI

https://item.taobao.com/item.htm?id=679175996067&pisk=gS8L_S2XCAD3hWTdsBogEUCBA_lGycAe_pRbrTX3Vdp9eIFHxgXlVap2HgaoYwjRyd6M-9AhR_sWEKthdHXuyUpwpy4lRL0RFI-Za9fH-7CWfpUkxBXHX7QeSH4lKv7JNKb-nx0moBRF7aMmnOfzn1bfiua7E6s1CafJjBZ3GBRFzTNgFmx6T7LGjnF5NTGO5_CcFasCFl_1Q_qCFL6CfR1Aga_WF96_565bRu1CPGGOMsPCOy1I5V1ANuwBFaG91O55P695Pv6seONCEzKcFaYJil287P8O9MB8rOzRMeUcftGOCzURp_ILxB6TPzT9bg0879i4sT7hLECpUqzFRgK2Z_pKJy9JgFJO1Kg8o9OwinjeRqrPDw6NqeOiDrQBL_IfPGF7PCQFdK81lqwO_hOHVeJLwz1e-EjR3Gh7zgb6oitXp7l21w1WUi8o3yWBNI82mZ3gAZO9VKKR4h8DkBLunIP4AfhT4uSC_FoPVShrkPcR6tcKyurPbf5OnfhT4uSC_1Bm9bEz4GlN.&spm=tbpc.boughtlist.suborder_itemtitle.1.12932e8d8xCDO2&skuId=5666470206563 3、STM32F103C8T6最小系统板

商品详情

五、原理图和接线说明

1、原理图

2、接线说明

需要注意的是:系统连接完成后,必须用TypeC口供电,否则用下载器供电不能同时带起来LCD屏和舵机,会出现LCD屏白屏闪烁的问题。

LCD显示引脚:

VCC --> 3.3V

GND --> GND

CS --> PB11

Reset --> PB12

DC --> PB10

SDI --> PB15

SCK --> PB13

LED -->  PB9

HC-SR04引脚:

VCC --> 5.0V

GND --> GND

Trig --> PA5

Echo --> PA0

SG90引脚:

VCC --> 5.0V

GND --> GND

PWM(信号线) --> PA6

六、软件设计过程

1、cubemx配置

(1)时钟和系统

(2)GPIO配置:PA5用于输出超声波传感器的发射信号,PB9、PB10、PB11、PB12用于LCD屏的控制

(3)定时器配置:TIM1用于产生微秒延时产生超声波的发射信号,TIM2用于捕获超声波收到的信号从而计算出距离物体的距离,TIM3用于产生PWM波用于控制舵机的转动

数据参数意义:

        此时产生PWM波形频率:72M / (719 +1)/ (1999+1) = 50Hz

        定时器周期:1/50 = 20ms

(4)SPI设置 :用于与LCD屏的通讯

(5)时钟树

2、程序代码

(1)main函数

int main(void)
{/* USER CODE BEGIN 1 */int i=50;double k;int d;/* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_SPI2_Init();MX_TIM1_Init();MX_TIM2_Init();MX_TIM3_Init();/* USER CODE BEGIN 2 */Lcd_Init();//LCD屏初始化LCD_LED_SET;//通过IO控制背光LCD_RST_SET;Lcd_Clear(BLACK);//画雷达图radar_picture();	 Hcsr04Init(&htim2, TIM_CHANNEL_1);//超声波测距初始化Hcsr04Start();HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);//***初始化定时器,用于舵机的控制/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */if(i==50){		for(i=50;i<250;i++){	Hcsr04Start();d = (int)Hcsr04Read()*152/100;//将超声波测得的距离投射在LCD屏上的距离if(d>152)		//测距越界{d=155;}LCD_Showdecimal(63,215,Hcsr04Read(),3,2,16);//LCD屏显示超声波的距离LCD_ShowNum(65,5,(double)(i-50)/200*180,3);//LCD屏显示旋转角度__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,i); //舵机运动		HAL_Delay(100);Radarline2((double)((i-50)*180/200),d);//在LCD屏画出超声波检测到物体的点//			Radarline((double)((i-50)*180/200),(int)Hcsr04Read()*152/300);			}}if(i==250){		for(i=250;i>50;i--){	Hcsr04Start();d = (int)Hcsr04Read()*152/100;if(d>152)		//测距越界{d=155;}LCD_Showdecimal(63,215,Hcsr04Read(),3,2,16);LCD_ShowNum(65,5,(double)(i-50)/200*180,3);//			Radarline((double)((i-50)*180/200),(int)Hcsr04Read()*152/200);//			Radarline((double)((i-50)*180/200),120);__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,i); //舵机运动		HAL_Delay(100);	Radarline2((double)((i-50)*180/200),d);//			Radarline((double)((i-50)*180/200),(int)Hcsr04Read()*152/300);			}}//	LCD_Showdecimal(63,215,Hcsr04Read(),3,2,16);//	Gui_DrawFont_GBK16(200,219,GREEN,BLACK,"cm");		//	HAL_Delay(100);	}/* USER CODE END 3 */
}

(2) hc-sr04.c

#include "hc-sr04.h"
#include "tim.h"Hcsr04InfoTypeDef Hcsr04Info;/*** @description: ??????????????????* @param {TIM_HandleTypeDef} *htim* @param {uint32_t} Channel* @return {*}*/
void Hcsr04Init(TIM_HandleTypeDef *htim, uint32_t Channel)
{/*--------[ Configure The HCSR04 IC Timer Channel ] */// MX_TIM2_Init();  // cubemx???Hcsr04Info.prescaler = htim->Init.Prescaler; //  72-1Hcsr04Info.period = htim->Init.Period;       //  65535Hcsr04Info.instance = htim->Instance;        //  TIM2Hcsr04Info.ic_tim_ch = Channel;if(Hcsr04Info.ic_tim_ch == TIM_CHANNEL_1){Hcsr04Info.active_channel = HAL_TIM_ACTIVE_CHANNEL_1;             //  TIM_CHANNEL_4}else if(Hcsr04Info.ic_tim_ch == TIM_CHANNEL_2){Hcsr04Info.active_channel = HAL_TIM_ACTIVE_CHANNEL_2;             //  TIM_CHANNEL_4}else if(Hcsr04Info.ic_tim_ch == TIM_CHANNEL_3){Hcsr04Info.active_channel = HAL_TIM_ACTIVE_CHANNEL_3;             //  TIM_CHANNEL_4}else if(Hcsr04Info.ic_tim_ch == TIM_CHANNEL_4){Hcsr04Info.active_channel = HAL_TIM_ACTIVE_CHANNEL_4;             //  TIM_CHANNEL_4}else if(Hcsr04Info.ic_tim_ch == TIM_CHANNEL_4){Hcsr04Info.active_channel = HAL_TIM_ACTIVE_CHANNEL_4;             //  TIM_CHANNEL_4}/*--------[ Start The ICU Channel ]-------*/HAL_TIM_Base_Start_IT(htim);HAL_TIM_IC_Start_IT(htim, Channel);
}/*** @description: HC-SR04??* @param {*}* @return {*}*/
void Hcsr04Start()
{HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET);Tims_delay_us(10);  //  10us延迟HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET);
}/*** @description: ?????????????* @param {*}    main.c????void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef* htim)* @return {*}*/
void Hcsr04TimOverflowIsr(TIM_HandleTypeDef *htim)
{if(htim->Instance == Hcsr04Info.instance) //  TIM2{Hcsr04Info.tim_overflow_counter++;}
}/*** @description: ???????????->??* @param {*}    main.c????void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)* @return {*}*/
void Hcsr04TimIcIsr(TIM_HandleTypeDef* htim)
{if((htim->Instance == Hcsr04Info.instance) && (htim->Channel == Hcsr04Info.active_channel)){if(Hcsr04Info.edge_state == 0)      //  ?????{// ?????????T1,???????????Hcsr04Info.t1 = HAL_TIM_ReadCapturedValue(htim, Hcsr04Info.ic_tim_ch);__HAL_TIM_SET_CAPTUREPOLARITY(htim, Hcsr04Info.ic_tim_ch, TIM_INPUTCHANNELPOLARITY_FALLING);Hcsr04Info.tim_overflow_counter = 0;  //  ??????????Hcsr04Info.edge_state = 1;        //  ????????????}else if(Hcsr04Info.edge_state == 1) //  ?????{// ???????T2,????????Hcsr04Info.t2 = HAL_TIM_ReadCapturedValue(htim, Hcsr04Info.ic_tim_ch);Hcsr04Info.t2 += Hcsr04Info.tim_overflow_counter * Hcsr04Info.period; //  ???????????Hcsr04Info.high_level_us = Hcsr04Info.t2 - Hcsr04Info.t1; //  ??????? = ?????? - ??????// ????Hcsr04Info.distance = (Hcsr04Info.high_level_us / 1000000.0) * 340.0 / 2.0 * 100.0;// ?????????Hcsr04Info.edge_state = 0;  //  ??????,??__HAL_TIM_SET_CAPTUREPOLARITY(htim, Hcsr04Info.ic_tim_ch, TIM_INPUTCHANNELPOLARITY_RISING);}}
}/*** @description: ???? * @param {*}* @return {*}*/
float Hcsr04Read()
{// ??????if(Hcsr04Info.distance >= 500){Hcsr04Info.distance = 500;}return Hcsr04Info.distance;
}///**
//  * @brief  ?????us,Prescaler -> 32-1
//  * @param  us: <= 65535
//  * @retval None
//  */
//void Tims_delay_us(uint16_t nus)
//{
//	__HAL_TIM_SET_COUNTER(DLY_TIM_Handle, 0);
//	__HAL_TIM_ENABLE(DLY_TIM_Handle);
//	while (__HAL_TIM_GET_COUNTER(DLY_TIM_Handle) < nus)
//	{
//	}
//	__HAL_TIM_DISABLE(DLY_TIM_Handle);
//}

(3) lcd.c   LCD屏的驱动代码

#include "lcd.h"
#include "spi.h"
#include "gpio.h"/****************************************************************************
* 名    称:void  SPIv_WriteData(u8 Data)
* 功    能:STM32_模拟SPI写一个字节数据底层函数
* 入口参数:Data
* 出口参数:无
* 说    明:STM32_模拟SPI读写一个字节数据底层函数
****************************************************************************/
//void  SPIv_WriteData(u8 Data)
//{
//	unsigned char i=0;
//	for(i=8;i>0;i--)
//	{
//	  if(Data&0x80)	
//		{
//			LCD_SDA_SET; //????
//		}
//    else 
//		{
//			LCD_SDA_CLR;
//		}	   
//      LCD_SCL_CLR;       
//      LCD_SCL_SET;
//      Data<<=1; 
//	}
//}void  SPIv_WriteData(u8 Data)
{SPI_WriteByte(&Data, 1);
}/****************************************************************************
* 名    称:Lcd_WriteIndex(u8 Index)
* 功    能:向液晶屏写一个8位指令
* 入口参数:Index   寄存器地址
* 出口参数:无
* 说    明:调用前需先选中控制器,内部函数
****************************************************************************/
void Lcd_WriteIndex(u8 Index)
{LCD_CS_CLR;LCD_RS_CLR;SPIv_WriteData(Index);LCD_CS_SET;
}/****************************************************************************
* 名    称:Lcd_WriteData(u8 Data)
* 功    能:向液晶屏写一个8位数据
* 入口参数:dat     寄存器数据
* 出口参数:无
* 说    明:向控制器指定地址写入数据,内部函数
****************************************************************************/
void Lcd_WriteData(u8 Data)
{LCD_CS_CLR;LCD_RS_SET;SPIv_WriteData(Data);LCD_CS_SET;
}/****************************************************************************
* 名    称:void LCD_WriteReg(u8 Index,u16 Data)
* 功    能:写寄存器数据
* 入口参数:Index,Data
* 出口参数:无
* 说    明:本函数为组合函数,向Index地址的寄存器写入Data值
****************************************************************************/
void LCD_WriteReg(u8 Index,u16 Data)
{Lcd_WriteIndex(Index);Lcd_WriteData_16Bit(Data);
}/****************************************************************************
* 名    称:void Lcd_WriteData_16Bit(u16 Data)
* 功    能:向液晶屏写一个16位数据
* 入口参数:Data
* 出口参数:无
* 说    明:向控制器指定地址写入一个16位数据
****************************************************************************/
void Lcd_WriteData_16Bit(u16 Data)
{	LCD_CS_CLR;LCD_RS_SET;Lcd_WriteData(Data>>8);Lcd_WriteData(Data);LCD_CS_SET;
}/****************************************************************************
* 名    称:void Lcd_Reset(void)
* 功    能:液晶硬复位函数
* 入口参数:无
* 出口参数:无
* 说    明:液晶初始化前需执行一次复位操作
****************************************************************************/
void Lcd_Reset(void)
{LCD_RST_CLR;HAL_Delay(100);LCD_RST_SET;HAL_Delay(50);LCD_LED_SET;
}void Lcd_Init(void)
{	Lcd_Reset(); //Reset before LCD Init.//2.2inch TM2.2-G2.2 Init 20171020 Lcd_WriteIndex(0x11);  Lcd_WriteData(0x00); Lcd_WriteIndex(0xCF);  Lcd_WriteData(0X00); Lcd_WriteData(0XC1); Lcd_WriteData(0X30);Lcd_WriteIndex(0xED);  Lcd_WriteData(0X64); Lcd_WriteData(0X03); Lcd_WriteData(0X12);Lcd_WriteData(0X81);Lcd_WriteIndex(0xE8);  Lcd_WriteData(0X85); Lcd_WriteData(0X11); Lcd_WriteData(0X78);Lcd_WriteIndex(0xF6);  Lcd_WriteData(0X01); Lcd_WriteData(0X30); Lcd_WriteData(0X00);Lcd_WriteIndex(0xCB);  Lcd_WriteData(0X39); Lcd_WriteData(0X2C); Lcd_WriteData(0X00);Lcd_WriteData(0X34);Lcd_WriteData(0X05);Lcd_WriteIndex(0xF7);  Lcd_WriteData(0X20); Lcd_WriteIndex(0xEA);  Lcd_WriteData(0X00); Lcd_WriteData(0X00); Lcd_WriteIndex(0xC0);  Lcd_WriteData(0X20); Lcd_WriteIndex(0xC1);  Lcd_WriteData(0X11); Lcd_WriteIndex(0xC5);  Lcd_WriteData(0X31); Lcd_WriteData(0X3C); Lcd_WriteIndex(0xC7);  Lcd_WriteData(0XA9); Lcd_WriteIndex(0x3A);  Lcd_WriteData(0X55); Lcd_WriteIndex(0x36);  #if USE_HORIZONTALLcd_WriteData(0xE8);//横屏参数#elseLcd_WriteData(0x48);//竖屏参数 #endifLcd_WriteIndex(0xB1);  Lcd_WriteData(0X00); Lcd_WriteData(0X18); Lcd_WriteIndex(0xB4);  Lcd_WriteData(0X00); Lcd_WriteData(0X00); Lcd_WriteIndex(0xF2);  Lcd_WriteData(0X00); Lcd_WriteIndex(0x26);  Lcd_WriteData(0X01); Lcd_WriteIndex(0xE0);  Lcd_WriteData(0X0F); Lcd_WriteData(0X17); Lcd_WriteData(0X14); Lcd_WriteData(0X09); Lcd_WriteData(0X0C); Lcd_WriteData(0X06); Lcd_WriteData(0X43); Lcd_WriteData(0X75); Lcd_WriteData(0X36); Lcd_WriteData(0X08); Lcd_WriteData(0X13); Lcd_WriteData(0X05); Lcd_WriteData(0X10); Lcd_WriteData(0X0B); Lcd_WriteData(0X08); Lcd_WriteIndex(0xE1);  Lcd_WriteData(0X00); Lcd_WriteData(0X1F); Lcd_WriteData(0X23); Lcd_WriteData(0X03); Lcd_WriteData(0X0E); Lcd_WriteData(0X04); Lcd_WriteData(0X39); Lcd_WriteData(0X25); Lcd_WriteData(0X4D); Lcd_WriteData(0X06); Lcd_WriteData(0X0D); Lcd_WriteData(0X0B); Lcd_WriteData(0X33); Lcd_WriteData(0X37); Lcd_WriteData(0X0F); Lcd_WriteIndex(0x29);  	
}/*************************************************
函数名:LCD_Set_XY
功能:设置lcd显示起始点
入口参数:xy坐标
返回值:无
*************************************************/
void Lcd_SetXY(u16 Xpos, u16 Ypos)
{	Lcd_WriteIndex(0x2A);Lcd_WriteData_16Bit(Xpos);Lcd_WriteIndex(0x2B);Lcd_WriteData_16Bit(Ypos);Lcd_WriteIndex(0x2c);	
} 
/*************************************************
函数名:LCD_Set_Region
功能:设置lcd显示区域,在此区域写点数据自动换行
入口参数:xy起点和终点
返回值:无
*************************************************/
//设置显示窗口
void Lcd_SetRegion(u16 xStar, u16 yStar,u16 xEnd,u16 yEnd)
{Lcd_WriteIndex(0x2A);Lcd_WriteData_16Bit(xStar);Lcd_WriteData_16Bit(xEnd);Lcd_WriteIndex(0x2B);Lcd_WriteData_16Bit(yStar);Lcd_WriteData_16Bit(yEnd);Lcd_WriteIndex(0x2c);
}/*************************************************
函数名:LCD_DrawPoint
功能:画一个点
入口参数:xy坐标和颜色数据
返回值:无
*************************************************/
void Gui_DrawPoint(u16 x,u16 y,u16 Data)
{Lcd_SetXY(x,y);Lcd_WriteData_16Bit(Data);}    /*************************************************
函数名:Lcd_Clear
功能:全屏清屏函数
入口参数:填充颜色COLOR
返回值:无
*************************************************/
void Lcd_Clear(u16 Color)               
{	unsigned int i;Lcd_SetRegion(0,0,X_MAX_PIXEL-1,Y_MAX_PIXEL-1);LCD_CS_CLR;LCD_RS_SET;	for(i=0;i<X_MAX_PIXEL*Y_MAX_PIXEL;i++){	
//	  	Lcd_WriteData_16Bit(Color);SPIv_WriteData(Color>>8);SPIv_WriteData(Color);}   LCD_CS_SET;
}

(4)LCDAPI.c   LCD雷达图的绘制封装代码

#include "LCDAPI.h"
#include "lcd.h"
#include "font.h"
#include "oledfont.h"
#include "bmp.h"u16 BACK_COLOR, POINT_COLOR;   
//从ILI93xx读出的数据为GBR格式,而我们写入的时候为RGB格式。
//通过该函数转换
//c:GBR格式的颜色值
//返回值:RGB格式的颜色值
u16 LCD_BGR2RGB(u16 c)
{u16  r,g,b,rgb;   b=(c>>0)&0x1f;g=(c>>5)&0x3f;r=(c>>11)&0x1f;	 rgb=(b<<11)+(g<<5)+(r<<0);		 return(rgb);}void Gui_Circle(u16 X,u16 Y,u16 R,u16 fc) 
{//Bresenham算法 unsigned short  a,b; int c; a=0; b=R; c=3-2*R; while (a<b) { Gui_DrawPoint(X+a,Y+b,fc);     //        7 Gui_DrawPoint(X-a,Y+b,fc);     //        6 Gui_DrawPoint(X+a,Y-b,fc);     //        2 Gui_DrawPoint(X-a,Y-b,fc);     //        3 Gui_DrawPoint(X+b,Y+a,fc);     //        8 Gui_DrawPoint(X-b,Y+a,fc);     //        5 Gui_DrawPoint(X+b,Y-a,fc);     //        1 Gui_DrawPoint(X-b,Y-a,fc);     //        4 if(c<0) c=c+4*a+6; else { c=c+4*(a-b)+10; b-=1; } a+=1; } if (a==b) { Gui_DrawPoint(X+a,Y+b,fc); Gui_DrawPoint(X+a,Y+b,fc); Gui_DrawPoint(X+a,Y-b,fc); Gui_DrawPoint(X-a,Y-b,fc); Gui_DrawPoint(X+b,Y+a,fc); Gui_DrawPoint(X-b,Y+a,fc); Gui_DrawPoint(X+b,Y-a,fc); Gui_DrawPoint(X-b,Y-a,fc); } } 
//画线函数,使用Bresenham 画线算法
void Gui_DrawLine(u16 x0, u16 y0,u16 x1, u16 y1,u16 Color)   
{
int dx,             // difference in x'sdy,             // difference in y'sdx2,            // dx,dy * 2dy2, x_inc,          // amount in pixel space to move during drawingy_inc,          // amount in pixel space to move during drawingerror,          // the discriminant i.e. error i.e. decision variableindex;          // used for looping	Lcd_SetXY(x0,y0);dx = x1-x0;//计算x距离dy = y1-y0;//计算y距离if (dx>=0){x_inc = 1;}else{x_inc = -1;dx    = -dx;  } if (dy>=0){y_inc = 1;} else{y_inc = -1;dy    = -dy; } dx2 = dx << 1;dy2 = dy << 1;if (dx > dy)//x距离大于y距离,那么每个x轴上只有一个点,每个y轴上有若干个点{//且线的点数等于x距离,以x轴递增画点// initialize error termerror = dy2 - dx; // draw the linefor (index=0; index <= dx; index++)//要画的点数不会超过x距离{//画点Gui_DrawPoint(x0,y0,Color);// test if error has overflowedif (error >= 0) //是否需要增加y坐标值{error-=dx2;// move to next liney0+=y_inc;//增加y坐标值} // end if error overflowed// adjust the error termerror+=dy2;// move to the next pixelx0+=x_inc;//x坐标值每次画点后都递增1} // end for} // end if |slope| <= 1else//y轴大于x轴,则每个y轴上只有一个点,x轴若干个点{//以y轴为递增画点// initialize error termerror = dx2 - dy; // draw the linefor (index=0; index <= dy; index++){// set the pixelGui_DrawPoint(x0,y0,Color);// test if error overflowedif (error >= 0){error-=dy2;// move to next linex0+=x_inc;} // end if error overflowed// adjust the error termerror+=dx2;// move to the next pixely0+=y_inc;} // end for} // end else |slope| > 1
}void Gui_box(u16 x, u16 y, u16 w, u16 h,u16 bc)
{Gui_DrawLine(x,y,x+w,y,0xEF7D);Gui_DrawLine(x+w-1,y+1,x+w-1,y+1+h,0x2965);Gui_DrawLine(x,y+h,x+w,y+h,0x2965);Gui_DrawLine(x,y,x,y+h,0xEF7D);Gui_DrawLine(x+1,y+1,x+1+w-2,y+1+h-2,bc);
}
void Gui_box2(u16 x,u16 y,u16 w,u16 h, u8 mode)
{if (mode==0)	{Gui_DrawLine(x,y,x+w,y,0xEF7D);Gui_DrawLine(x+w-1,y+1,x+w-1,y+1+h,0x2965);Gui_DrawLine(x,y+h,x+w,y+h,0x2965);Gui_DrawLine(x,y,x,y+h,0xEF7D);}if (mode==1)	{Gui_DrawLine(x,y,x+w,y,0x2965);Gui_DrawLine(x+w-1,y+1,x+w-1,y+1+h,0xEF7D);Gui_DrawLine(x,y+h,x+w,y+h,0xEF7D);Gui_DrawLine(x,y,x,y+h,0x2965);}if (mode==2)	{Gui_DrawLine(x,y,x+w,y,0xffff);Gui_DrawLine(x+w-1,y+1,x+w-1,y+1+h,0xffff);Gui_DrawLine(x,y+h,x+w,y+h,0xffff);Gui_DrawLine(x,y,x,y+h,0xffff);}
}/**************************************************************************************
功能描述: 在屏幕显示一凸起的按钮框
输    入: u16 x1,y1,x2,y2 按钮框左上角和右下角坐标
输    出: 无
**************************************************************************************/
void DisplayButtonDown(u16 x1,u16 y1,u16 x2,u16 y2)
{Gui_DrawLine(x1,  y1,  x2,y1, GRAY2);  //HGui_DrawLine(x1+1,y1+1,x2,y1+1, GRAY1);  //HGui_DrawLine(x1,  y1,  x1,y2, GRAY2);  //VGui_DrawLine(x1+1,y1+1,x1+1,y2, GRAY1);  //VGui_DrawLine(x1,  y2,  x2,y2, WHITE);  //HGui_DrawLine(x2,  y1,  x2,y2, WHITE);  //V
}/**************************************************************************************
功能描述: 在屏幕显示一凹下的按钮框
输    入: u16 x1,y1,x2,y2 按钮框左上角和右下角坐标
输    出: 无
**************************************************************************************/
void DisplayButtonUp(u16 x1,u16 y1,u16 x2,u16 y2)
{Gui_DrawLine(x1,  y1,  x2,y1, WHITE); //HGui_DrawLine(x1,  y1,  x1,y2, WHITE); //VGui_DrawLine(x1+1,y2-1,x2,y2-1, GRAY1);  //HGui_DrawLine(x1,  y2,  x2,y2, GRAY2);  //HGui_DrawLine(x2-1,y1+1,x2-1,y2, GRAY1);  //VGui_DrawLine(x2  ,y1  ,x2,y2, GRAY2); //V
}//display 16 ziti
void Gui_DrawFont_GBK16(u16 x, u16 y, u16 fc, u16 bc, u8 *s)
{unsigned char i,j;unsigned short k,x0;x0=x;while(*s) {	if((*s) < 128) {k=*s;if (k==13) {x=x0;y+=16;}else {if (k>32) k-=32; else k=0;for(i=0;i<16;i++)for(j=0;j<8;j++) {if(asc16[k*16+i]&(0x80>>j))	Gui_DrawPoint(x+j,y+i,fc);else {if (fc!=bc) Gui_DrawPoint(x+j,y+i,bc);}}x+=8;}s++;}else {for (k=0;k<hz16_num;k++) {if ((hz16[k].Index[0]==*(s))&&(hz16[k].Index[1]==*(s+1))){ for(i=0;i<16;i++){for(j=0;j<8;j++) {if(hz16[k].Msk[i*2]&(0x80>>j))	Gui_DrawPoint(x+j,y+i,fc);else {if (fc!=bc) Gui_DrawPoint(x+j,y+i,bc);}}for(j=0;j<8;j++) {if(hz16[k].Msk[i*2+1]&(0x80>>j))	Gui_DrawPoint(x+j+8,y+i,fc);else {if (fc!=bc) Gui_DrawPoint(x+j+8,y+i,bc);}}}}}s+=2;x+=16;} }
}
//display 24 ziti
void Gui_DrawFont_GBK24(u16 x, u16 y, u16 fc, u16 bc, u8 *s)
{unsigned char i,j;unsigned short k;while(*s) {if( *s < 0x80 ) {k=*s;if (k>32) k-=32; else k=0;for(i=0;i<16;i++)for(j=0;j<8;j++) {if(asc16[k*16+i]&(0x80>>j))	Gui_DrawPoint(x+j,y+i,fc);else {if (fc!=bc) Gui_DrawPoint(x+j,y+i,bc);}}s++;x+=8;}else {for (k=0;k<hz24_num;k++) {if ((hz24[k].Index[0]==*(s))&&(hz24[k].Index[1]==*(s+1))){ for(i=0;i<24;i++){for(j=0;j<8;j++) {if(hz24[k].Msk[i*3]&(0x80>>j))Gui_DrawPoint(x+j,y+i,fc);else {if (fc!=bc) Gui_DrawPoint(x+j,y+i,bc);}}for(j=0;j<8;j++) {if(hz24[k].Msk[i*3+1]&(0x80>>j))	Gui_DrawPoint(x+j+8,y+i,fc);else {if (fc!=bc) Gui_DrawPoint(x+j+8,y+i,bc);}}for(j=0;j<8;j++) {if(hz24[k].Msk[i*3+2]&(0x80>>j))	Gui_DrawPoint(x+j+16,y+i,fc);else {if (fc!=bc) Gui_DrawPoint(x+j+16,y+i,bc);}}}}}s+=2;x+=24;}}
}void Gui_DrawFont_Num32(u16 x, u16 y, u16 fc, u16 bc, u16 num)
{unsigned char i,j,k,c;//lcd_text_any(x+94+i*42,y+34,32,32,0x7E8,0x0,sz32,knum[i]);
//	w=w/8;for(i=0;i<32;i++){for(j=0;j<4;j++) {c=*(sz32+num*32*4+i*4+j);for (k=0;k<8;k++)	{if(c&(0x80>>k))	Gui_DrawPoint(x+j*8+k,y+i,fc);else {if (fc!=bc) Gui_DrawPoint(x+j*8+k,y+i,bc);}}}}
}void Address_set(unsigned int x1,unsigned int y1,unsigned int x2,unsigned int y2)
{ Lcd_WriteIndex(0x2a);Lcd_WriteData(x1>>8);Lcd_WriteData(x1);Lcd_WriteData(x2>>8);Lcd_WriteData(x2);Lcd_WriteIndex(0x2b);Lcd_WriteData(y1>>8);Lcd_WriteData(y1);Lcd_WriteData(y2>>8);Lcd_WriteData(y2);Lcd_WriteIndex(0x2C);					 						 
}//??
//POINT_COLOR:?????
void LCD_DrawPoint(u16 x,u16 y)
{Address_set(x,y,x,y);//?????? Lcd_WriteData_16Bit(POINT_COLOR); 	    
} void LCD_ShowChar(u16 x,u16 y,u8 num,u8 mode)
{u8 temp;u8 pos,t;u16 x0=x;u16 colortemp=GREEN;      if(x>LCD_X_SIZE-16||y>LCD_Y_SIZE-16)return;	    //????		   num=num-' ';//???????Address_set(x,y,x+8-1,y+16-1);      //??????if(mode) //?????{for(pos=0;pos<16;pos++){ temp=asc2_1608[(u16)num*16+pos];		 //??1608??for(t=0;t<8;t++){                 if(temp&0x01)POINT_COLOR=colortemp;else POINT_COLOR=BLACK;Lcd_WriteData_16Bit(POINT_COLOR);	temp>>=1; x++;}x=x0;y++;}	}else//????{for(pos=0;pos<16;pos++){temp=asc2_1608[(u16)num*16+pos];		 //??1608??for(t=0;t<8;t++){                 if(temp&0x01)LCD_DrawPoint(x+t,y+pos);//????     temp>>=1; }}}POINT_COLOR=colortemp;	    	   	 	  
}   unsigned long oled_pow(u8 m,u8 n)
{unsigned long result=1;	 while(n--)result*=m;    return result;
}void LCD_Showdecimal(u8 x,u8 y,float num,u8 z_len,u8 f_len,u8 size2)
{         	u8 t,temp;u8 enshow;int z_temp,f_temp;      z_temp=(int)num;//????for(t=0;t<z_len;t++){temp=(z_temp/oled_pow(10,z_len-t-1))%10;if(enshow==0 && t<(z_len-1)){if(temp==0){LCD_ShowChar(x+(size2/2)*t,y,' ',size2);continue;}elseenshow=1;}LCD_ShowChar(x+(size2/2)*t,y,temp+'0',size2); }//???LCD_ShowChar(x+(size2/2)*(z_len),y,'.',size2); f_temp=(int)((num-z_temp)*(oled_pow(10,f_len)));//????for(t=0;t<f_len;t++){temp=(f_temp/oled_pow(10,f_len-t-1))%10;LCD_ShowChar(x+(size2/2)*(t+z_len)+5,y,temp+'0',size2); }
}void showhanzi(unsigned int x,unsigned int y,unsigned char index)	
{  unsigned char i,j;unsigned char *temp=hanzi;    Address_set(x,y,x+31,y+31); //设置区域      temp+=index*128;	for(j=0;j<128;j++){for(i=0;i<8;i++){ 		     if((*temp&(1<<i))!=0){Lcd_WriteData_16Bit(POINT_COLOR);} else{Lcd_WriteData_16Bit(WHITE);}   }temp++;}
}//显示图片
void showimage(const unsigned char *p) 
{//??128*128 ??int i; unsigned char picH,picL;
//	Lcd_Clear(WHITE); //?? ->1 Address_set(100,100,219,219);for(i=0;i<120*120;i++){	picL=*(p+i*2);	//??????picH=*(p+i*2+1);				Lcd_WriteData_16Bit(picH<<8|picL); 				}	
}//??2???
//x,y :????	 
//len :?????
//color:??
//num:??(0~4294967295);	
void LCD_ShowNum(u16 x,u16 y,unsigned long num,u8 len)
{         	u8 t,temp;u8 enshow=0;num=(u16)num;for(t=0;t<len;t++){temp=(num/oled_pow(10,len-t-1))%10;if(enshow==0&&t<(len-1)){if(temp==0){LCD_ShowChar(x+8*t,y,' ',1);continue;}else enshow=1; }LCD_ShowChar(x+8*t,y,temp+48,1); }
} void picture()
{showimage(gImage_new);
}//矩形
void rectangle(u16 x0, u16 y0, u16 x1, u16 y1,u16 bc)
{int i,j;for(i=x0;i<=x1;i++){for(j=y0;j<=y1;j++){Gui_DrawPoint(i,j,bc);}}
}void LCD_DrawPoint2(u16 x,u16 y,u16 Color)
{Address_set(x,y,x,y);//?????? Lcd_WriteData_16Bit(Color); 	    
} 

(5)radar.c   雷达图的绘制

#include "radar.h"
#include "LCDAPI.h"
#include "lcd.h"
#include "math.h"
#include "hc-sr04.h"void Radarline(double k,int r)
{double x,y;x=160+r*(double)cos(k/180*3.1415926);	y=200-r*(double)sin(k/180*3.1415926);Gui_DrawLine(160,200,x,y,GREEN);}void radar_picture()
{Gui_DrawFont_GBK24(307,98,GREEN,BLACK,"°");Gui_DrawFont_GBK24(263,58,GREEN,BLACK,"°");Gui_DrawFont_GBK24(181,28,GREEN,BLACK,"°");Gui_DrawFont_GBK24(110,40,GREEN,BLACK,"°");Gui_DrawFont_GBK24(35,90,GREEN,BLACK,"°");//雷达图Gui_Circle(160,200,152,GREEN);Gui_Circle(160,200,114,GREEN);Gui_Circle(160,200,76,GREEN);Gui_Circle(160,200,38,GREEN);Radarline(30,170);Radarline(60,170);Radarline(90,170);Radarline(120,170);Radarline(150,170);rectangle(0,200,320,240,BLACK);Gui_DrawLine(0,200,320,200,GREEN);//数据信息Gui_DrawFont_GBK24(0,212,GREEN,BLACK,"距离");Gui_DrawFont_GBK24(50,219,GREEN,BLACK,":");Gui_DrawFont_GBK24(0,0,GREEN,BLACK,"角度");Gui_DrawFont_GBK24(50,7,GREEN,BLACK,":");Gui_DrawFont_GBK24(117,211,GREEN,BLACK,"CM");	Gui_DrawFont_GBK24(100,0,GREEN,BLACK,"°");Gui_DrawFont_GBK16(175,205,GREEN,BLACK,"25");Gui_DrawFont_GBK16(210,205,GREEN,BLACK,"50");Gui_DrawFont_GBK16(245,205,GREEN,BLACK,"75");Gui_DrawFont_GBK16(285,205,GREEN,BLACK,"100");Gui_DrawFont_GBK16(290,100,GREEN,BLACK,"30");Gui_DrawFont_GBK16(247,60,GREEN,BLACK,"60");Gui_DrawFont_GBK16(165,30,GREEN,BLACK,"90");Gui_DrawFont_GBK16(85,42,GREEN,BLACK,"120");Gui_DrawFont_GBK16(10,92,GREEN,BLACK,"150");Gui_DrawFont_GBK24(190,0,GREEN,BLACK,"超声波雷达");//	Gui_DrawFont_GBK24(307,98,GREEN,BLACK,"°");
//	Gui_DrawFont_GBK24(263,58,GREEN,BLACK,"°");
//	Gui_DrawFont_GBK24(185,28,GREEN,BLACK,"°");
//	Gui_DrawFont_GBK24(110,40,GREEN,BLACK,"°");
//	Gui_DrawFont_GBK24(35,90,GREEN,BLACK,"°");
}

七、程序源码工程及原理图下载链接

https://download.csdn.net/download/jacklood/91023554

http://www.xdnf.cn/news/14421.html

相关文章:

  • 3 Studying《THE CACHE MEMORY BOOK》
  • python3.9成功安装nbextensions
  • 【Linux入门】安装一个Linux内核的虚拟机
  • 【IQA技术专题】-PSNR和SSIM
  • DOM-Based XSS(基于文档对象模型的跨站脚本攻击)
  • leetcode 搜索插入位置 java
  • 定时器时基单元参数配置及计算公式
  • Python | Python中最常用的100个函数(含内置函数、标准库函数及第三方库)
  • 基于 Transformer RoBERTa的情感分类任务实践总结之五——剪枝
  • 使用LDA进行主题建模:发现文本中的隐藏主题 - 父亲节特别版
  • 【旧题新解】第 9 集 带余除法
  • router.push()
  • 疗愈经济崛起:如何把“情绪价值”转化为医疗健康产品?
  • 我的研究方向是关于联邦学习的数据隐私保护,这些都是我在学校过程中遇到的困惑,借助ai来解决我的问题,也分享给大家。联邦学习的公开数据集,数据集的使用方法等
  • 《解码SCSS:悬浮与点击效果的高阶塑造法则》
  • 电影院管理系统的设计与实现
  • O - 方差
  • 【项目实训】【项目博客#06】大模型微调与推理优化(4.21-5.11)
  • Velocity提取模板变量
  • 项目三 - 任务7:开发名片管理系统
  • SCAU大数据技术原理期末复习|第10、11章
  • ansible模块使用实践
  • UnityDots学习(六)
  • 手动 + 自动双方案组合:Innocise 壁虎吸盘灵活适配多场景无损搬运需求
  • 谷歌浏览器编译windows版本
  • Vue3相关知识1
  • STM32 HAL库学习 RNG篇
  • 编译链接实战(32)动态库的本质和原理
  • 循环神经网络及其变体
  • 数据库核心技术深度剖析:事务、索引、锁与SQL优化实战指南(第六节)-----InnoDB引擎