使用模拟SPI接口驱动串行接口的LCD( STM32F4)

目录

概述

1. 硬件介绍

1.1 ST7796-LCD

1.2 MCU IO与LCD PIN对应关系

2 代码实现

2.1 STM32CubeMX 6.11生成工程

2.2 IO模拟SPI接口

2.3 实现LCD的驱动

3 测试


测试代码下载地址:

stm32-f407-lcd-ft6336-proj资源-CSDN文库

gitee下载地址:

https://gitee.com/mftang/stm32_open_test_proj/tree/master/stm32_f407_lcd_proj

概述

本文主要讲述使用模拟SPI接口驱动ST7796-LCD,主控MCU为STM32F407芯片。笔者详细介绍整个驱动的实现过程,并使用STM32Cube生成一个工程,测试驱动程序的功能。

1. 硬件介绍

1.1 ST7796-LCD

LCD的PIN引脚功能介绍

序号模块引脚引脚说明
1VCC屏电源正
2GND屏电源地
3LCD_CS液晶屏片选控制信号,低电平有效
4LCD_RST液晶屏复位控制信号,低电平复位
5LCD_RS液晶屏命令/数据选择控制信号

高电平:数据,低电平:命令

6SDI(MOSI)SPI总线写数据信号(SD卡和液晶屏共用)
7SCKSPI总线时钟信号(SD卡和液晶屏共用)
8LED液晶屏背光控制信号(如需要控制,请接引脚,如不需要控制,可以不接)
9SDO(MISO)SPI总线读数据信号(SD卡和液晶屏共用)
10CTP_SCL电容触摸屏IIC总线时钟信号(无触摸屏的模块不需连接)
11CTP_RST电容触摸屏复位控制信号,低电平复位(无触摸屏的模块不需连接)
12CTP_SDA电容触摸屏IIC总线数据信号(无触摸屏的模块不需连接)
13CTP_INT电容触摸屏IIC总线触摸中断信号,产生触摸时,输入低电平到主控(无触摸屏的模块不需连接)
14SD_CSSD卡片选控制信号,低电平有效(不使用SD卡功能,可不接)

实体LCD Port对应关系如下图所示

1.2 MCU IO与LCD PIN对应关系

STM32 PIN引脚LCD PIN引脚
PB5-MOSIMOSI
PB4-MISOMISO
PB3-SCKSCK
PB6CS
PB9RST
PB8RS

2 代码实现

2.1 STM32CubeMX 6.11生成工程

笔者尝试使用IO模拟SPI接口,以实现读写数据功能,其配置接口信息如下:

step-1: 配LCD对应的IO

step-2: 使能外部时钟

配置完成后,系统时钟关系如下:

 step-3: 生成工程

2.2 IO模拟SPI接口

1)头文件里定义MOSI,SCK和MISO的电平状态

#ifndef __LCD_SPI_H
#define __LCD_SPI_H

#include <stdlib.h>
#include <stdio.h>
#include "main.h"


// spi port io
// set IO to high 
#define SPI_SCLK_SET           HAL_GPIO_WritePin(lcd_sck_GPIO_Port,lcd_sck_Pin, GPIO_PIN_SET )
#define SPI_MOSI_SET           HAL_GPIO_WritePin(lcd_mosi_GPIO_Port,lcd_mosi_Pin, GPIO_PIN_SET )

// set IO to low 
#define SPI_SCLK_CLR           HAL_GPIO_WritePin(lcd_sck_GPIO_Port,lcd_sck_Pin, GPIO_PIN_RESET )
#define SPI_MOSI_CLR           HAL_GPIO_WritePin(lcd_mosi_GPIO_Port,lcd_mosi_Pin, GPIO_PIN_RESET )

#define SPI_MISO_READ          ((HAL_GPIO_ReadPin(lcd_miso_GPIO_Port, lcd_miso_Pin) == GPIO_PIN_SET)?1:0)  


void SPI_WriteByte(uint8_t Byte);
uint8_t SPI_ReadByte(void);
void lcd_delay_us(uint32_t us);

