【STM32多级界面】-LCD结构体多级图形界面框架

2023-05-16

STM32多级界面搭建

在实际的项目之中,需要用单片机在LCD/OLED中搭建一个3级的图形界面。本文的工程文件我将上次传到百度网盘,链接在最后的部分。

  • STM32多级界面搭建
    • 一、方案选择
    • 二、实现效果
    • 三、程序设计
      • 3-1宏定义变量设计
      • 3-2控制函数设计
      • 3-3主函数调用设计
    • 四、总结

一、方案选择

方案一:使用if条件语句写一个界面,但是这种方法在两级界面的时候还可以,在多级界面的时候代码的逻辑上的复杂度会大幅增加,不太使用。

方案二:使用嵌入式图形库lvgl等,但是这个对新手不太友好。

方案三:使用结构体变量存储界面信息,可以是使得多级界面也可以逻辑清晰。

二、实现效果

主界面
在这里插入图片描述菜单界面
在这里插入图片描述

功能界面
在这里插入图片描述

三、程序设计

3-1宏定义变量设计

·界面标志位
在头文件中首先需要定义一个结构体来存放界面标志位,包括现在界面的状态,当前运行的任务状态,以及当前任务是否处于运行状态。

·界面变量
创建三个枚举变量,Main_Interface,Menu_Interface,Task_Interface,来表示目前界面所在的位置,是主界面还是菜单界面还是任务界面。

·任务变量
创建n个任务,每个任务提供一个代号,方便识别。

#ifndef __GUI_H__
#define __GUI_H__
/*********************************************
 * 创建一个结构体
 * 存放界面标志位
*********************************************/
typedef struct
{
    uint8_t Interface_Mark;     //界面状态
    uint8_t Task_Mark;          //任务状态
    uint8_t Run_Task;           //开始运行任务
} Mark;

/*********************************************
 * 创建一个枚举
 * 存放界面变量
*********************************************/
enum
{
    Main_Interface, /****主界面*****/
    Menu_Interface, /****菜单界面***/
    Task_Interface, /****任务界面***/
};
/*********************************************
 * 创建一个枚举
 * 存放功能变量
*********************************************/
enum
{
	F_ONE,
	F_TWO,
	F_THREE,
	F_FOUR,	
	Stopping,		/****任务停止***/
};

extern  Mark Mark_Sign;

void Interface_APP(Mark *Mark_Sign);
void Interface(Mark *Mark_Sign,uint8_t keys);
void GUI_init(void);

#endif

3-2控制函数设计

主函数调用
使用定义的结构体来显示界面,即显示初始界面

显示界面函数
主函数调用,根据Mark_Sign->Interface_Mar变量来确实显示当前所在的界面

功能切换函数:主函数调用,通过扫描按键,当按下对应按键时,执行相应的函数,如确认进入函数,返回退出函数,功能切换函数。

/***************
//初始化,显示主界面
***************/
void GUI_init(void)
{	
	Interface_APP(&Mark_Sign);	
}
/***************
//mian函数中显示,主循环中调用,用于显示界面
***************/
void Interface_APP(Mark *Mark_Sign)
{
	switch (Mark_Sign->Interface_Mark)
	{
		//状态标志位 主界面
		case Main_Interface:
			Main_Interface_APP();//显示主界面
		break;

		//状态标志位 菜单界面
		case Menu_Interface:
			Menu_Interface_APP();//显示菜单界面
		break;

		//状态标志位 任务界面
		case Task_Interface:
			Function_Menu_APP(Mark_Sign);//显示功能界面
		break;
		default:
		break;
	}
}
/***************
//mian函数中显示,主循环中调用,按键扫描,当按下对应按键时,执行相应的函数
***************/
void Interface(Mark *Mark_Sign,uint8_t keys)
{
/* 1,检测当前按下的按键为确认键
 * 2,检测当前的界面
 *    (1)如果是主界面,则进入菜单界面
 *    (2)如果是菜单界面,则进入任务界面
 *     (3)如果是任务界面,则开执行被选中的任务*/   
    if(keys == KEY1_PRES)
    {
		key_Inter(Mark_Sign);
    }
	
/*1,检测当前按下的按键为返回键
 * 2,检测当前的界面
 * (1)如果是任务界面,则停止正在运行的任务,返回到菜单界面
 * (2)如果是菜单界面,则返回到主界面*/
	
    if(keys == KEY2_PRES)
    {
		key_Cancel(Mark_Sign);
    }
/*1,检测当前按下的按键为任务切换
 * (1)在菜单界面,选择切换接下来要运行的任务*/
	if(keys == KEY3_PRES)
    {
		key_Up_move(Mark_Sign);
    }
	if(keys == KEY4_PRES)
    {
		key_Down_move(Mark_Sign);
    }
}

