SOC-ESP32S3部分:31-ESP-LCD控制器库

news2025/6/8 0:20:48

飞书文档https://x509p6c8to.feishu.cn/wiki/Syy3wsqHLiIiQJkC6PucEJ7Snib

ESP 系列芯片可以支持市场上常见的 LCD(如 SPI LCD、I2C LCD、并行 LCD (Intel 8080)、RGB/SRGB LCD、MIPI DSI LCD 等)所需的各种时序。esp_lcd 控制器为上述各类 LCD 提供了一个统一的抽象驱动框架。

更多支持的接口例程可以查看:esp-idf/examples/peripherals/lcd

在开发LCD类应用时,我们可以优先选择IDF自带了部分驱动,例如NT35510 SSD1306 ST7789,这部分驱动位于esp-idf/components/esp_lcd中,或者,我们也可以在组件库中查找,例如gc9a01

https://components.espressif.com/components?q=esp_lcd_gc9a01

这些驱动都是适配了esp_lcd控制器的,使用起来非常方便。

如果以上两个方法都找不到对应驱动呢?这时候就需要我们自己写了,有两种办法,

第一种是比较传统的,是把厂家提供的驱动文件,修改为ESP32的接口,例如SPI、IO相关的函数,这部分可以参考我们SPI课程中,使用SPI适配的ST7789屏幕驱动。

第二种是推荐大家用的,把驱动按esp_lcd框架的方式封装,找接近的芯片,更改部分参数即可,例如找不到ST7789的,我们可以找ST77916的,一般同一个厂家一系列的芯片,差异点只在初始化参数的不同。

https://components.espressif.com/components?q=esp_lcd_st

最终参考esp-idf/examples/peripherals/lcd/spi_lcd_touch实现的驱动:

步骤如下

  1. 初始化背光IO
  2. 初始化LCD的SPI配置
  3. 初始化其它显示IO
  4. 初始化ST7789驱动
  5. 设置屏幕显示方向颜色,打开背光
  6. 使用绘制函数绘制图像esp_lcd_panel_draw_bitmap

初始化背光IO

   gpio_config_t bk_gpio_config = {
       .mode = GPIO_MODE_OUTPUT, // 设置GPIO模式为输出
       .pin_bit_mask = 1ULL << EXAMPLE_PIN_NUM_BK_LIGHT // 设置背光控制引脚
   };
   ESP_ERROR_CHECK(gpio_config(&bk_gpio_config)); // 配置GPIO

初始化LCD的SPI配置

   spi_bus_config_t buscfg = {
       .sclk_io_num = EXAMPLE_PIN_NUM_SCLK, // SCLK引脚编号
       .mosi_io_num = EXAMPLE_PIN_NUM_MOSI, // MOSI引脚编号
       .miso_io_num = GPIO_NUM_NC,          // MISO引脚编号
       .quadwp_io_num = GPIO_NUM_NC,        // QUADWP引脚编号(未使用)
       .quadhd_io_num = GPIO_NUM_NC,        // QUADHD引脚编号(未使用)
       .max_transfer_sz = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES * sizeof(uint16_t), // 最大传输大小
   };
   ESP_ERROR_CHECK(spi_bus_initialize(LCD_HOST, &buscfg, SPI_DMA_CH_AUTO)); // 初始化SPI总线

初始化其它显示IO

   ESP_LOGI(TAG, "Install panel IO");
   esp_lcd_panel_io_handle_t io_handle = NULL;
   esp_lcd_panel_io_spi_config_t io_config = {
       .dc_gpio_num = EXAMPLE_PIN_NUM_LCD_DC, // 数据/命令控制引脚编号
       .cs_gpio_num = EXAMPLE_PIN_NUM_LCD_CS, // 片选引脚编号
       .pclk_hz = EXAMPLE_LCD_PIXEL_CLOCK_HZ, // 像素时钟频率
       .lcd_cmd_bits = EXAMPLE_LCD_CMD_BITS, // 命令位数
       .lcd_param_bits = EXAMPLE_LCD_PARAM_BITS, // 参数位数
       .spi_mode = 3, // SPI模式
       .trans_queue_depth = 10, // 传输队列深度
   };
   // 将LCD连接到SPI总线
   ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)LCD_HOST, &io_config, &io_handle));

