基于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.pswp.cn/news/909498.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/909498.shtml
英文地址,請注明出處:http://en.pswp.cn/news/909498.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

飛書多維表格利用 Amazon Bedrock AI 能力賦能業務

背景 飛書多維表格是一款功能強大的在線數據管理與協作工具。它打破傳統表格局限&#xff0c;將電子表格與數據庫特性融合&#xff0c;支持看板、甘特圖、表單等多種視圖自由切換&#xff0c;可根據項目進度、任務管理等不同場景靈活展示數據。其豐富的字段類型能精準適配各類…

表格對比工具推薦,快速比對Excel文件

軟件介紹 今天為大家推薦一款專為Excel用戶設計的表格比較工具&#xff0c;簡單易用&#xff0c;零基礎也能快速掌握。 輕量高效的辦公助手 Excel比較工具體積僅為11MB&#xff0c;占用空間小&#xff0c;運行流暢&#xff0c;適合各類電腦配置使用。 簡潔明了的操作界面 軟…

深入探究其內存開銷與JVM布局——Java Record

Java 14引入的Record類型如同一股清流&#xff0c;旨在簡化不可變數據載體的定義。它的核心承諾是&#xff1a;??透明的數據建模??和??簡潔的語法??。自動生成的equals(), hashCode(), toString()以及構造器極大地提升了開發效率。 當我們看到這樣的代碼&#xff1a; …

Vue 3 九宮格抽獎系統,采用優雅的 UI 設計和流暢的動畫效果

九宮格抽獎 預覽地址 項目簡介 這是一個基于 Vue 3 開發的現代化九宮格抽獎系統&#xff0c;采用優雅的 UI 設計和流暢的動畫效果&#xff0c;為用戶提供極致的抽獎體驗。系統支持多種獎品配置&#xff0c;實時抽獎記錄展示&#xff0c;以及完整的活動說明功能。 核心功能 …

無縫對接大疆算力平臺:基于Coovally的無人機AI模型端到端優化方案

【導讀】 隨著無人機應用場景的快速拓展&#xff0c;企業對于定制化AI解決方案的需求日益迫切。大疆算力開放平臺為開發者提供了專業的模型量化與部署環境&#xff0c;幫助開發者將訓練好的AI模型高效部署至大疆無人機平臺。 然而&#xff0c;要實現完整的AI開發閉環&#xf…

ubuntu下載CUDA cuDNN

nivida-smi查看顯卡驅動版本 &#xff08;一&#xff09;安裝CUDA cuda官網 cuda官網 下載對應版本的cuda 這個官網真不錯啊&#xff0c;下面附上了指令 wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/x86_64/cuda-ubuntu2404.pin sudo mv c…

FreeRTOS定時器

目錄 1.特性2.運行環境2.1 守護任務2.2 回調函數2.3 內部源碼 3.和Linux對比4.ID5.數據傳輸6.操作函數6.1 創建6.2 刪除6.3 啟動6.4 停止6.5 復位&#xff08;重置&#xff09;6.6 修改周期6.7 注意事項 7.示例&#xff1a;一般使用8.示例&#xff1a;定時器防抖 1.特性 定時器…

JavaScript中的迭代器模式:優雅遍歷數據的“設計之道”

JavaScript中的迭代器模式&#xff1a;優雅遍歷數據的“設計之道” 一、什么是迭代器模式&#xff1f; 在編程世界中&#xff0c;迭代器模式&#xff08;Iterator Pattern&#xff09;是一種經典的設計模式&#xff0c;它的核心思想是&#xff1a;為集合對象提供一種統一的訪…

Debian/Ubuntu systemd coredump調試程序Crash

程序是通過systemd監管&#xff0c;當程序出現crash的時候&#xff0c;需要保存crash的日志&#xff0c;也就是coredump日志&#xff0c;按照一般做法設置coredump。而在安裝有systemd服務的系統中一般都有systemd-coredump服務。 systemd-coredump 是 systemd 子系統中的一個工…

【圖片轉 3D 模型】北大·字節跳動·CMU攜手——單圖15 秒生成結構化3D模型!

??引言&#xff1a;單圖生成結構化 3 D 模型的技術突破? ? PartCrafter 由北京大學、字節跳動與卡耐基梅隆大學聯合研發&#xff0c;是全球首個??端到端生成結構化 3 D 網格??的模型。它僅需單張 RGB 圖像&#xff0c;即可在 34 秒內生成帶語義分解的 3 D 部件&#xf…

