STM32F103RET6 4G开发板的LVGL GUI图形界面的移植和用法

文档结尾有代码下载链接

🎯 实现效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

🌟 传感器的介绍

LVGL(Light and Versatile Graphics Library)是一款开源嵌入式图形库,主打轻量、跨平台特性,专为资源受限的嵌入式设备设计,能快速开发出流畅、美观的 GUI(图形用户界面)。

1.核心定位与核心优势

  • LVGL 的核心价值在于平衡 “资源占用” 与 “GUI 体验”,让低性能嵌入式设备也能拥有接近高端设备的界面效果,核心优势如下:
    极致轻量:最低仅需 64KB RAM 和 128KB Flash 即可运行,适配 8 位、16 位、32 位 MCU(如 STM32、ESP32、PIC 等),完全满足嵌入式设备的资源限制。
  • 强跨平台性:不依赖特定硬件或操作系统,支持裸机(无 OS)、RTOS(FreeRTOS、RT-Thread 等)、Linux/Windows,可轻松移植到 LCD、OLED 等各类显示设备。
  • 易用性高:提供简洁的 C 语言 API,支持链式调用;配套可视化开发工具,无需手动写大量界面代码,降低嵌入式 GUI 开发门槛。
  • 高性能体验:支持硬件加速(如 DMA、GPU),自带反锯齿、透明度、平滑动画效果,界面刷新帧率可达 60FPS,触摸响应流畅。

2.典型适用场景
LVGL 专为嵌入式场景设计,覆盖各类需要 GUI 交互的设备,尤其匹配你之前的嵌入式项目(4G 物联网终端),常见场景包括:

  • 物联网(IoT)终端:如温湿度监测屏、智能网关面板(对应你项目中 LCD 显示温湿度、GPS 数据的场景)。
  • 工业控制设备:如 PLC 触摸屏、传感器控制台,支持显示实时数据、操作按钮、状态警告。
  • 智能穿戴设备:如智能手表、手环,适配小尺寸屏幕,支持低功耗运行。
  • 汽车电子:如车载中控副屏、仪表盘,支持多页面切换、动画过渡。
  • 消费电子:如智能家居控制面板、小型家电显示界面。

🌟 驱动思路

LVGL 与 STM32 的交互主要依赖显示驱动(Disp)、输入驱动(Indev)、定时器驱动(Tick),三者共同构成驱动核心。整体流程为:STM32硬件初始化 → 实现LVGL抽象接口函数 → 向LVGL注册接口 → LVGL调用接口操作硬件。

步骤 1:显示驱动:LVGL ↔ STM32 LCD

显示驱动是最核心的部分,负责将 LVGL 生成的图像数据渲染到 STM32 外接的 LCD/OLED 屏幕上。

  • 首先需根据 LCD 的接口类型初始化STM32的硬件外设:
  • 初始化步骤:① 配置 LCD 引脚(GPIO 推挽输出 / 复用);② 初始化外设,设置时序;③ 初始化 LCD 控制器
  • LVGL 输入接口实现
  • LVGL 输入驱动需实现读取回调函数,并注册输入设备类型
  • 注册输入驱动

步骤 2:输入驱动–LVGL ↔ STM32 触摸 / 按键

输入驱动负责将 STM32 的输入设备(如触摸屏幕、物理按键)信号转换为 LVGL 可识别的事件(如按下、滑动、释放)。

步骤 3.:定时器驱动(Tick Driver):LVGL 时间基准

LVGL 需要1ms 级的时间基准来实现动画、任务调度、触摸防抖等功能,这由 STM32 的定时器中断提供。

LVGL数据显示修改
其中,LVGL 显示的温度 / 湿度数据,来自代码中这两处:
标签显示:通过lv_label_set_text用DHT11_Data.temp_int(温度)和DHT11_Data.humi_int(湿度)设置文本。
折线图显示:通过lv_chart_set_next_value用上述两个变量更新图表数据。
因此,在这两处代码之前修改数据源,即可单独调整 LVGL 的显示内容。
在这里插入图片描述

🎯 单片机程序代码

main.c

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"	 
#include "lcd_init.h"
#include "lcd.h"
#include "pic.h"
#include "lv_port_disp_template.h"
#include "lv_conf.h"
#include "lv_port_indev_template.h"
#include "lv_demo_stress.h"
#include "gui_guider.h"
#include "events_init.h"
#include "lv_analogclock.h"
#include "lv_demo_stress.h"
#include "timer.h"
#include "4g.h"
#include "dht11.h"