初始化ST7789驱动

   // 安装st7789面板驱动
   esp_lcd_panel_handle_t panel_handle = NULL;
   esp_lcd_panel_dev_config_t panel_config = {
       .reset_gpio_num = EXAMPLE_PIN_NUM_LCD_RST,  // 复位引脚编号
       .rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB, // RGB元素顺序
       .bits_per_pixel = 16,                       // 每像素位数
       .data_endian = LCD_RGB_DATA_ENDIAN_BIG,     // MSB
   };
   ESP_LOGI(TAG, "Install st7789 panel driver");
   ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle));

设置屏幕显示方向颜色,打开背光

   // 复位和初始化面板
   ESP_ERROR_CHECK(esp_lcd_panel_reset(panel_handle)); // 复位面板
   ESP_ERROR_CHECK(esp_lcd_panel_init(panel_handle)); // 初始化面板
   ESP_ERROR_CHECK(esp_lcd_panel_invert_color(panel_handle, true)); // 反转颜色
   ESP_ERROR_CHECK(esp_lcd_panel_mirror(panel_handle, true, false)); // 镜像显示(水平镜像)

   // 用户可以在点亮屏幕或背光之前刷新预定义的图案到屏幕上
   ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_handle, true)); // 打开屏幕显示
  
   // 打开LCD背光
   ESP_LOGI(TAG, "Turn on LCD backlight");
   gpio_set_level(EXAMPLE_PIN_NUM_BK_LIGHT, EXAMPLE_LCD_BK_LIGHT_ON_LEVEL); // 设置背光引脚电平

使用绘制函数绘制图像esp_lcd_panel_draw_bitmap

// 设置液晶屏颜色
void lcd_set_color(uint16_t color)
{
   // 分配内存 这里分配了液晶屏一行数据需要的大小
    uint16_t *buffer = (uint16_t *)heap_caps_malloc(EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES * sizeof(uint16_t), MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);

    if (NULL == buffer)
    {
        ESP_LOGE(TAG, "Memory for bitmap is not enough");
    }
    else
    {
        for (size_t i = 0; i < EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES; i++) // 给缓存中放入颜色数据
        {
            buffer[i] = color;
        }
        esp_lcd_panel_draw_bitmap(panel_handle, 0 + X_OFFSET, 0, EXAMPLE_LCD_H_RES + X_OFFSET, EXAMPLE_LCD_V_RES, buffer);
        free(buffer); // 释放内存
    }
}

SPI屏幕

SPI屏幕使用的驱动芯片是ST7789,这个驱动芯片支持的分辨率是240*320,据厂家手册说明可知,由于是异形屏幕,屏幕的分辨率是172*320,所以驱动芯片左右两边分别有34列((240-172)/2) = 34是没有接到屏幕的,所以我们设置显示地址是,要偏移34列,屏幕接线部分如下:

从原理图可知:

SPI SCLK为GPIO_NUM_16
SPI MOSI为GPIO_NUM_17
SPI MISO不需要
LCD_DC为GPIO_NUM_21
LCD_RST为GPIO_NUM_18
LCD_CS为GPIO_NUM_15
背光IO为GPIO_NUM_2,背光有效电平为低电平

具体代码如下

#include <stdio.h>
#include <unistd.h>
#include <sys/lock.h>
#include <sys/param.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_lcd_panel_io.h"
#include "esp_lcd_panel_vendor.h"
#include "esp_lcd_panel_ops.h"
#include "driver/gpio.h"
#include "driver/spi_master.h"
#include "esp_err.h"
#include "esp_log.h"

static const char *TAG = "example";

// Using SPI2 in the example
#define LCD_HOST  SPI2_HOST


 Please update the following configuration according to your LCD spec //

#define EXAMPLE_LCD_PIXEL_CLOCK_HZ     (20 * 1000 * 1000)
#define EXAMPLE_LCD_BK_LIGHT_ON_LEVEL  0
#define EXAMPLE_LCD_BK_LIGHT_OFF_LEVEL !EXAMPLE_LCD_BK_LIGHT_ON_LEVEL

#define EXAMPLE_PIN_NUM_SCLK           GPIO_NUM_16
#define EXAMPLE_PIN_NUM_MOSI           GPIO_NUM_17
#define EXAMPLE_PIN_NUM_MISO           GPIO_NUM_NC
#define EXAMPLE_PIN_NUM_LCD_DC         GPIO_NUM_21
#define EXAMPLE_PIN_NUM_LCD_RST        GPIO_NUM_18
#define EXAMPLE_PIN_NUM_LCD_CS         GPIO_NUM_15
#define EXAMPLE_PIN_NUM_BK_LIGHT       GPIO_NUM_2