不同界面的显示函数: 主界面,菜单界面,功能界面

static unsigned char Lcd_Disp_String[21];
/***************
//显示主界面
***************/
void Main_Interface_APP(void)
{
		LCD_DisplayStringLine(Line1 ,(unsigned char *)"Main_Interface_APP");
		LCD_DisplayStringLine(Line2 ,(unsigned char *)"ADC-LED-REF");
}


/***************
显示菜单界面
***************/
void Menu_Interface_APP(void)
{
	LCD_DisplayStringLine(Line1 ,(unsigned char *)"Menu_Interface_APP");
}


/***************
显示功能界面
***************/
void Function_Menu_APP(Mark *Mark_Sign)
{
	LCD_DisplayStringLine(Line1 ,(unsigned char *)"Function_Menu_APP  ");
	if(Mark_Sign->Task_Mark == F_ONE )
	{
		LCD_DisplayStringLine(Line2 ,(unsigned char *)"ADC         ");
		sprintf((char*)Lcd_Disp_String, "  RES38_vol: %6.3f  ",getADC1()*(3.3/4096));	
		//3.3为总的电压值 2的12次方等于4096 用于对电压值分成一份
		LCD_DisplayStringLine(Line4, Lcd_Disp_String);

	}
}

按键控制函数: 确认 返回 切换 其中keys_number用于切换功能时候,选择对应功能的时候记录用,因为up和down函数在切换的时候,需要作出循环的效果,既可以到了上限F_FOUR之后就,继续向上时,重新回到F_ONE, 也可以在到了下限F_ONE之后就,继续向下时,重新回到F_FOUR。

uint8_t keys_number;
/***************
 *  1,检测当前按下的按键为确认键
 *  2,检测当前的界面
 *     (1)如果是主界面,则进入菜单界面
 *     (2)如果是菜单界面,则进入任务界面
 *     (3)如果是任务界面,则开执行被选中的任务
***************/
void key_Inter(Mark *Mark_Sign)
{

        //当按下菜单键时,判断当前界面
        /************判断当前界面为主界面***********************/
        if(Main_Interface == Mark_Sign->Interface_Mark)
        {
            /**************进入菜单界面*************/
            Mark_Sign->Interface_Mark = Menu_Interface;
			Mark_Sign->Task_Mark = F_ONE;
			keys_number = 0;
        }
        /************判断当前界面为菜单界面*******************/
        else if(Menu_Interface == Mark_Sign->Interface_Mark)
        {
            /***************进入任务界面************/
            Mark_Sign->Interface_Mark = Task_Interface;

            /**************进入指定的功能任务*******/
            switch(Mark_Sign->Task_Mark)
            {
				//Task_Mark;          //任务状态
				//Run_Task;           //开始运行任务

            /**************开始运行time任务*******/
            case F_ONE:
                Mark_Sign->Run_Task = F_ONE;
				
                break;
            /**************开始运行蓝牙任务*******/
            case F_TWO:
                Mark_Sign->Run_Task = F_TWO;

                break;
            /**************开始运行F_THREE任务*******/
            case F_THREE:
                Mark_Sign->Run_Task = F_THREE;

                break;
            /**************开始运行设置任务*******/
            case F_FOUR:
                Mark_Sign->Run_Task = F_FOUR;
                break;
            default:
                break;
		    }
        }
        /************判断当前界面为任务界面******************/
        else if(Task_Interface == Mark_Sign->Interface_Mark)
        {
            /*******判断当前正在运行的任务*******/
            switch(Mark_Sign->Run_Task)
            {
				//Task_Mark;          //任务状态
				//Run_Task;           //开始运行任务

            /**************开始运行time任务*******/
            case F_ONE:
				
                break;
            /**************开始运行蓝牙任务*******/
            case F_TWO:
            
                break;
            /**************开始运行F_THREE任务*******/
            case F_THREE:

                break;
            /**************开始运行设置任务*******/
            case F_FOUR:
       
                break;
            default:
                break;
            }
        }
}
/*显示推出的时候箭头和向上移动的时候的箭头*/
void Menu_cancel(uint8_t keys_number,Mark *Mark_Sign);
void Menu_input(uint8_t keys_number,Mark *Mark_Sign);
/***************
//返回键,可以返回上一界面,如果在菜单界面
返回的时候指针在指向上次的位置
 * 1,检测当前按下的按键为返回键
 * 2,检测当前的界面
 *    (1)如果是任务界面,则停止正在运行的任务,返回到菜单界面
 *    (2)如果是菜单界面,则返回到主界面
***************/
void key_Cancel(Mark *Mark_Sign)
{

        //当按下返回键时,判断当前界面
        /************判断当前界面为菜单界面*******************/
        if(Menu_Interface == Mark_Sign->Interface_Mark)
        {
            /*******退出菜单界面***进入主界面**/
            Mark_Sign->Interface_Mark = Main_Interface;

        }
        /************判断当前界面为任务界面******************/
        else if(Task_Interface == Mark_Sign->Interface_Mark)
        {
            /***退出正在运行的任务***/
//            Mark_Sign->Run_Task = Stop;
            /*******退出任务界面*****/
            Mark_Sign->Interface_Mark = Menu_Interface;
			Mark_Sign->Run_Task = Stopping;
			Menu_cancel(keys_number,Mark_Sign);
        }
}
/***************
//菜单界面,可以上下选择进入那些功能之中
、、任务界面中
time功能中,可以上下更改对应的时间与日期的值
***************/
void key_Up_move(Mark *Mark_Sign)
{
	

	if(Mark_Sign->Interface_Mark==Menu_Interface)
	{
		if(keys_number==0) keys_number = 4;
		keys_number--;
		Menu_cancel(keys_number,Mark_Sign);
	}
	else if(Mark_Sign->Run_Task == F_ONE)
	{
		
	}
}