零基礎RT-thread第二節:按鍵控制

我這里依然使用的是野火開發板&#xff0c;F767芯片。 這一節寫一下按鍵控制LED亮滅。 這是按鍵以及LED的原理圖。 按鍵對應的引腳不按下時是低電平&#xff0c;按下后是高電平。 LED是在低電平點亮。 接下來是key.c: /** Copyright (c) 2006-2021, RT-Thread Development T…

《Gulp與SCSS:解構前端樣式開發的底層邏輯與實戰智慧》

探尋Gulp與SCSS協作的底層邏輯 Gulp&#xff0c;作為任務自動化的佼佼者&#xff0c;其核心價值在于將一系列復雜的任務&#xff0c;如文件的編譯、合并、壓縮等&#xff0c;以一種流暢且高效的方式串聯起來&#xff0c;形成一個自動化的工作流。它基于流&#xff08;stream&a…

OpenCV CUDA模塊圖像變形------對圖像進行GPU加速的透視變換函數warpPerspective()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 該函數用于對圖像進行 GPU 加速的透視變換&#xff08;Perspective Transformation&#xff09;&#xff0c;是 cv::warpPerspective 的 CUDA 版…

吳恩達機器學習筆記(2)—單變量線性回歸

目錄 一、模型表示 二、代價函數 三、代價函數的直觀理解&#xff08;1&#xff09; 四、代價函數的直觀理解&#xff08;2&#xff09; 五、梯度下降 六、梯度下降的直觀理解 七、線性回歸的梯度下降 在本篇內容中&#xff0c;我們將介紹第一個機器學習算法——線性回歸…

最新華為 HCIP-Datacom(H12-821)

最新 HCIP-Datacom&#xff08;H12-821&#xff09;&#xff0c;完整題庫請上方訪問&#xff0c;更新完畢。 在OSPF網絡中&#xff0c;NSSA區域與STUB區域都是為了減少LSA數量&#xff0c;兩者最主要的區別在于&#xff0c;NSSA區域可以引入外部路由&#xff0c;并同時接收OSPF…

vba學習系列(11)--批退率通過率等數據分析

系列文章目錄 文章目錄 系列文章目錄前言一、外觀報表1.產能2.固定傷排查3.鏡片不良TOP4.鏡片公式計算5.鏡片良率計算6.鏡片批退率7.鏡筒不良TOP8.鏡筒公式計算9.鏡筒良率計算10.鏡筒批退率 二、反射率報表1.機臺通過率2.鏡片通過率圈數分析3.鏡片通過率罩次分析4.鏡筒通過率圈…

成功在 Conda Python 2.7 環境中安裝 Clipper(eCLIP peak caller)

&#x1f52c; 成功在 Conda Python 2.7 環境中安裝 Clipper&#xff08;eCLIP peak caller&#xff09; 本文記錄了如何在無 root 權限下使用 Conda 環境&#xff0c;解決依賴、構建擴展模塊并成功安裝運行 clipper 的詳細流程。適用于再現 eCLIP 分析流程時遇到 clipper 安裝…

通過 VS Code 連接 GitLab 并上傳項目

通過 VS Code 連接 GitLab 并上傳項目&#xff0c;請按照以下步驟操作&#xff1a; 1. 安裝必要工具 確保已安裝 Git 并配置用戶名和郵箱&#xff1a; git config --global user.name "你的用戶名" git config --global user.email "你的郵箱" 在 VS Cod…

開源夜鶯支持MySQL數據源,更方便做業務指標監控了

夜鶯監控項目最核心的定位&#xff0c;是做一個告警引擎&#xff0c;支持多種數據源的告警。這個版本的更新主要是增加了對 MySQL 數據源的支持&#xff0c;進一步增強了夜鶯在業務指標監控方面的能力。 之前版本的夜鶯主要聚焦在 Prometheus、VictoriaMetrics、ElasticSearch…

SpringCloud + MybatisPlus:多租戶模式與實現

一、多租戶的基本概念 多租戶(Multi-Tenancy) 是指在一套軟件系統中,多個租戶(客戶)共享相同的基礎設施和應用程序,但數據和配置相互隔離的架構模式。其核心目標是 降低成本 和 保證數據安全。 核心特點: 資源共享:租戶共享服務器、數據庫、代碼等資源。數據隔離:通…