一、雷達概述
????????雷達(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