// The pixel number in horizontal and vertical
#define EXAMPLE_LCD_H_RES              172
// Bit number used to represent command and parameter
#define EXAMPLE_LCD_V_RES              320
#define EXAMPLE_LCD_CMD_BITS           8
#define EXAMPLE_LCD_PARAM_BITS         8

// 列地址偏移示例(假设X起始偏移为0,Y起始偏移为40)
#define X_OFFSET 34
#define Y_OFFSET 0
#define Y_OFFSET_NUM 0

esp_lcd_panel_handle_t panel_handle = NULL;

typedef struct {
    int cmd;                /*<! The specific LCD command */
    const void *data;       /*<! Buffer that holds the command specific data */
    size_t data_bytes;      /*<! Size of `data` in memory, in bytes */
    unsigned int delay_ms;  /*<! Delay in milliseconds after this command */
} st7789_lcd_init_cmd_t;

typedef struct {
    const st7789_lcd_init_cmd_t *init_cmds;   
    uint16_t init_cmds_size;    /*<! Number of commands in above array */
    struct {
        unsigned int use_qspi_interface: 1;     /*<! Set to 1 if use QSPI interface, default is SPI interface */
    } flags;
} st7789_vendor_config_t;

static const st7789_lcd_init_cmd_t lcd_init_cmds [] ={
    /* {cmd, { data }, data_size, delay_ms} "*/
    // {0x2A, (uint8_t []){0x00, X_OFFSET, 0x00, 0xEF - X_OFFSET}, 4, 0}, // 列地址 0~171 (0xAB = 171)
    // {0x2B, (uint8_t []){0x00, Y_OFFSET, 0x01, 0x3F - Y_OFFSET}, 4, 0}, // 行地址 0~319
    {0x11, (uint8_t []){0x00}, 0, 0},
    {0x36, (uint8_t []){0x00}, 1, 0},
    {0x3A, (uint8_t []){0x05}, 1, 0},
    {0xB2, (uint8_t []){0x0C, 0x0C, 0x00, 0x33, 0x33}, 5, 0},
    {0xB7, (uint8_t []){0x35}, 1, 0},
    {0xBB, (uint8_t []){0x35}, 1, 0},
    {0xC0, (uint8_t []){0x2C}, 1, 0},
    {0xC2, (uint8_t []){0x01}, 1, 0},
    {0xC3, (uint8_t []){0x13}, 1, 0},
    {0xC4, (uint8_t []){0x20}, 1, 0},
    {0xC6, (uint8_t []){0x0F}, 1, 0},
    {0xD0, (uint8_t []){0xA4, 0xA1}, 2, 0},
    {0xD6, (uint8_t []){0xA1}, 1, 0},
    {0xE0, (uint8_t []){0xF0, 0x00, 0x04, 0x04, 0x04, 0x05, 0x29, 0x33, 0x3e, 0x38, 0x12, 0x12, 0x28, 0x30}, 14, 0},
    {0xE1, (uint8_t []){0xF0, 0x07, 0x0A, 0x0D, 0x0b, 0x07, 0x28, 0x33, 0x3e, 0x36, 0x14, 0x14, 0x29, 0x32}, 14, 0},
    {0x21, (uint8_t []){0x00}, 0, 0},
    {0x11, (uint8_t []){0x00}, 0, 120},
    {0x29, (uint8_t []){0x00}, 0, 0},
};

// 设置液晶屏颜色
void lcd_set_color(uint16_t color)
{
   // 分配内存 这里分配了液晶屏一行数据需要的大小
    uint16_t *buffer = (uint16_t *)heap_caps_malloc(EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES * sizeof(uint16_t), MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL);

    if (NULL == buffer)
    {
        ESP_LOGE(TAG, "Memory for bitmap is not enough");
    }
    else
    {
        for (size_t i = 0; i < EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES; i++) // 给缓存中放入颜色数据
        {
            buffer[i] = color;
        }
        esp_lcd_panel_draw_bitmap(panel_handle, 0 + X_OFFSET, 0, EXAMPLE_LCD_H_RES + X_OFFSET, EXAMPLE_LCD_V_RES, buffer);
        free(buffer); // 释放内存
    }
}