/***************
//菜单界面,可以上下选择进入那些功能之中
//任务界面中
//time功能中,可以上下更改对应的时间与日期的值
***************/
void key_Down_move(Mark *Mark_Sign)
{
	
	if(Mark_Sign->Interface_Mark==Menu_Interface)
	{
		if(keys_number==4) keys_number=0;
		keys_number++;
		Menu_input(keys_number,Mark_Sign);
	}
	else if(Mark_Sign->Run_Task == F_ONE)
	{
		
	}
}

切换时的效果: 不管是LCD 还是OLED在切换界面的时候,如果不及时清理的话,都会保留上一次的印记,因此在任务变更,界面改变的时候都要及时清理。

==而且可以在任务界面的时候可以写一个光标来表示,即将运行的任务是什么。==这样便于观看。

/*显示推出的时候箭头和向上移动的时候的箭头*/
void Menu_cancel(uint8_t keys_number,Mark *Mark_Sign)
{
		if(keys_number==3)
		{
			Mark_Sign->Task_Mark = F_FOUR;
			LCD_DisplayStringLine(Line2 ,(unsigned char *)"TEST       ");

		}
		else if(keys_number==2)
		{
			Mark_Sign->Task_Mark = F_THREE;
			LCD_DisplayStringLine(Line2 ,(unsigned char *)"FRE        ");
		}
		else if(keys_number==1)
		{
			Mark_Sign->Task_Mark = F_TWO;
			LCD_DisplayStringLine(Line2 ,(unsigned char *)"LED        ");
		}
		else if(keys_number<=0)
		{
			Mark_Sign->Task_Mark = F_ONE;
			LCD_DisplayStringLine(Line2 ,(unsigned char *)"ADC        ");
			keys_number=0;
		}
}

/*前进移动的时候的箭头*/
void Menu_input(uint8_t keys_number,Mark *Mark_Sign)
{
		if(keys_number==1)
		{
			Mark_Sign->Task_Mark = F_TWO;
			LCD_DisplayStringLine(Line2 ,(unsigned char *)"LED        ");
		}
		else if(keys_number==2)
		{
			Mark_Sign->Task_Mark = F_THREE;
			LCD_DisplayStringLine(Line2 ,(unsigned char *)"FRE        ");
		}
		else if(keys_number==3)
		{
			Mark_Sign->Task_Mark = F_FOUR;
			LCD_DisplayStringLine(Line2 ,(unsigned char *)"AAA        ");
		}
		else if(keys_number>=4)
		{
			Mark_Sign->Task_Mark = F_ONE; 
			LCD_DisplayStringLine(Line2 ,(unsigned char *)"ADC        ");
		}
}

3-3主函数调用设计

主函数调用:
在主函数先定义一个结构体Mark Mark_Sign = {Main_Interface,0,0};来表示初始界面为主界面。之后调用gui_init函数来显示初始界面。