/*****************************************************
下面就是需要修改的地方,修改服务器的IP地址和端口号
*****************************************************/
#define SERVER4GIP "101.200.212.234"
#define SERVER4GPORT "1001"
/////////////////////////////////////////////////////

lv_ui guider_ui;

uint16_t lv_task_run_time = 0;
uint16_t timer3_count = 0;
uint16_t lv_run_count = 0;
uint16_t com_updata_count = 0;
uint16_t send_data_count = 0;
uint16_t get_gps_count1 = 0;
uint16_t get_gps_count2 = 0;
uint16_t get_sensor_count = 0;
uint16_t get_gps_flag = 0;



 int main(void)
 {	 		    
	char label_buf[10];
	uint8_t i = 0;
	char temp_disp[128];
	char *gpsStr;
	delay_init();	    	 //延时函数初始化	  
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
	CSTX_4GCTR_Init();        //初始化CSTX_4G的供电引脚 对模块进行供电
	uart_init(115200);	 	//串口初始化为115200
	Uart1_SendStr("UART1 Init Successful\r\n");
	Key_Init();
	 
	LED_Init();		  		//初始化与LED连接的硬件接口
	LED_Run();					//初始化跑马灯
	uart2_init(115200);//初始化和EC200连接串口	
	Uart2_SendStr("UART2 Init Successful\r\n");

	uart3_init(115200);
	Uart3_SendStr("UART3 Init Successful\r\n");
	printf("\r\n ############ http://www.csgsm.com/ ############\r\n ############("__DATE__ " - " __TIME__ ")############");
	 
	lv_init();
	lv_port_disp_init();
 	lv_port_indev_init();
	 
	 
	setup_ui(&guider_ui);
	events_init(&guider_ui);
	LCD_Fill(0,0,128,160,WHITE);
	CSTX_4G_Init();//对设备初始化
	Start_GPS();//早点开启GPS让他定位好
	CSTX_4G_ConUDP();//关闭上一次连接
	CSTX_4G_CreateUDPSokcet((u8 *)SERVER4GIP,(u8 *)SERVER4GPORT);//创建一个SOCKET连接
	Clear_Buffer_UART1();		//清空串口1的数据
	DHT11_Init();	//初始化温湿度 用PA11

	printf("开始运行主循环\r\n");
	TIM3_Int_Init(10-1,7200-1);//100000
	TIM2_Int_Init(65535,7200-1);//100us
	while(1)
	{
		//20ms 运行一次
		if(lv_run_count >=  20)
		{
			TIM2->CNT = 0;
			lv_task_handler();
			if(TIM2->CNT > lv_task_run_time)
			{
				lv_task_run_time = TIM2->CNT;
			}
			
			//500 ms执行一次
			if(com_updata_count >= 500)
			{
				com_updata_count = 0;
				//如果页面处于是第一页
				if(lv_scr_act() == guider_ui.screen)
				{		
					i = i < 70?++i:0;
					memset(label_buf,0,sizeof(label_buf));
					sprintf(label_buf,"%d",DHT11_Data.temp_int);
					lv_label_set_text(guider_ui.screen_label_2, label_buf);
					memset(label_buf,0,sizeof(label_buf));
					sprintf(label_buf,"%d",DHT11_Data.humi_int);
					lv_label_set_text(guider_ui.screen_label_4, label_buf);
					
					//第一根折线
					lv_chart_set_next_value(guider_ui.screen_chart_1, guider_ui.screen_chart_1_0, DHT11_Data.temp_int);
					//第二根折线
					lv_chart_set_next_value(guider_ui.screen_chart_1, guider_ui.screen_chart_1_1, DHT11_Data.humi_int);
					
					if( DHT11_Data.temp_int >= 34)
					{
						if(lv_obj_has_flag(guider_ui.screen_label_5, LV_OBJ_FLAG_HIDDEN) == true)
						{
							start_label_();//lv_obj_has_flag
							lv_obj_clear_flag(guider_ui.screen_label_5, LV_OBJ_FLAG_HIDDEN);
							lv_label_set_text(guider_ui.screen_label_5, "temp high");
						}
					}
					
					if( DHT11_Data.humi_int >= 60)
					{
						if(lv_obj_has_flag(guider_ui.screen_label_5, LV_OBJ_FLAG_HIDDEN) == true)
						{
							start_label_();//lv_obj_has_flag
							lv_obj_clear_flag(guider_ui.screen_label_5, LV_OBJ_FLAG_HIDDEN);
							lv_label_set_text(guider_ui.screen_label_5, "humi high");
						}
						
					}
					
					if(DHT11_Data.humi_int < 60 && DHT11_Data.temp_int < 34)
					{
							if(lv_obj_has_flag(guider_ui.screen_label_5, LV_OBJ_FLAG_HIDDEN) == false) end_label_();
					}
				}
			}
			lv_run_count = 0;
		}
		
		if(lv_scr_act() == guider_ui.screen)
		{	
				//1200ms执行一次
			if(send_data_count > 1200)
			{
				//printf("\r\n==111===\r\n");
				memset(temp_disp,0,128);	//清空需要装载的数组
				sprintf(temp_disp,"temperature:%d.0#",DHT11_Data.temp_int);	//温湿度打印到数组
				CSTX_4G_Senddata(strlen((const char *)temp_disp),(uint8_t *)temp_disp);//发数据
				send_data_count = 0;
			}
			
			//600ms执行一次
			if(get_sensor_count > 600)
			{
				DHT11_Read_TempAndHumidity();	//读取温湿度
				printf("DHT11 温度:%d 湿度:%d \r\n",DHT11_Data.temp_int,DHT11_Data.humi_int);	 //打印温湿度
				get_sensor_count = 0;
			}
			//接收到数据后执行一次
			if(buf_uart1.index>0 && buf_uart1.rx_flag == 1)
			{
				printf("=====Send PC Data=====\r\n");	//标识 PC 发送过来的数据 
				CSTX_4G_Senddata(buf_uart1.index,(uint8_t *)buf_uart1.buf);	//发送串口1的数据到服务器
				Clear_Buffer_UART1();	//清空串口1
				LED1=!LED1;	//第一个灯闪烁
			}
			
			if(get_gps_count1 >= 1500 && get_gps_flag == 0)
			{
				Get_GPS_LOC();
				get_gps_count1 = 0;
				get_gps_flag = 1;
				get_gps_count2 = 0;
			}
			if(get_gps_count2 > 1500 && get_gps_flag == 1)
			{
				gpsStr=Get_GPS_RMC();	//获取GPRMC数据
				CSTX_4G_Senddata(strlen((const char *)gpsStr),(uint8_t *)gpsStr);//发数据GPRMC到服务器显示
				get_gps_count2 = 0;
				get_gps_count1 = 0;
				get_gps_flag = 0;
			}
			
			CSTX_4G_RECTCPData();//收数据,接收服务器下发的数据并打印到串口1进行显示
		}

		//1000ms执行一次
		if(timer3_count >= 1000)
		{
			//printf("%d %d\r\n",GPIO_ReadInputDataBit(KEY1_INT_GPIO_PORT, KEY1_INT_GPIO_PIN),GPIO_ReadInputDataBit(KEY2_INT_GPIO_PORT, KEY2_INT_GPIO_PIN));
			printf("\r\n[time]-->(%.2f)ms\r\n",lv_task_run_time/10.0f);
			timer3_count = 0;
			lv_task_run_time = 0;
		}
		
		
	}
}