void app_main(void)
{

   // 关闭LCD背光
   ESP_LOGI(TAG, "Turn off LCD backlight");
   gpio_config_t bk_gpio_config = {
       .mode = GPIO_MODE_OUTPUT, // 设置GPIO模式为输出
       .pin_bit_mask = 1ULL << EXAMPLE_PIN_NUM_BK_LIGHT // 设置背光控制引脚
   };
   ESP_ERROR_CHECK(gpio_config(&bk_gpio_config)); // 配置GPIO

   // 初始化SPI总线
   ESP_LOGI(TAG, "Initialize SPI bus");
   spi_bus_config_t buscfg = {
       .sclk_io_num = EXAMPLE_PIN_NUM_SCLK, // SCLK引脚编号
       .mosi_io_num = EXAMPLE_PIN_NUM_MOSI, // MOSI引脚编号
       .miso_io_num = GPIO_NUM_NC,          // MISO引脚编号
       .quadwp_io_num = GPIO_NUM_NC,        // QUADWP引脚编号(未使用)
       .quadhd_io_num = GPIO_NUM_NC,        // QUADHD引脚编号(未使用)
       .max_transfer_sz = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES * sizeof(uint16_t), // 最大传输大小
   };
   ESP_ERROR_CHECK(spi_bus_initialize(LCD_HOST, &buscfg, SPI_DMA_CH_AUTO)); // 初始化SPI总线

   // 安装面板IO
   ESP_LOGI(TAG, "Install panel IO");
   esp_lcd_panel_io_handle_t io_handle = NULL;
   esp_lcd_panel_io_spi_config_t io_config = {
       .dc_gpio_num = EXAMPLE_PIN_NUM_LCD_DC, // 数据/命令控制引脚编号
       .cs_gpio_num = EXAMPLE_PIN_NUM_LCD_CS, // 片选引脚编号
       .pclk_hz = EXAMPLE_LCD_PIXEL_CLOCK_HZ, // 像素时钟频率
       .lcd_cmd_bits = EXAMPLE_LCD_CMD_BITS, // 命令位数
       .lcd_param_bits = EXAMPLE_LCD_PARAM_BITS, // 参数位数
       .spi_mode = 3, // SPI模式
       .trans_queue_depth = 10, // 传输队列深度
   };
   // 将LCD连接到SPI总线
   ESP_ERROR_CHECK(esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)LCD_HOST, &io_config, &io_handle));

   st7789_vendor_config_t vendor_config = {  // 用于替换驱动组件中的初始化命令及参数
    .init_cmds = lcd_init_cmds,
    .init_cmds_size = sizeof(lcd_init_cmds) / sizeof(st7789_lcd_init_cmd_t),
    };

   esp_lcd_panel_dev_config_t panel_config = {
       .reset_gpio_num = EXAMPLE_PIN_NUM_LCD_RST,  // 复位引脚编号
       .rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB, // RGB元素顺序
       .bits_per_pixel = 16,                       // 每像素位数
       .data_endian = LCD_RGB_DATA_ENDIAN_BIG,     // MSB
       .vendor_config = &vendor_config,           // 用于替换驱动组件中的初始化命令及参数
   };
   ESP_LOGI(TAG, "Install ST7789 panel driver");
   ESP_ERROR_CHECK(esp_lcd_new_panel_st7789(io_handle, &panel_config, &panel_handle));
   // 复位和初始化面板
   ESP_ERROR_CHECK(esp_lcd_panel_reset(panel_handle)); // 复位面板
   ESP_ERROR_CHECK(esp_lcd_panel_init(panel_handle)); // 初始化面板
   ESP_ERROR_CHECK(esp_lcd_panel_invert_color(panel_handle, true)); // 反转颜色
   ESP_ERROR_CHECK(esp_lcd_panel_mirror(panel_handle, false, false)); // 镜像显示(水平镜像)

   // 用户可以在点亮屏幕或背光之前刷新预定义的图案到屏幕上
   ESP_ERROR_CHECK(esp_lcd_panel_disp_on_off(panel_handle, true)); // 打开屏幕显示

   // 打开LCD背光
   ESP_LOGI(TAG, "Turn on LCD backlight");
   gpio_set_level(EXAMPLE_PIN_NUM_BK_LIGHT, EXAMPLE_LCD_BK_LIGHT_ON_LEVEL); // 设置背光引脚电平

   while(1){
    lcd_set_color(0xFFFF);
    vTaskDelay(1000 / portTICK_PERIOD_MS);
    ESP_LOGI(TAG, "lcd_set_color switch");
    lcd_set_color(0x001F);
    vTaskDelay(1000 / portTICK_PERIOD_MS);
    ESP_LOGI(TAG, "lcd_set_color switch");
   }
}