#endif /* __LCD_SPI_H */

2)实现SPI的读写接口

#include "lcd_spi.h"

void lcd_delay_us(uint32_t us)
{
    uint32_t i=0;
    
    while(us--){
        for(i=0;i<1000;i++);
    }
}

void SPI_WriteByte(uint8_t Byte)
{
    uint8_t i=0;
    
    for(i=0;i<8;i++)
    {
        if(Byte&0x80)
        {
            SPI_MOSI_SET;
        }
        else
        {
            SPI_MOSI_CLR;
        }
        SPI_SCLK_CLR;
        SPI_SCLK_SET;
        Byte<<=1;
    }
} 

uint8_t SPI_ReadByte(void)
{
    uint8_t value=0,i=0,byte=0xFF;

    for(i=0;i<8;i++)
    {
        value<<=1;
        if(byte&0x80)
        {
            SPI_MOSI_SET;
        }
        else
        {
            SPI_MOSI_CLR;
        }
        byte<<=1;
        SPI_SCLK_CLR;
        lcd_delay_us(100);
        if(SPI_MISO_READ)
        {
            value += 1;
        }
        
        SPI_SCLK_SET;
        lcd_delay_us(100);
    }
    return value;
} 

2.3 实现LCD的驱动

在该文件中实现初始化LCD,读写point等接口函数

#include "lcd_drv.h"
#include "lcd_spi.h"

_lcd_dev lcddev;

void LCD_WR_REG(uint8_t data)
{ 
    LCD_CS_CLR;
    LCD_RS_CLR; 
    
    SPI_WriteByte(data);
    LCD_CS_SET;
}

void LCD_WR_DATA(uint8_t data)
{
    LCD_CS_CLR;
    LCD_RS_SET;
    SPI_WriteByte(data);
    LCD_CS_SET;
}

uint8_t LCD_RD_DATA(void)
{
    uint8_t data;
    
    LCD_CS_CLR;
    LCD_RS_SET;
    data = SPI_ReadByte();
    LCD_CS_SET;
    
    return data;
}

void LCD_WriteReg(uint8_t LCD_Reg, uint16_t LCD_RegValue)
{
    LCD_WR_REG(LCD_Reg);  
    LCD_WR_DATA(LCD_RegValue); 
}

uint8_t LCD_ReadReg(uint8_t LCD_Reg)
{
    LCD_WR_REG(LCD_Reg);
    return LCD_RD_DATA();
}

void LCD_WriteRAM_Prepare(void)
{
    LCD_WR_REG(lcddev.wramcmd);
}

void Lcd_WriteData_16Bit(uint16_t Data)
{
    LCD_CS_CLR;
    LCD_RS_SET;
    SPI_WriteByte(Data>>8);
    SPI_WriteByte(Data);
    LCD_CS_SET;
}

uint16_t Lcd_ReadData_16Bit(void)
{
    uint16_t r,g;
    
    LCD_CS_CLR;
    LCD_RS_CLR;
    
    SPI_WriteByte(lcddev.rramcmd);
    LCD_RS_SET;
    SPI_ReadByte();
    r = SPI_ReadByte();
    g = SPI_ReadByte();
    LCD_CS_SET;
    r<<=8;
    r|=g;
    
    return r;
}

void LCD_DrawPoint(uint16_t x,uint16_t y, uint16_t color)
{
    LCD_SetCursor(x,y);//ÉèÖùâ±êλÖà 
    Lcd_WriteData_16Bit(color); 
}

uint16_t LCD_ReadPoint(uint16_t x,uint16_t y)
{
    uint16_t color;
    
    LCD_SetCursor(x,y);//ÉèÖùâ±êλÖà 
    color = Lcd_ReadData_16Bit();
    
    return color;
}

void LCD_Clear(uint16_t Color)
{
    uint16_t i,m; 
    
    LCD_SetWindows(0,0,lcddev.width-1,lcddev.height-1);
    
    LCD_CS_CLR;
    LCD_RS_SET;
    
    for(i=0;i<lcddev.height;i++)
    {
        for(m=0;m<lcddev.width;m++)
        {
            SPI_WriteByte(Color>>8);
            SPI_WriteByte(Color);
        }
    }
    LCD_CS_SET;
} 