//定时器3中断服务程序
void TIM3_IRQHandler(void)   //TIM3中断
{
	if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
		{
			TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx更新中断标志 
			lv_tick_inc(1);//在中断里面进行刷新
			timer3_count++;
			lv_run_count++;
			com_updata_count++;
			send_data_count++;
			get_sensor_count++;
			get_gps_count1++;
			get_gps_count2++;
			Key_Handler();
		}
}

rs485.c

#include "4G.h"
#include "string.h"
#include "usart.h"
#include "led.h"
///////////////下面是液晶屏头文件/////////////////////
#include "Lcd_Driver.h"
#include "GUI.h"
#include "delay.h"
//#include "Picture.h"
#include "QDTFT_demo.h"
/////////////////////////////////////////////////////
char *strx,*extstrx;

CSTX_4G CSTX_4G_Status;	//模块的状态信息
int  errcount=0;	//发送命令失败次数 防止死循环
int  errCountData=0;
char ATSTR[BUFLEN];	//组建AT命令的函数
char GPRMCSTR[BUFLEN]; //转载GPS信息 GPRMC


/*****************************************************
清空模块反馈的信息
*****************************************************/
void Clear_Buffer(void)//清空缓存
{
		printf(buf_uart2.buf);
	
		strx=strstr((const char*)buf_uart2.buf,(const char*)"+QIURC");//返回+QIURC:,表明接收到TCP服务器发回的数据
    if(strx)
    {
				Gui_DrawFont_GBK16(16,10,RED,WHITE, "RECEIVE DATA");      
    }
		
    delay_ms(300);
    buf_uart2.index=0;
    memset(buf_uart2.buf,0,BUFLEN);
	
}