如果编译报错fatal error: esp_lcd_panel_io.h: No such file or directory

需要在main/CMakeLists.txt中添加esp_lcd组件

idf_component_register(SRCS "main.c"
                    PRIV_REQUIRES esp_lcd
                    INCLUDE_DIRS "")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2403513.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【云安全】以Aliyun为例聊云厂商服务常见利用手段

目录 OSS-bucket_policy_readable OSS-object_public_access OSS-bucket_object_traversal OSS-Special Bucket Policy OSS-unrestricted_file_upload OSS-object_acl_writable ECS-SSRF 云攻防场景下对云厂商服务的利用大同小异&#xff0c;下面以阿里云为例 其他如腾…

读文献先读图:GO弦图怎么看?

GO弦图&#xff08;Gene Ontology Chord Diagram&#xff09;是一种用于展示基因功能富集结果的可视化工具&#xff0c;通过弦状连接可以更直观的展示基因与GO term&#xff08;如生物过程、分子功能等&#xff09;之间的关联。 GO弦图解读 ①内圈连线表示基因和生物过程之间的…

怎么让大语言模型(LLMs)自动生成和优化提示词:APE

怎么让大语言模型(LLMs)自动生成和优化提示词:APE https://arxiv.org/pdf/2211.01910 1. 研究目标:让机器自己学会设计提示词 问题:大语言模型(如GPT-3)很强大,但需要精心设计的“提示词”才能发挥最佳效果。过去靠人工设计提示词,费时费力,还可能因表述差异导致模…

实现单例模式的常见方式

前言 java有多种设计模式&#xff0c;如下图所示&#xff1a; 单例模式它确保一个类只有一个实例&#xff0c;并提供一个全局访问点。 1、单例模式介绍 1.1、使用原因 为什么要使用单例模式&#xff1f; 1. 控制资源访问 核心价值&#xff1a;确保对共享资源&#xff08;如…

day20 leetcode-hot100-38(二叉树3)

226. 翻转二叉树 - 力扣&#xff08;LeetCode&#xff09; 1.广度遍历 思路 这题目很简单&#xff0c;就是交换每个节点的左右子树&#xff0c;也就是相当于遍历到某个节点&#xff0c;然后交换子节点即可。 具体步骤 &#xff08;1&#xff09;创建队列&#xff0c;使用广…

OpenVINO环境配置--OpenVINO安装

TOC环境配置–OpenVINO安装 本节内容 OpenVINO 支持的安装方式有很多种&#xff0c;每一种操作系统以及语言都有对应的安装方法&#xff0c;在官网上有很详细的教程&#xff1a;   我们可以根据自己的需要&#xff0c;来点选环境配置和安装方法&#xff0c;然后网页会给出正…

黑龙江云前沿服务器租用:便捷高效的灵活之选​

服务器租用&#xff0c;即企业直接从互联网数据中心&#xff08;IDC&#xff09;提供商处租赁服务器。企业只需按照所选的服务器配置和租赁期限&#xff0c;定期支付租金&#xff0c;即可使用服务器开展业务。​ 便捷快速部署&#xff1a;租用服务器能极大地缩短服务器搭建周期…

论文解读:Locating and Editing Factual Associations in GPT(ROME)

论文发表于人工智能顶会NeurIPS(原文链接)&#xff0c;研究了GPT(Generative Pre-trained Transformer)中事实关联的存储和回忆&#xff0c;发现这些关联与局部化、可直接编辑的计算相对应。因此&#xff1a; 1、开发了一种因果干预方法&#xff0c;用于识别对模型的事实预测起…

学习设计模式《十二》——命令模式

一、基础概念 命令模式的本质是【封装请求】命令模式的关键是把请求封装成为命令对象&#xff0c;然后就可以对这个命令对象进行一系列的处理&#xff08;如&#xff1a;参数化配置、可撤销操作、宏命令、队列请求、日志请求等&#xff09;。 命令模式的定义&#xff1a;将一个…

十三、【核心功能篇】测试计划管理:组织和编排测试用例