在while循环中不断读取按键值和显示界面函数来实现显示界面的动态更新。

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "usart.h"
#include "gpio.h"
#include "lcd.h"
#include "stdio.h"
#include "gui.h"

/* Private define ------------------------------------------------------------*/
Mark Mark_Sign = {Main_Interface,0,0};

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
unsigned char Lcd_Disp_String[21];
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* Configure the system clock */
  HAL_Init();
  SystemClock_Config();
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  MX_ADC1_Init();
  MX_ADC2_Init();
  /* USER CODE BEGIN 2 */
	LCD_Init();
	LCD_Clear(White);
	LCD_SetBackColor(White);
	LCD_SetTextColor(Black);
	LCD_Clear(White);
	LCD_DisplayStringLine(Line1 ,(unsigned char *)"   hello	dma.   ");
	
	GUI_init();/

  /* USER CODE END 2 */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	Interface_APP(&Mark_Sign);
	Interface(&Mark_Sign, KEY_Scan(0));
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

四、总结

这是一个用结构体写的一个基础多级界面的框架,如果你使用的界面大于或是小时3级的话,这时候就需要对结构的中的界面枚举变量进行更改。根据整个设计你所喜欢的界面叭。总体来说来时不错的

本文的工程文件我将上次传到百度网盘。链接: https://pan.baidu.com/s/1QNpKRsyHVr-UyCGsyvkLBw .
提取码:vsh2
在这里插入图片描述