/*****************************************************
初始化模块 和单片机连接,获取卡号和信号质量
*****************************************************/
void CSTX_4G_Init(void)
{
		//打印初始化信息
		printf("start init EC200X\r\n");
		//发第一个命令ATE1
    Uart2_SendStr("ATE1\r\n"); 
    delay_ms(300);
		printf(buf_uart2.buf);      //打印串口收到的信息
    strx=strstr((const char*)buf_uart2.buf,(const char*)"OK");//返回OK
    Clear_Buffer();	
    while(strx==NULL)
    {
				//Gui_DrawFont_GBK16(16,70,RED,WHITE, "全程技术支持");
				Gui_DrawFont_GBK16(16,10,RED,WHITE, "CONNECT 4G..");
				printf("单片机正在连接模块......\r\n");
        Clear_Buffer();	
        Uart2_SendStr("ATE1\r\n"); 
        delay_ms(300);
        strx=strstr((const char*)buf_uart2.buf,(const char*)"OK");//返回OK
    }
	  Gui_DrawFont_GBK16(16,10,RED,WHITE, "CONNECT [OK]");
		printf("****单片机和模块连接成功*****\r\n");
		Uart2_SendStr("ATI\r\n");//获取模块的版本
		delay_ms(300);
		Clear_Buffer();	
		
    Uart2_SendStr("AT+CIMI\r\n");//获取卡号,类似是否存在卡的意思,比较重要。
    delay_ms(300);
    strx=strstr((const char*)buf_uart2.buf,(const char*)"460");//返460,表明识别到卡了
    while(strx==NULL)
    {
        Clear_Buffer();	
        Uart2_SendStr("AT+CIMI\r\n");//获取卡号,类似是否存在卡的意思,比较重要。
        delay_ms(300);
        strx=strstr((const char*)buf_uart2.buf,(const char*)"460");//返回OK,说明卡是存在的
    } 
		printf("我的卡号是 : %s \r\n",buf_uart2.buf+8);
		Clear_Buffer();	
		
	  Gui_DrawFont_GBK16(16,10,RED,WHITE, "SIMCARD [OK]");
		
		Uart2_SendStr("AT+CGATT?\r\n");//查询激活状态
		delay_ms(300);
		strx=strstr((const char*)buf_uart2.buf,(const char*)"+CGATT: 1");//返1
		Clear_Buffer();	
		while(strx==NULL)
		{
				Clear_Buffer();	
				Uart2_SendStr("AT+CGATT?\r\n");//获取激活状态
				delay_ms(300);
				strx=strstr((const char*)buf_uart2.buf,(const char*)"+CGATT: 1");//返回1,表明注网成功
		}
		
	  Gui_DrawFont_GBK16(16,10,RED,WHITE, "REGISTER[OK]");
		
		
		Clear_Buffer();	
		Uart2_SendStr("AT+CSQ\r\n");//查看获取CSQ值
		delay_ms(300);
    strx=strstr((const char*)buf_uart2.buf,(const char*)"+CSQ:");//返回CSQ
		if(strx)
		{
				
				printf("信号质量是:%s 注意:信号最大值是31 \r\n",buf_uart2.buf+14);      
		}
}