void LCD_SetWindows(uint16_t xStar, uint16_t yStar,uint16_t xEnd,uint16_t yEnd)
{
    LCD_WR_REG(lcddev.setxcmd);
    LCD_WR_DATA(xStar>>8);
    LCD_WR_DATA(0x00FF&xStar);
    LCD_WR_DATA(xEnd>>8);
    LCD_WR_DATA(0x00FF&xEnd);

    LCD_WR_REG(lcddev.setycmd);
    LCD_WR_DATA(yStar>>8);
    LCD_WR_DATA(0x00FF&yStar);
    LCD_WR_DATA(yEnd>>8);
    LCD_WR_DATA(0x00FF&yEnd);

    LCD_WriteRAM_Prepare();	//¿ªÊ¼Ð´ÈëGRAM
} 

void LCD_SetCursor(uint16_t Xpos, uint16_t Ypos)
{
    LCD_SetWindows(Xpos,Ypos,Xpos,Ypos);
}

void LCD_direction(uint8_t direction)
{ 
    lcddev.setxcmd=0x2A;
    lcddev.setycmd=0x2B;
    lcddev.wramcmd=0x2C;
    lcddev.rramcmd=0x2E;
    lcddev.dir = direction%4;
    
    switch(lcddev.dir){  
        case 0:
            lcddev.width=LCD_W;
            lcddev.height=LCD_H;
            LCD_WriteReg(0x36,(1<<3)|(1<<6));
        break;
        
        case 1:
            lcddev.width=LCD_H;
            lcddev.height=LCD_W;
            LCD_WriteReg(0x36,(1<<3)|(1<<5));
        break;
        
        case 2:
            lcddev.width=LCD_W;
            lcddev.height=LCD_H;
            LCD_WriteReg(0x36,(1<<3)|(1<<7));
        break;
        
        case 3:
            lcddev.width=LCD_H;
            lcddev.height=LCD_W;
            LCD_WriteReg(0x36,(1<<3)|(1<<7)|(1<<6)|(1<<5));
        break;
        default:break;
    }
} 

uint16_t LCD_Read_ID(void)
{
    uint8_t i,val[3] = {0};

    LCD_WR_REG(0xF0);     // Command Set Control
    LCD_WR_DATA(0xC3);   

    LCD_WR_REG(0xF0);     
    LCD_WR_DATA(0x96);  
    LCD_CS_CLR;

    for(i=1;i<4;i++)
    {
        LCD_RS_CLR;	  
        SPI_WriteByte(0xFB);
        LCD_RS_SET;
        SPI_WriteByte(0x10+i);
        LCD_RS_CLR;	  
        SPI_WriteByte(0xD3);
        LCD_RS_SET;
        val[i-1] = SPI_ReadByte();
        LCD_RS_CLR;	  
        SPI_WriteByte(0xFB);
        LCD_RS_SET;
        SPI_WriteByte(0x00);
    }
    
    LCD_CS_SET;
    LCD_WR_REG(0xF0);     // Command Set Control
    LCD_WR_DATA(0x3C);   
    LCD_WR_REG(0xF0);     
    LCD_WR_DATA(0x69);  
    lcddev.id=val[1];
    lcddev.id<<=8;
    lcddev.id|=val[2];

    return lcddev.id;
}

void LCD_RESET(void)
{
    LCD_RST_CLR;
    lcd_delay_us(100);
    LCD_RST_SET;
    lcd_delay_us(50);
}