此文本工程参考了链接: 基于STM32之OLED菜单界面框架搭建,特此感谢。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【STM32多级界面】-LCD结构体多级图形界面框架 的相关文章

  • mysql学习——修改用户名

    通过命令行修改数据库用户名和密码 修改用户名 mysql span class token operator span u root span class token operator span p Enter password xff1a
  • python面向对象——类成员与初始化方法

    类成员 类的成员主要由实例方法和数据成员组成 在类中创建了类的成员后 xff0c 可以通过类的实例进行访问 实例方法 是指在类中定义的函数 该函数是一种在类的实例上操作的函数 语法 class 类名 类的说明信息 def 方法名 self
  • Python GUI之tkinter库教程

    tkinter的简介 tkinter 是 Python 的标准 GUI 库 它基于 Tk 工具包 xff0c 该工具包最初是为工具命令语言 xff08 Tool Command Language xff0c Tcl xff09 设计的 Tk
  • falsk练习小项目——利用mysql实现登录+注册

    本文主要记录利用python的Flask框架和Mysql数据库实现登录 43 注册功能 xff0c 创建项目文件 templates文件夹主要放网页文件 static文件夹下主要放静态文件比如 css js 图片等等 xff1b 因为在fl
  • 大数据可视化学习总结

    自大一下学期听说的大数据 xff0c 也是那个时候才了解大数据这个专业 xff0c 自己并不喜欢这个专业 xff0c 一方面是因为学历的原因 xff0c 一方面自己对这个确实没什么兴趣 xff0c 当时一心都扑在了Java方向 先说好的一方
  • Python1+X(中级)证书培训笔记(上)

    最近参加了一个Python1 43 X的证书培训 xff0c 然后以下是整理的学习笔记 xff0c 证书涵盖的知识点有三大块 分别是数据库操作 WEB开发 网络爬虫分析下面将详细分别讲解 阅读必看 本博客没有安装的讲解 xff0c 更多是如
  • 初识Python自动化运维(一)

    系统模块 系统模块主要是使用psutil库 xff0c 后面会主要写这个介绍一下 psutil 是一个跨平台库 xff0c 能够轻松实现获取系统运行的进程和系统利用率 xff08 包括cpu 磁盘 网络等信息 xff09 常用psutil监
  • 二叉树先中后序遍历(递归非递归)

    先序遍历 先序遍历也叫先根遍历 xff0c 采用先访问根节点 xff0c 再访问左节点 xff0c 最后访问右节点 递归实现 span class token comment Definition for a binary tree nod
  • 数据结构与算法二 ---链表

    前言 这一节是链表 xff0c 这是为了填坑 xff0c 自己说过的话 xff0c 一定要做到 什么是链表 相比上一章的数组 xff0c 链表是一种稍微麻烦亿丢丢的数据结构 如图 xff1a 数组需要一块连续的存储空间 xff0c 对内存要
  • 如何在Linux中的命令行中列出和启动VirtualBox VM?

    VirtualBox is a nice open source virtual machine software It works nicely on Linux and is supported by many Linux distro
  • 数据结构与算法---(最小栈)

    最小栈 题目需求 xff1a 实现一个这样的栈 xff0c 这个栈除了可以进行普通的push pop操作以外 xff0c 还可以进行getMin的操作 xff0c getMin方法被调用后 xff0c 会返回当前栈的最小值 栈里面存放的都是
  • JAVA集合三大类

    JAVA集合三大类 xff1a 1 set set集合无法记住添加的顺序 xff0c 因此set集合中的元素不能重复 2 list xff1a 与数组类似 xff0c list集合可以记住每次添加元素的顺序 xff0c 因此可以根据元素的索
  • 计算机网络词汇解释(二)——交互、 点到点、端到端

    计算机网络词汇解释 xff08 二 xff09 交互 点到点 端到端 本篇文章试图以 xff1a 是什么 xff1f 为什么 xff1f 怎么样 xff1f 三个层次来解释词汇 xff0c 并尽量实现通信的哲学 你传达的复杂信息 xff0c
  • java 字符串 提取 或 去除字母字符串

    提取 linStr span class token operator 61 span linStr span class token punctuation span span class token function replaceAl
  • 数字图像处理---自适应中值滤波实验(MATLAB实现含源码)

    自适应中值滤波实验 xff08 MATLAB实现 xff09 实验目的 1 掌握中值滤波以及自适应中值滤波器的原理以及滤波过程 2 掌握自适应中值滤波的算法设计 3 进一步熟悉MATLAB编程 实验原理 中值滤波的思想就是比较一定领域内的像
  • SpringBoot拦截器执行后,Controller层不执行

    问题描述 xff1a 请求在SpringBoot拦截器中执行后 xff0c 在Controller层不执行 xff0c 前端错误码400 原因分析 xff1a ServletRequest 中通过流获取参数 xff08 getInputSt
  • 一位工作了10年的C++程序员总结出这些忠告

    1 可以考虑先学习C 大多数时候 xff0c 我们学习语言的目的 xff0c 不是为了成为一个语言专家 xff0c 而是希望成为一个解决问题的专家 做一个有用的程序员 xff0c 做一个赚钱的程序员 我们的价值 xff0c 将体现在客户价值
  • 1.6配置通过ftp进行文件操作

    ftp是文件传输的internet标准 xff0c 主要功能是向用户提供本地和远程主机之间的文件传输 版本升级 日志下载 使用c s结构 实验内容 xff1a 模拟企业网络 xff0c pc1访问ftp server 做上传下载操作 出于安
  • 数据库原理及应用复习资料

    单选 xff08 无解析 xff09 xff08 A xff09 是对数据库中全部数据的逻辑结构和特征的描述 A 模式 B 外模式 C 内模式 D 视图 xff08 B xff09 是对数据库用户能够看见和使用的局部数据的逻辑结构和特征的描
  • ae 渲染选项_好的MPlayer选项,以提高视频渲染质量

    ae 渲染选项 MPlayer has lots options for video rendering and filtering Any suggestions on good MPlayer options that improve