/*
AT+QGPSLOC=0

+QGPSLOC: 035658.000,2603.8722N,11912.4159E,1.8,269.9,3,000.00,0.4,0.2,140821,10

OK
AT+QGPSLOC=1

+QGPSLOC: 035702.000,2603.871651,N,11912.416382,E,1.8,268.8,3,000.00,1.2,0.6,140821,11

OK
AT+QGPSLOC=2

+QGPSLOC: 035704.000,26.06451,119.20694,1.8,270.8,3,000.00,0.2,0.1,140821,11

OK
*/
void Get_GPS_LOC(void)
{
		Clear_Buffer();	
		memset(GPRMCSTR,0,BUFLEN);
		Uart2_SendStr("AT+QGPSLOC=2\r\n");//查询激活状态
		delay_ms(200);
		strx=strstr((const char*)buf_uart2.buf,(const char*)"+QGPSLOC:");//如果反馈错误就表示没有定位好
		
		if(strx)	//没有反馈错误就表示有经纬度了 然后来进行显示 反馈得到LOC就表示有位置了
		{
				strncpy(GPRMCSTR,strx+21,18);
				printf("模块定位好了经纬度是 %s\r\n",GPRMCSTR);
				memset(GPRMCSTR,0,BUFLEN);
				strncpy(GPRMCSTR,strx+21,8);
				//Gui_DrawFont_GBK16(0,90,RED,WHITE, (u8*) GPRMCSTR);
				memset(GPRMCSTR,0,BUFLEN);
				strncpy(GPRMCSTR,strx+30,9);
				//Gui_DrawFont_GBK16(0,110,RED,WHITE, (u8*) GPRMCSTR);
				
		}
		Clear_Buffer();	
}

/*
AT+QGPSGNMEA="RMC"

+QGPSGNMEA: $GNRMC,035645.00,A,2603.9111,N,11912.4140,E,0.336,,140821,,,A,V*19

OK
*/

char *Get_GPS_RMC(void)
{
		Clear_Buffer();	
		memset(GPRMCSTR,0,BUFLEN);
		Uart2_SendStr("AT+QGPSGNMEA=\"RMC\"\r\n");//查询激活状态
		//delay_ms(300);
		strx=strstr((const char*)buf_uart2.buf,(const char*)"$GNRMC");//返1
		
		while(strx==NULL)
		{
				Clear_Buffer();	
				Uart2_SendStr("AT+QGPSGNMEA=\"RMC\"\r\n");//获取激活状态
				delay_ms(100);
				strx=strstr((const char*)buf_uart2.buf,(const char*)"$GNRMC");//返回1,表明注网成功
		}
		sprintf(GPRMCSTR,"%s",strx);
	  //Gui_DrawFont_GBK16(16,10,RED,WHITE, "REGISTER[OK]");
		//Gui_DrawFont_GBK16(16,10,RED,WHITE, "STARTGPS[OK]");
		Clear_Buffer();
		GPRMCSTR[2]=	'P';
		return GPRMCSTR;
}

void Start_GPS(void)
{
		Clear_Buffer();	
		Uart2_SendStr("AT+QGPS=1\r\n");//查询激活状态
		delay_ms(300);
		strx=strstr((const char*)buf_uart2.buf,(const char*)"OK");//返1
		
		while(strx==NULL)
		{
				delay_ms(300);
				strx=strstr((const char*)buf_uart2.buf,(const char*)"OK");//返回1,表明注网成功
		}
		
	  //Gui_DrawFont_GBK16(16,10,RED,WHITE, "REGISTER[OK]");
		Gui_DrawFont_GBK16(16,10,RED,WHITE, "STARTGPS[OK]");
		Clear_Buffer();	
}


/*****************************************************
关闭之前存在的和服务器的链接 可能反馈失败 
*****************************************************/
void CSTX_4G_ConUDP(void)
{		
		//关闭之前建立的链接
		Uart2_SendStr("AT+QICLOSE=0\r\n");//关闭socekt连接
		delay_ms(100);
		Uart2_SendStr("AT+QICLOSE=1\r\n");//关闭socekt连接
		delay_ms(100);
		Uart2_SendStr("AT+QICLOSE=2\r\n");//关闭socekt连接
		delay_ms(100);
	
    Clear_Buffer();
}