【核心功能篇】测试计划管理&#xff1a;组织和编排测试用例 前言准备工作第一部分&#xff1a;后端实现 (Django)1. 定义 TestPlan 模型2. 生成并应用数据库迁移3. 创建 TestPlanSerializer4. 创建 TestPlanViewSet5. 注册路由6. 注册到 Django Admin 第二部分&#xff1a;前端…

手撕 K-Means

1. K-means 的原理 K-means 是一种经典的无监督学习算法&#xff0c;用于将数据集划分为 kk 个簇&#xff08;cluster&#xff09;。其核心思想是通过迭代优化&#xff0c;将数据点分配到最近的簇中心&#xff0c;并更新簇中心&#xff0c;直到簇中心不再变化或达到最大迭代次…

SmolVLA: 让机器人更懂 “看听说做” 的轻量化解决方案

&#x1f9ed; TL;DR 今天&#xff0c;我们希望向大家介绍一个新的模型: SmolVLA&#xff0c;这是一个轻量级 (450M 参数) 的开源视觉 - 语言 - 动作 (VLA) 模型&#xff0c;专为机器人领域设计&#xff0c;并且可以在消费级硬件上运行。 SmolVLAhttps://hf.co/lerobot/smolvla…

day45python打卡

知识点回顾&#xff1a; tensorboard的发展历史和原理tensorboard的常见操作tensorboard在cifar上的实战&#xff1a;MLP和CNN模型 效果展示如下&#xff0c;很适合拿去组会汇报撑页数&#xff1a; 作业&#xff1a;对resnet18在cifar10上采用微调策略下&#xff0c;用tensorbo…

AIGC赋能前端开发

一、引言&#xff1a;AIGC对前端开发的影响 1. AIGC与前端开发的关系 从“写代码”到“生成代码”传统开发痛点&#xff1a;重复性编码工作、UI 设计稿还原、问题定位与调试...核心场景的AI化&#xff1a;需求转代码&#xff08;P2C&#xff09;、设计稿转代码&#xff08;D2…

Web 3D协作平台开发案例:构建制造业远程设计与可视化协作

HOOPS Communicator为开发者提供了丰富的定制化能力&#xff0c;助力他们在实现强大 Web 3D 可视化功能的同时&#xff0c;灵活构建符合特定业务需求的工程应用。对于希望构建在线协同设计工具的企业而言&#xff0c;如何在保障性能与用户体验的前提下实现高效开发&#xff0c;…

AI Agent开发第78课-大模型结合Flink构建政务类长公文、长文件、OA应用Agent

开篇 AI Agent2025确定是进入了爆发期,到处都在冒出各种各样的实用AI Agent。很多人、组织都投身于开发AI Agent。 但是从3月份开始业界开始出现了一种这样的声音: AI开发入门并不难,一旦开发完后没法用! 经历过至少一个AI Agent从开发到上线的小伙伴们其实都听到过这种…

第三方测试机构进行科技成果鉴定测试有什么价值

在当今科技创新的浪潮中&#xff0c;科技成果的鉴定测试至关重要&#xff0c;而第三方测试机构凭借其独特优势&#xff0c;在这一领域发挥着不可替代的作用。那么&#xff0c;第三方测试机构进行科技成果鉴定测试究竟有什么价值呢&#xff1f; 一、第三方测试机构能提供独立、公…

华为云Flexus+DeepSeek征文|基于华为云Flexus X和DeepSeek-R1打造个人知识库问答系统

目录 前言 1 快速部署&#xff1a;一键搭建Dify平台 1.1 部署流程详解 1.2 初始配置与登录 2 构建专属知识库 2.1 进入知识库模块并创建新库 2.2 选择数据源导入内容 2.3 上传并识别多种文档格式 2.4 文本处理与索引构建 2.5 保存并完成知识库创建 3接入ModelArts S…

【数据结构】_排序

【本节目标】 排序的概念及其运用常见排序算法的实现排序算法复杂度及稳定性分析 1.排序的概念及其运用 1.1排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 1.2特性…

PPT转图片拼贴工具 v4.3

软件介绍 这个软件就是将PPT文件转换为图片并且拼接起来。 效果展示 支持导入文件和支持导入文件夹&#xff0c;也支持手动输入文件/文件夹路径 软件界面 这一次提供了源码和开箱即用版本&#xff0c;exe就是直接用就可以了。 软件源码 import os import re import sys …