void LCD_Init(void)
{  
    LCD_RESET();          //LCD ¸´Î»
    //*************3.5 ST7796S IPS³õʼ»¯**********
    LCD_WR_REG(0x11);     

    lcd_delay_us(120);    //Delay 120ms
    lcd_delay_us(120);    //Delay 120ms

    LCD_WR_REG(0x36);     // Memory Data Access Control MY,MX~~
    LCD_WR_DATA(0x48);   

    LCD_WR_REG(0x3A);     
    LCD_WR_DATA(0x55);   

    LCD_WR_REG(0xF0);     // Command Set Control
    LCD_WR_DATA(0xC3);   

    LCD_WR_REG(0xF0);     
    LCD_WR_DATA(0x96);   

    LCD_WR_REG(0xB4);     
    LCD_WR_DATA(0x01);   

    LCD_WR_REG(0xB7);     
    LCD_WR_DATA(0xC6);   

    //LCD_WR_REG(0xB9);     
    //LCD_WR_DATA(0x02);
    //LCD_WR_DATA(0xE0);

    LCD_WR_REG(0xC0);     
    LCD_WR_DATA(0x80);   
    LCD_WR_DATA(0x45);   

    LCD_WR_REG(0xC1);     
    LCD_WR_DATA(0x13);   //18  //00

    LCD_WR_REG(0xC2);     
    LCD_WR_DATA(0xA7);   

    LCD_WR_REG(0xC5);     
    LCD_WR_DATA(0x0A);   

    LCD_WR_REG(0xE8);     
    LCD_WR_DATA(0x40);
    LCD_WR_DATA(0x8A);
    LCD_WR_DATA(0x00);
    LCD_WR_DATA(0x00);
    LCD_WR_DATA(0x29);
    LCD_WR_DATA(0x19);
    LCD_WR_DATA(0xA5);
    LCD_WR_DATA(0x33);

    LCD_WR_REG(0xE0);
    LCD_WR_DATA(0xD0);
    LCD_WR_DATA(0x08);
    LCD_WR_DATA(0x0F);
    LCD_WR_DATA(0x06);
    LCD_WR_DATA(0x06);
    LCD_WR_DATA(0x33);
    LCD_WR_DATA(0x30);
    LCD_WR_DATA(0x33);
    LCD_WR_DATA(0x47);
    LCD_WR_DATA(0x17);
    LCD_WR_DATA(0x13);
    LCD_WR_DATA(0x13);
    LCD_WR_DATA(0x2B);
    LCD_WR_DATA(0x31);

    LCD_WR_REG(0xE1);
    LCD_WR_DATA(0xD0);
    LCD_WR_DATA(0x0A);
    LCD_WR_DATA(0x11);
    LCD_WR_DATA(0x0B);
    LCD_WR_DATA(0x09);
    LCD_WR_DATA(0x07);
    LCD_WR_DATA(0x2F);
    LCD_WR_DATA(0x33);
    LCD_WR_DATA(0x47);
    LCD_WR_DATA(0x38);
    LCD_WR_DATA(0x15);
    LCD_WR_DATA(0x16);
    LCD_WR_DATA(0x2C);
    LCD_WR_DATA(0x32);


    LCD_WR_REG(0xF0);     
    LCD_WR_DATA(0x3C);   

    LCD_WR_REG(0xF0);     
    LCD_WR_DATA(0x69);   

    lcd_delay_us(120);

    LCD_WR_REG(0x21);     

    LCD_WR_REG(0x29); 

    LCD_direction(USE_HORIZONTAL); //ÉèÖÃLCDÏÔʾ·½Ïò 
    LCD_Clear(GREEN);              //ÇåÈ«ÆÁ°×É«
}


/* End of this file */

该driver对应的头文件:

#ifndef __LCD_DRV_H
#define __LCD_DRV_H

#include <stdlib.h>
#include <stdio.h>
#include "main.h"

//LCD重要参数集
typedef struct  
{ 
    uint16_t width;      //LCD 宽度
    uint16_t height;     //LCD 高度
    uint16_t id;         //LCD ID
    uint8_t  dir;        //横屏还是竖屏控制:0,竖屏;1,横屏。	
    uint16_t  wramcmd;   //开始写gram指令
    uint16_t  rramcmd;   //开始读gram指令
    uint16_t  setxcmd;   //设置x坐标指令
    uint16_t  setycmd;   //设置y坐标指令
}_lcd_dev; 	