/*****************************************************
建立TCP链接 
*****************************************************/
void CSTX_4G_CreateUDPSokcet(u8 *ServerIP, u8 *Port)//创建sokcet
{
	//void LCD_ShowString(u16 x,u16 y,const u8 *p,u16 fc,u16 bc,u8 sizey,u8 mode)
		Gui_DrawFont_GBK16(0,30,BLUE,WHITE,ServerIP);
		Gui_DrawFont_GBK16(0,50,BLUE,WHITE,"SERVER PORT");
		Gui_DrawFont_GBK16(88,50,BLUE,WHITE,Port);	//显示IP地址和端口号 中文是16个像素 英文是8个像素
		//Gui_DrawFont_GBK16(16,10,RED,WHITE, "SERVER  [OK]");
		Gui_DrawFont_GBK16(16,10,RED,WHITE, "SERVER  [..]");
		memset(ATSTR,0,BUFLEN);
		sprintf(ATSTR,"AT+QIOPEN=1,0,\"UDP\",\"%s\",%s,0,1\r\n",ServerIP,Port);
    Uart2_SendStr(ATSTR);//创建连接TCP,输入IP以及服务器端口号码 
    delay_ms(300);
	
		strx=strstr((const char*)buf_uart2.buf,(const char*)"+QIOPEN: 0,566");//检查是否登陆成功
		if(strx)
		{
			 Gui_DrawFont_GBK16(16,10,RED,WHITE, "SERVER  [NO]");	//链接服务器失败
			 return ;	//如果连接服务器失败就反馈 后面不需要判断是否成功了
		}
	
    strx=strstr((const char*)buf_uart2.buf,(const char*)"+QIOPEN: 0,0");//检查是否登陆成功
	  errcount=0;
		while(strx==NULL)
		{
				errcount++;
				strx=strstr((const char*)buf_uart2.buf,(const char*)"+QIOPEN: 0,0");//检查是否登陆成功
				delay_ms(100);
				if(errcount>100)     //超时退出死循环 表示服务器连接失败
        {
            errcount = 0;
            break;
        }
		}  
	  Gui_DrawFont_GBK16(16,10,RED,WHITE, "SERVER  [OK]");
     Clear_Buffer();	
    
}

/*****************************************************
发送数据函数
*****************************************************/
void CSTX_4G_Senddata(int len,uint8_t *data)//发送字符串数据
{
	  //Gui_DrawFont_GBK16(16,10,RED,WHITE, "SEND DATA...");
		memset(ATSTR,0,BUFLEN);
		sprintf(ATSTR,"AT+QISEND=0,%d\r\n",len);
    Uart2_SendStr(ATSTR);
		//等待模块反馈 >
		strx=strstr((const char*)buf_uart2.buf,(const char*)">");//模块反馈可以发送数据了
    while(strx==NULL)
    {
        errcount++;
        strx=strstr((const char*)buf_uart2.buf,(const char*)">");//模块反馈可以发送数据了
        if(errcount>100)     //防止死循环跳出
        {
            errcount = 0;
            break;
        }
    }
		printf("SEND_DATA : %s",data);
		Uart2_SendStr((char *)data);//发送真正的数据
		
		strx=strstr((const char*)buf_uart2.buf,(const char*)"ERROR");//如果发送失败
		if(strx)
		{
				errCountData++;
				//Gui_DrawFont_GBK16(16,10,RED,WHITE, "SEND DATA NO");
				if(errCountData>3)     //超时退出死循环 表示服务器连接失败
        {
							__set_FAULTMASK(1);//关闭总中断
							NVIC_SystemReset();//请求单片机重启
        }
				return ;	//发送数据失败了就不要去下面判断是否成功了
		}
		
    strx=strstr((const char*)buf_uart2.buf,(const char*)"SEND OK");//检查是否发送成功
		errcount=0;
		while(strx==NULL)	//如果没有收到SEND OK就循环查询 
		{
				errcount++;
				strx=strstr((const char*)buf_uart2.buf,(const char*)"SEND OK");//检查是否发送成功
				delay_ms(10);
				if(errcount>10)     //超时退出死循环 表示服务器连接失败
        {
            errcount = 0;
            break;
        }
		}  
    Clear_Buffer();	//发送完毕清空
	  //Gui_DrawFont_GBK16(16,10,RED,WHITE, "SEND DATA OK");
}


/*****************************************************
收到服务器下发的数据就直接打印
*****************************************************/
void CSTX_4G_RECTCPData(void)
{
    strx=strstr((const char*)buf_uart2.buf,(const char*)"+QIURC");//返回+QIURC:,表明接收到TCP服务器发回的数据
    if(strx)
    {
				Clear_Buffer();   
				//Gui_DrawFont_GBK16(16,10,RED,WHITE, "RECEIVE DATA");      
    }
}

🎯 代码下载链接

https://download.csdn.net/download/qq_41954594/92170392

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