随机推荐

  • Nuxt.js 概述 安装 目录结构说明

    什么是SEO SEO xff1a 搜索引擎优化 xff08 Search Engine Optimization xff09 通过各种技术 xff08 手段 xff09 来确保 xff0c 我们的Web内容被搜索引擎最大化收录 xff0c
  • Nuxt.js路由

    路由 路由概述 Nuxt js 依据 pages 目录结构自动生成 vue router 模块的路由配置 要在页面之间切换路由 xff0c 我们建议使用 nuxt link 标签 基础路由 自动生成基础路由规则 情况1 xff1a 访问路径
  • Nuxt.js 视图

    视图 默认模板 定制化默认的 html 模板 xff0c 只需要在应用根目录下创建一个 app html 的文件 默认模板 xff1a span class token doctype span class token punctuatio
  • Nuxt.js整合axios

    整合 axios 默认整合 在构建项目时 xff0c 如果选择axios组件 xff0c nuxt js将自动与axios进行整合 手动整合 步骤1 xff1a package json有axios的版本 34 dependencies 3
  • Vuex 状态树

    根模块数据操作 步骤一 xff1a 创建 store index js 添加一个 counter变量 xff0c 并可以继续累加操作 export const state 61 61 gt counter 0 export const mu
  • Nuxt.js查询学生列表案例

    查询所有的班级 xff1a 后端 父工程pom文件 lt xml version 61 34 1 0 34 encoding 61 34 UTF 8 34 gt lt project xmlns 61 34 http maven apach
  • 大数据面试题

    Hive理论知识汇总 1 Hive和数据库比较 Hive 和数据库除了拥有类似的查询语言 xff0c 再无类似之处 1 xff09 数据存储位置 Hive 存储在 HDFS 数据库将数据保存在块设备或者本地文件系统中 2 xff09 数据更
  • MyBatis Plus

    概述 简介 MyBatis Plus xff08 简称 MP xff09 是一个 MyBatis 的增强工具 xff0c 在 MyBatis 的基础上只做增强不做改变 xff0c 为简化开发 提高效率而生 特点 无侵入 xff1a 只做增强
  • MybatisPlus--QueryWrapper

    QueryWrapper wrapper介绍 Wrapper xff1a 条件构造抽象类 xff0c 最顶端父类 AbstractWrapper xff1a 用于查询条件封装 xff0c 生成 sql 的 where 条件 QueryWra
  • 大数据导论题库

    选择题 1 下面哪个程序负责 HDFS数据存储 C A NameNode B Jobtracker C Datanode D secondaryNameNode 2 HDfS 中的 block 默认保存几份 A A 3份 B 2 份 C 1
  • Oracle Linux7.8 下离线 一键静默安装Oracle12c

    目录 安装前的准备最小安装OracleLinux7 8 xff08 centos7 8一样 xff09 安装oracle需要的依赖包 准备Oracle安装包准备一键安装脚本 并执行脚本使用安装前配置 问题及解决方法 xff1a 错误码ORA
  • MybatisPlus-插件机制-乐观锁-逻辑删除-通用service

    插件机制 自动填充 项目中经常会遇到一些数据 xff0c 每次都使用相同的方式填充 xff0c 例如记录的创建时间 xff0c 更新时间等 我们可以使用MyBatis Plus的自动填充功能 xff0c 完成这些字段的赋值工作 原理 实现元
  • 畅购商城项目--(用户模块+用户注册【用户名占用】)

    搭建环境 4 1 1 后端web服务 xff1a changgou4 service web 修改pom xml文档 lt xml version 61 34 1 0 34 encoding 61 34 UTF 8 34 gt lt pro
  • Mysql对于列中存储键值对数据的查询

    对于键值对数据的查询 为了方便查看 xff0c 将其称之为A表 A表 xff1a 可以看到A表中的列有 id inquiry id data key data value date key列中的各个字段对应的data value中的各个数据
  • PathVariable注解的用法以及报错

    今天碰见个很奇怪的问题 xff0c 因为之前在学校没怎么用过 64 PathVariable这个注解 xff0c 但是postman测试时并没有请求到 xff0c 具体如下 接口就是一个简单的查询详情 xff0c 而当我请求postman的
  • 关于@PreAuthorize注解的使用场景

    作用 64 PreAuthorize 能够在执行方法之前进行权限的认证 xff0c 支持Spring EL表达式 xff0c 基于方法注解和权限解决方案 xff0c 并且只有当 64 EnableGlobalMethodSecurity p
  • 获取 当前时间的前五天凌晨0点的时间

    公司今天提到的需求是 xff1a 每日凌晨两点 xff0c 调用方法 xff0c 方法的内容是 xff1a 拉取当前时间的前五天的0点的消息聊天记录 在网上查了好久才找到 xff0c 现在奉上代码 xff1a span class toke
  • 查询 按照 指定时间的前一天的数据

    需求 xff1a 查询按照指定时间的前一天的数据 xff0c 举个例子 xff1a 传入2023 2 27 xff0c 需要获取到2023 2 26 的数据 xff0c 如果这一天没有数据 xff0c 那就需要往前找 xff0c 直到找不到
  • 关于limit的使用场景

    什么情况下使用 limit 1呢 xff1f 当我们写sql语句的时候需要进行全表扫描 xff0c 前提我们已经确认返回的结果只有一条数据的时候 xff0c 使用limit 1 xff0c 因为使用limit 1 之后 xff0c 在查询过
  • 【STM32多级界面】-LCD结构体多级图形界面框架

    STM32多级界面搭建 在实际的项目之中 xff0c 需要用单片机在LCD OLED中搭建一个3级的图形界面 本文的工程文件我将上次传到百度网盘 xff0c 链接在最后的部分 STM32多级界面搭建一 方案选择二 实现效果三 程序设计3 1