//LCD参数
extern _lcd_dev lcddev;	//管理LCD重要参数

/用户配置区///	 
#define USE_HORIZONTAL        0//定义液晶屏顺时针旋转方向 	0-0度旋转,1-90度旋转,2-180度旋转,3-270度旋转

//	  
//定义LCD的尺寸
#define LCD_W 320
#define LCD_H 480



//如果使用官方库函数定义下列底层,速度将会下降到14帧每秒,建议采用我司推荐方法
//以下IO定义直接操作寄存器,快速IO操作,刷屏速率可以达到28帧每秒! 

#define	LCD_CS_SET     HAL_GPIO_WritePin(lcd_cs_GPIO_Port,lcd_cs_Pin, GPIO_PIN_SET )
#define	LCD_RS_SET     HAL_GPIO_WritePin(lcd_rs_GPIO_Port,lcd_rs_Pin, GPIO_PIN_SET ) 
#define	LCD_RST_SET    HAL_GPIO_WritePin(lcd_rst_GPIO_Port,lcd_rst_Pin, GPIO_PIN_SET )

  
#define	LCD_CS_CLR     HAL_GPIO_WritePin(lcd_cs_GPIO_Port,lcd_cs_Pin, GPIO_PIN_RESET )
#define	LCD_RS_CLR     HAL_GPIO_WritePin(lcd_rs_GPIO_Port,lcd_rs_Pin, GPIO_PIN_RESET ) 
#define	LCD_RST_CLR    HAL_GPIO_WritePin(lcd_rst_GPIO_Port,lcd_rst_Pin, GPIO_PIN_RESET )


//画笔颜色
#define WHITE       0xFFFF
#define BLACK       0x0000  
#define BLUE        0x001F  
#define BRED        0XF81F
#define GRED        0XFFE0
#define GBLUE       0X07FF
#define RED         0xF800
#define MAGENTA     0xF81F
#define GREEN       0x07E0
#define CYAN        0x7FFF
#define YELLOW      0xFFE0
#define BROWN       0XBC40 //棕色
#define BRRED       0XFC07 //棕红色
#define GRAY        0X8430 //灰色
//GUI颜色

#define DARKBLUE    0X01CF //深蓝色
#define LIGHTBLUE   0X7D7C //浅蓝色  
#define GRAYBLUE    0X5458 //灰蓝色
//以上三色为PANEL的颜色 
 
#define LIGHTGREEN   0X841F //浅绿色
#define LIGHTGRAY    0XEF5B //浅灰色(PANNEL)
#define LGRAY        0XC618 //浅灰色(PANNEL),窗体背景色

#define LGRAYBLUE    0XA651 //浅灰蓝色(中间层颜色)
#define LBBLUE       0X2B12 //浅棕蓝色(选择条目的反色)


void LCD_Init(void);
void LCD_DisplayOn(void);
void LCD_DisplayOff(void);
void LCD_Clear(uint16_t Color);	 
void LCD_SetCursor(uint16_t Xpos, uint16_t Ypos);
void LCD_DrawPoint(uint16_t x,uint16_t y, uint16_t color);
uint16_t  LCD_ReadPoint(uint16_t x,uint16_t y);              //读点
void LCD_DrawLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
void LCD_DrawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
void LCD_SetWindows(uint16_t xStar, uint16_t yStar,uint16_t xEnd,uint16_t yEnd);

uint8_t LCD_RD_DATA(void);                                 //读取LCD数据  
void LCD_WriteReg(uint8_t LCD_Reg, uint16_t LCD_RegValue);
void LCD_WR_DATA(uint8_t data);
uint8_t LCD_ReadReg(uint8_t LCD_Reg);
void LCD_WriteRAM_Prepare(void);
void LCD_WriteRAM(uint16_t RGB_Code);
uint16_t LCD_ReadRAM(void);
uint16_t LCD_BGR2RGB(uint16_t c);
void LCD_SetParam(void);
void Lcd_WriteData_16Bit(uint16_t Data);
void LCD_direction(uint8_t direction );
uint16_t LCD_Read_ID(void);



#endif    /* __LCD_DRV_H */

3 测试

1)调用接口,并编译项目

   LCD_Init();              // 初始化LCD 
   LCD_Read_ID();     // 读取LCD的驱动芯片ID

2) 运行代码

读取id测试:

清屏测试:

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

48. 旋转图像/240. 搜索二维矩阵 II

48. 旋转图像 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 &#xff1a; 输入&#xff1a;matrix [[5,1,9,11],[2,4,…

NodeMCU ESP8266 获取I2C从机地址

文章目录 前言关于地址位读写位程序总结前言 I2C总线上可以挂载很多的从设备,每个设备都会有一个自己唯一的一个地址; 关于地址位 通常地址位占7位数据,主设备如果需要向从机发送/接收数据,首先要发送对应从机的地址,然后会匹配总线上挂载的从机的地址; 读写位 该位…

81.网络游戏逆向分析与漏洞攻防-移动系统分析-飞天遁地的实现与面向计算

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果&#xff0c;代码看不懂是正常的&#xff0c;只要会抄就行&#xff0c;抄着抄着就能懂了 内容…

服装定制|基于SSM+vue的服装定制系统的设计与实现(源码+数据库+文档)

服装定制系统 目录 基于SSM&#xff0b;vue的服装定制系统的设计与实现 一、前言 二、系统设计 三、系统功能设计 1系统功能模块 2管理员功能模块 3用户后台管理模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xf…

【CTF Web】QSNCTF 文章管理系统 Writeup(SQL注入+Linux命令+RCE)

文章管理系统 题目描述 这是我们的文章管理系统&#xff0c;快来看看有什么漏洞可以拿到FLAG吧&#xff1f;注意&#xff1a;可能有个假FLAG哦 解法 SQL 注入。 ?id1 or 11 --取得假 flag。 爆库名。 ?id1 union select 1,group_concat(schema_name) from information_sch…

【机器学习】集成学习在信用评分领域实例

集成学习在信用评分领域的应用与实践 一、引言二、集成学习的概念与原理三、集成学习在信用评分中的应用实例四、总结与展望 一、引言 在当今金融数字化快速发展的时代&#xff0c;信用评分成为银行、金融机构等评估个人或企业信用风险的重要工具。然而&#xff0c;单一的信用评…

飞天使-k8s知识点31-rancher的正确打开方式

文章目录 安装之前优化一下内核参数以及系统内核版本 rancher安装主要是使用以下命令nginx的配置为解决办法 安装之前优化一下内核参数以及系统内核版本 内核版本 4.17 cat > /etc/modules-load.d/iptables.conf <<EOF ip_tables iptable_filter EOF 然后重启服务器…

STM32快速入门(定时器之输出PWM波形)

STM32快速入门&#xff08;定时器之输出PWM波形&#xff09; 前言 本节主要讲解STM32利用通用定时器&#xff0c;利用CCR和CNT寄存器&#xff0c;输出指定占空比和频率的PWM波形。其功能的应用有&#xff1a;实现LED呼吸灯的效果、控制步进电机、控制直流电机转速等。 导航 …

基于FPGA的NC图像质量评估verilog实现,包含testbench和MATLAB辅助验证程序

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 vivado2019.2和matlab2022a测试&#xff0c;结果如下&#xff1a; 2.算法运行软件版本 vivado2019.2 matlab2022a 3.部分核心程序 timescale …

解决vue3项目打包后部署后某些静态资源图片不加载问题

目录 问题 原因 解决方案 问题 开发完项目打包并部署 然后访问时发现导航栏背景图片没加载 打开浏览器控制台发现这张图片报错404 原因 可能是因为在部署后的服务器环境中对中文文件名的支持不完善。服务器在解析 URL 时可能无法正确识别或编码中文字符&#xff0c;导致无…

高精度原理介绍及代码实现

目录 高精度 引入 使用场景 实现原理 高精度加法 数据存储 加法实现 总代码 高精度减法 与加法的不同点&#xff1a; 总代码 高精度乘法 总代码 高精度除法 总结 总注意点 减法注意点 高精度 引入 所谓高精度并不是很高级难懂的东西&#xff0c;只是对传统的…

Kubernetes 核心概念

kubernetes的对象 Kubernetes 包含多种类型的资源对象&#xff1a;Pod、Label、Service、Replication Controller 等。 所有的资源对象都可以通过 Kubernetes 提供的 kubectl 工具进行增、删、改、查等操作&#xff0c;并将其保存在 etcd 中持久化存储。 Kubernets其实是一个…

【JAVA进阶篇教学】第十三篇:Java中volatile关键字讲解

博主打算从0-1讲解下java进阶篇教学&#xff0c;今天教学第十三篇&#xff1a;volatile关键字讲解。 在 Java 中&#xff0c;volatile关键字是一种轻量级的同步机制&#xff0c;用于确保变量的可见性和禁止指令重排序。本文将详细解释volatile关键字的工作原理、可见性保证以及…

对称加密介绍

一、什么是对称加密 对称密钥算法(Symmetric-key algorithm)&#xff0c;又称为对称加密、私钥加密、共享密钥加密&#xff0c;是密码学中的一类加密算法。 对称加密的特点是&#xff0c;在加密和解密时使用相同的密钥&#xff0c;或是使用两个可以简单地相互推算的密钥。 这…

Zynq开发-使用PYNQ快速入门摄像头MIPI驱动(OV5640)-overlay设计

目录 1. 简介 2. Overlay 设计 2.1 总体设计 2.2 MIPI 子系统 2.3 去马赛克 2.4 AXI_IIC 3. 注意事项 4. 总结 1. 简介 本文是关于《Zynq开发-使用PYNQ快速入门摄像头MIPI驱动(OV5640)-CSDN博客》的博客文章&#xff0c;涉及了overlay设计的Vivado工程细节。在使用PYN…

iZotope RX 11 for Mac 激活版:让您的音频焕发生机!

在追求音频完美的道路上&#xff0c;iZotope RX 11 for Mac是您的得力助手。它凭借先进的音频修复技术和丰富的音频增强工具&#xff0c;让您的音频作品焕发出前所未有的生机与活力。无论您是专业的音频工程师&#xff0c;还是业余的音乐爱好者&#xff0c;都能在这款工具中找到…

【Spring】验证 @ServerEndpoint 的类成员变量线程安全

文章目录 前言猜想来源验证方法Controller 的情况ServerEndpoint 的情况 后记 前言 最近有 websocket 的需求。探索 ServerEndpoint 的类成员变量特点。 这里类比 Controller 讨论 ServerEndpoint 类成员变量是否线程安全。 猜想来源 网上的教程大多数都这么展示程序&#…

OBS插件--音频采集

音频采集 音频采集是一款 源 插件,类似于OBS的win-capture/game-capture&#xff0c;允许从特定应用程序捕获音频&#xff0c;而不是捕获整个系统的音频。避免了因为特定音频的采集而需要引入第三方软件&#xff0c;而且时延也非常低。 下面截图演示下操作步骤&#xff1a; 首…

HCIP-Datacom-ARST自选题库_06_排障【28道题】

一、单选题 1.如果面对复杂的网络故障&#xff0c;并经过评估认为短时间内无法完成排障&#xff0c;而此时用户又急需恢复网络的可用性&#xff0c;那么正确的做法是? 告诉用户这是不可能实现的 不通知客户的情况下&#xff0c;直接搭建替代的网络环境 始终尝试排除故障&a…

前端AJAX与后台交互技术知识点及案例(续2)

以下笔记均为学习哔站黑马程序员AJAX视频所得&#xff01;&#xff01;&#xff01; AJAX作用&#xff1a;浏览器和服务器之间通信&#xff0c;动态数据交互 axios函数 先引入axios库&#xff0c;可在bootcdn中寻找相关js文件或者对应的script标签 axios({url:http://hmajax…