树莓派3B驱动ST7735(Python)

news2024/9/21 16:36:28

一 环境准备

之前做了PICO驱动ST7735,这次再进一步,用树莓派3B来驱动。还是先上图。

最开始还是根据GPT的指引来做的。SPI的细节就不多说了,之前在PICO的时候说过了。

总线学习3--SPI-CSDN博客

二 实现细节

连接方式如下:

  • VCC → 3.3V
  • GND → GND
  • SCL (SCK) → GPIO 11 (Pin 23)
  • SDA (MOSI) → GPIO 10 (Pin 19)
  • RES (Reset) → GPIO 25 (Pin 22)
  • DC (Data/Command) → GPIO 24 (Pin 18)
  • CS (Chip Select) → GPIO 8 (Pin 24)

首先还是配置打开SPI。

就是用sudo raspi-config,或者直接改config.txt也可以。

然后是安装需要的库。

sudo apt-get update
sudo apt-get install python3-pip python3-dev python3-spidev python3-pil python3-numpy
sudo pip3 install st7735

这里遇到了两个坑。

首先是GPT说的在config.txt增加内容:

如果你想通过 Linux 帧缓冲设备(`/dev/fb1`)来控制 ST7735,可以使用设备树配置 ST7735
   ```bash
   dtoverlay=spi0-hw-cs
   dtoverlay=pitft28-resistive,rotate=90,speed=32000000,fps=60
   ```

这个部分加进去,立马SPI整个启动都有问题了。

[    5.560311] stmpe-spi spi0.1: unknown chip id: 0x0
[    5.560351] stmpe-spi: probe of spi0.1 failed with error -22

查了一下午,最后发现GPT搞成需要触屏的驱动了,pitft28-resistive一般是用在需要触屏的地方,然后dtoverlay的用法也不是很熟悉,看起来应该是设备树的匹配,这块后面有时间再研究研究。

最后直接删掉这个不加,一下就好了。

第二个坑是直接用的python的st7735库,也就是pip3 install的。按照它说的初始化

disp = ST7735.ST7735(
    port=0,
    cs=0,
    dc=24,
    backlight=18,
    rst=25,
    width=160,
    height=128,
    rotation=90,
    spi_speed_hz=4000000
)

最后屏幕能驱动,但是整个都是花屏的,没法正常显示。试了很久都没解决。

最后还是被三哥拯救了。看到三哥的一个视频。

https://www.youtube.com/watch?v=SYdGNpfLxKw

三哥用的是这个库:

https://github.com/degzero/Python_ST7735

Adafruit,好像之前PICO的时候也看过,算了,不细究了。直接把库和库上的example拿下来,立刻出图。。。。就是最开始那张。

这里有两个小疑惑。

不知道3B的SPI是不是只有这一组,我看基本上都是用的11,10两个口。DC和RST也基本都是24,25两个口。

另外CS好像没配置,但是也能用。难道说默认就试直接拉低?等有时间有心情看看波形吧。。。

三 驱动代码

驱动的原理也不多说了,以前PICO的时候写过:显示学习5(基于树莓派Pico) -- 彩色LCD的驱动_树莓派pico将摄像头画面显示到spi显示屏-CSDN博客

image.py代码如下:

# Copyright (c) 2014 Adafruit Industries
# Author: Tony DiCola
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
from PIL import Image

import ST7735 as TFT
import Adafruit_GPIO as GPIO
import Adafruit_GPIO.SPI as SPI


WIDTH = 128
HEIGHT = 160
SPEED_HZ = 4000000


# Raspberry Pi configuration.
DC = 24
RST = 25
SPI_PORT = 0
SPI_DEVICE = 0

# BeagleBone Black configuration.
# DC = 'P9_15'
# RST = 'P9_12'
# SPI_PORT = 1
# SPI_DEVICE = 0

# Create TFT LCD display class.
disp = TFT.ST7735(
    DC,
    rst=RST,
    spi=SPI.SpiDev(
        SPI_PORT,
        SPI_DEVICE,
        max_speed_hz=SPEED_HZ))

# Initialize display.
disp.begin()

# Load an image.
print('Loading image...')
image = Image.open('cat.jpg')

# Resize the image and rotate it so matches the display.
image = image.rotate(90).resize((WIDTH, HEIGHT))

# Draw the image on the display hardware.
print('Drawing image')
disp.display(image)

驱动库ST7735.py如下:

# Copyright (c) 2014 Adafruit Industries
# Author: Tony DiCola
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
import numbers
import time
import numpy as np

from PIL import Image
from PIL import ImageDraw

import Adafruit_GPIO as GPIO
import Adafruit_GPIO.SPI as SPI


# SPI_CLOCK_HZ = 64000000 # 64 MHz
SPI_CLOCK_HZ = 4000000 # 4 MHz


# Constants for interacting with display registers.
ST7735_TFTWIDTH    = 128
ST7735_TFTHEIGHT   = 160

ST7735_NOP         = 0x00
ST7735_SWRESET     = 0x01
ST7735_RDDID       = 0x04
ST7735_RDDST       = 0x09

ST7735_SLPIN       = 0x10
ST7735_SLPOUT      = 0x11
ST7735_PTLON       = 0x12
ST7735_NORON       = 0x13

# ILI9341_RDMODE      = 0x0A
# ILI9341_RDMADCTL    = 0x0B
# ILI9341_RDPIXFMT    = 0x0C
# ILI9341_RDIMGFMT    = 0x0A
# ILI9341_RDSELFDIAG  = 0x0F

ST7735_INVOFF      = 0x20
ST7735_INVON       = 0x21
# ILI9341_GAMMASET    = 0x26
ST7735_DISPOFF     = 0x28
ST7735_DISPON      = 0x29

ST7735_CASET       = 0x2A
ST7735_RASET       = 0x2B
ST7735_RAMWR       = 0x2C
ST7735_RAMRD       = 0x2E

ST7735_PTLAR       = 0x30
ST7735_MADCTL      = 0x36
# ST7735_PIXFMT      = 0x3A
ST7735_COLMOD       = 0x3A

ST7735_FRMCTR1     = 0xB1
ST7735_FRMCTR2     = 0xB2
ST7735_FRMCTR3     = 0xB3
ST7735_INVCTR      = 0xB4
# ILI9341_DFUNCTR     = 0xB6
ST7735_DISSET5      = 0xB6


ST7735_PWCTR1      = 0xC0
ST7735_PWCTR2      = 0xC1
ST7735_PWCTR3      = 0xC2
ST7735_PWCTR4      = 0xC3
ST7735_PWCTR5      = 0xC4
ST7735_VMCTR1      = 0xC5
# ILI9341_VMCTR2      = 0xC7

ST7735_RDID1       = 0xDA
ST7735_RDID2       = 0xDB
ST7735_RDID3       = 0xDC
ST7735_RDID4       = 0xDD

ST7735_GMCTRP1     = 0xE0
ST7735_GMCTRN1     = 0xE1

ST7735_PWCTR6      = 0xFC

# Colours for convenience
ST7735_BLACK       = 0x0000 # 0b 00000 000000 00000
ST7735_BLUE        = 0x001F # 0b 00000 000000 11111
ST7735_GREEN       = 0x07E0 # 0b 00000 111111 00000
ST7735_RED         = 0xF800 # 0b 11111 000000 00000
ST7735_CYAN        = 0x07FF # 0b 00000 111111 11111
ST7735_MAGENTA     = 0xF81F # 0b 11111 000000 11111
ST7735_YELLOW      = 0xFFE0 # 0b 11111 111111 00000
ST7735_WHITE       = 0xFFFF # 0b 11111 111111 11111


def color565(r, g, b):
    """Convert red, green, blue components to a 16-bit 565 RGB value. Components
    should be values 0 to 255.
    """
    return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3)

def image_to_data(image):
    """Generator function to convert a PIL image to 16-bit 565 RGB bytes."""
    # NumPy is much faster at doing this. NumPy code provided by:
    # Keith (https://www.blogger.com/profile/02555547344016007163)
    pb = np.array(image.convert('RGB')).astype('uint16')
    color = ((pb[:,:,0] & 0xF8) << 8) | ((pb[:,:,1] & 0xFC) << 3) | (pb[:,:,2] >> 3)
    return np.dstack(((color >> 8) & 0xFF, color & 0xFF)).flatten().tolist()

# Define a function to hard code that we are using a raspberry pi
def get_platform_gpio_for_pi(**keywords):
    import RPi.GPIO
    return GPIO.RPiGPIOAdapter(RPi.GPIO, **keywords)

class ST7735(object):
    """Representation of an ST7735 TFT LCD."""

    def __init__(self, dc, spi, rst=None, gpio=None, width=ST7735_TFTWIDTH,
        height=ST7735_TFTHEIGHT):
        """Create an instance of the display using SPI communication.  Must
        provide the GPIO pin number for the D/C pin and the SPI driver.  Can
        optionally provide the GPIO pin number for the reset pin as the rst
        parameter.
        """
        self._dc = dc
        self._rst = rst
        self._spi = spi
        self._gpio = gpio
        self.width = width
        self.height = height
        if self._gpio is None:
            #self._gpio = GPIO.get_platform_gpio()
            self._gpio = get_platform_gpio_for_pi()
        # Set DC as output.
        self._gpio.setup(dc, GPIO.OUT)
        # Setup reset as output (if provided).
        if rst is not None:
            self._gpio.setup(rst, GPIO.OUT)
        # Set SPI to mode 0, MSB first.
        spi.set_mode(0)
        spi.set_bit_order(SPI.MSBFIRST)
        spi.set_clock_hz(SPI_CLOCK_HZ)
        # Create an image buffer.
        self.buffer = Image.new('RGB', (width, height))

    def send(self, data, is_data=True, chunk_size=4096):
        """Write a byte or array of bytes to the display. Is_data parameter
        controls if byte should be interpreted as display data (True) or command
        data (False).  Chunk_size is an optional size of bytes to write in a
        single SPI transaction, with a default of 4096.
        """
        # Set DC low for command, high for data.
        self._gpio.output(self._dc, is_data)
        # Convert scalar argument to list so either can be passed as parameter.
        if isinstance(data, numbers.Number):
            data = [data & 0xFF]
        # Write data a chunk at a time.
        for start in range(0, len(data), chunk_size):
            end = min(start+chunk_size, len(data))
            self._spi.write(data[start:end])

    def command(self, data):
        """Write a byte or array of bytes to the display as command data."""
        self.send(data, False)

    def data(self, data):
        """Write a byte or array of bytes to the display as display data."""
        self.send(data, True)

    def reset(self):
        """Reset the display, if reset pin is connected."""
        if self._rst is not None:
            self._gpio.set_high(self._rst)
            time.sleep(0.500)
            self._gpio.set_low(self._rst)
            time.sleep(0.500)
            self._gpio.set_high(self._rst)
            time.sleep(0.500)

    def _init(self):
        # Initialize the display.  Broken out as a separate function so it can
        # be overridden by other displays in the future.
        
        self.command(ST7735_SWRESET) # Software reset
        time.sleep(0.150) # delay 150 ms
        
        self.command(ST7735_SLPOUT) # Out of sleep mode
        time.sleep(0.500) # delay 500 ms
        
        self.command(ST7735_FRMCTR1) # Frame rate ctrl - normal mode
        self.data(0x01) # Rate = fosc/(1x2+40) * (LINE+2C+2D)
        self.data(0x2C)
        self.data(0x2D)
        
        self.command(ST7735_FRMCTR2) # Frame rate ctrl - idle mode
        self.data(0x01) # Rate = fosc/(1x2+40) * (LINE+2C+2D)
        self.data(0x2C)
        self.data(0x2D)
        
        self.command(ST7735_FRMCTR3) # Frame rate ctrl - partial mode
        self.data(0x01) # Dot inversion mode
        self.data(0x2C)
        self.data(0x2D)
        self.data(0x01) # Line inversion mode
        self.data(0x2C)
        self.data(0x2D)
        
        self.command(ST7735_INVCTR) # Display inversion ctrl
        self.data(0x07) # No inversion
        
        self.command(ST7735_PWCTR1) # Power control
        self.data(0xA2)
        self.data(0x02) # -4.6V
        self.data(0x84) # auto mode
        
        self.command(ST7735_PWCTR2) # Power control
        self.data(0x0A) # Opamp current small
        self.data(0x00) # Boost frequency
        
        self.command(ST7735_PWCTR4) # Power control
        self.data(0x8A) # BCLK/2, Opamp current small & Medium low
        self.data(0x2A)
        
        self.command(ST7735_PWCTR5) # Power control
        self.data(0x8A)
        self.data(0xEE)
        
        self.command(ST7735_VMCTR1) # Power control
        self.data(0x0E)
        
        self.command(ST7735_INVOFF) # Don't invert display
        
        self.command(ST7735_MADCTL) # Memory access control (directions)
        self.data(0xC8) # row addr/col addr, bottom to top refresh
        
        self.command(ST7735_COLMOD) # set color mode
        self.data(0x05) # 16-bit color
        
        #
        
        self.command(ST7735_CASET) # Column addr set
        self.data(0x00) # XSTART = 0
        self.data(0x00)
        self.data(0x00) # XEND = 127
        self.data(0x7F)
        
        self.command(ST7735_RASET) # Row addr set
        self.data(0x00) # XSTART = 0
        self.data(0x00)
        self.data(0x00) # XEND = 159
        self.data(0x9F)
        
        #
        
        self.command(ST7735_GMCTRP1) # Set Gamma
        self.data(0x02)
        self.data(0x1c)
        self.data(0x07)
        self.data(0x12)
        self.data(0x37)
        self.data(0x32)
        self.data(0x29)
        self.data(0x2d)
        self.data(0x29)
        self.data(0x25)
        self.data(0x2B)
        self.data(0x39)
        self.data(0x00)
        self.data(0x01)
        self.data(0x03)
        self.data(0x10)
        
        self.command(ST7735_GMCTRN1) # Set Gamma
        self.data(0x03)
        self.data(0x1d)
        self.data(0x07)
        self.data(0x06)
        self.data(0x2E)
        self.data(0x2C)
        self.data(0x29)
        self.data(0x2D)
        self.data(0x2E)
        self.data(0x2E)
        self.data(0x37)
        self.data(0x3F)
        self.data(0x00)
        self.data(0x00)
        self.data(0x02)
        self.data(0x10)
        
        self.command(ST7735_NORON) # Normal display on
        time.sleep(0.10) # 10 ms
        
        self.command(ST7735_DISPON) # Display on
        time.sleep(0.100) # 100 ms

    def begin(self):
        """Initialize the display.  Should be called once before other calls that
        interact with the display are called.
        """
        self.reset()
        self._init()

    def set_window(self, x0=0, y0=0, x1=None, y1=None):
        """Set the pixel address window for proceeding drawing commands. x0 and
        x1 should define the minimum and maximum x pixel bounds.  y0 and y1
        should define the minimum and maximum y pixel bound.  If no parameters
        are specified the default will be to update the entire display from 0,0
        to width-1,height-1.
        """
        if x1 is None:
            x1 = self.width-1
        if y1 is None:
            y1 = self.height-1
        self.command(ST7735_CASET)        # Column addr set
        self.data(x0 >> 8)
        self.data(x0)                    # XSTART
        self.data(x1 >> 8)
        self.data(x1)                    # XEND
        self.command(ST7735_RASET)        # Row addr set
        self.data(y0 >> 8)
        self.data(y0)                    # YSTART
        self.data(y1 >> 8)
        self.data(y1)                    # YEND
        self.command(ST7735_RAMWR)        # write to RAM

    def display(self, image=None):
        """Write the display buffer or provided image to the hardware.  If no
        image parameter is provided the display buffer will be written to the
        hardware.  If an image is provided, it should be RGB format and the
        same dimensions as the display hardware.
        """
        # By default write the internal buffer to the display.
        if image is None:
            image = self.buffer
        # Set address bounds to entire display.
        self.set_window()
        # Convert image to array of 16bit 565 RGB data bytes.
        # Unfortunate that this copy has to occur, but the SPI byte writing
        # function needs to take an array of bytes and PIL doesn't natively
        # store images in 16-bit 565 RGB format.
        pixelbytes = list(image_to_data(image))
        # Write data to hardware.
        self.data(pixelbytes)

    def clear(self, color=(0,0,0)):
        """Clear the image buffer to the specified RGB color (default black)."""
        width, height = self.buffer.size
        self.buffer.putdata([color]*(width*height))

    def draw(self):
        """Return a PIL ImageDraw instance for 2D drawing on the image buffer."""
        return ImageDraw.Draw(self.buffer)

四 后续

对了,再说说ST7735的理论刷新率。

  • SPI 时钟速度:ST7735 的数据手册中提到 SPI 时钟可以达到 15MHz,但树莓派 3B 的 SPI 最高可以达到 125MHz(这取决于配置和线缆质量)。
  • 屏幕分辨率:160x128 像素。

计算刷新率:

假设你将 SPI 速度配置为 32MHz:

  1. 每帧的数据量

    • 160 x 128 像素,假设每个像素使用 16 位(2 字节)颜色数据。
    • 每帧数据量 = 160 * 128 * 2 = 40960 字节。
  2. 传输时间

    • 传输时间 = 数据量 / SPI 时钟速度 = 40960 字节 / 32MHz = 1.28 毫秒。
  3. 理论最大刷新率

    • 刷新率 = 1 / 传输时间 = 1 / 1.28 毫秒 ≈ 781 Hz。

看起来接口刷新率是足够了,就看图形侧行不行了。。。

好了,虽然被GPT坑了一下,最后还是在今天搞定了,当然自己确实还是很多不懂的。这个只是前菜,过两天会改成直接在内核支持,然后全部用C/C++实现。好了,就这样吧。。。

五 GPT参考

要在树莓派 3B 上驱动 ST7735 LCD 屏幕并显示 "Hello World",你可以使用 Linux 内核中的 SPI 驱动程序以及帧缓冲驱动程序来控制显示屏。下面是一个详细的步骤,包括硬件连接、内核配置、驱动安装以及代码实现。

### 1. 硬件连接

首先,将 ST7735 屏幕连接到树莓派 3B 的 SPI 接口。以下是标准的连接方式:

- **VCC** → 3.3V
- **GND** → GND
- **SCL (SCK)** → GPIO 11 (Pin 23)
- **SDA (MOSI)** → GPIO 10 (Pin 19)
- **RES (Reset)** → GPIO 25 (Pin 22)
- **DC (Data/Command)** → GPIO 24 (Pin 18)
- **CS (Chip Select)** → GPIO 8 (Pin 24)

### 2. 启用 SPI 接口

SPI 是默认禁用的,因此需要启用它:

1. 打开 Raspberry Pi 配置工具:

   ```bash
   sudo raspi-config
   ```

2. 选择 **Interfacing Options** → **SPI**,然后选择 **Yes** 启用 SPI。

3. 重启 Raspberry Pi:

   ```bash
   sudo reboot
   ```

### 3. 安装必要的库和工具

安装 Python 库和工具来与 ST7735 屏幕交互:

```bash
sudo apt-get update
sudo apt-get install python3-pip python3-dev python3-spidev python3-pil python3-numpy
sudo pip3 install st7735
```

### 4. 配置设备树

如果你想通过 Linux 帧缓冲设备(`/dev/fb1`)来控制 ST7735,可以使用设备树配置 ST7735:

1. 打开设备树文件:

   ```bash
   sudo nano /boot/config.txt
   ```

2. 添加以下行来启用 SPI 并配置 ST7735:

   ```bash
   dtoverlay=spi0-hw-cs
   dtoverlay=pitft28-resistive,rotate=90,speed=32000000,fps=60
   ```

   这里的 `rotate` 参数可以根据需要调整屏幕方向。

3. 保存文件并退出,然后重启 Raspberry Pi:

   ```bash
   sudo reboot
   ```

### 5. 使用 Python 脚本显示 "Hello World"

以下是一个简单的 Python 脚本,使用 `st7735` 库在屏幕上显示 "Hello World":

```python
import ST7735
from PIL import Image, ImageDraw, ImageFont

# 创建ST7735 LCD实例
disp = ST7735.ST7735(
    port=0,
    cs=0,
    dc=24,
    backlight=18,
    rst=25,
    width=160,
    height=128,
    rotation=90,
    spi_speed_hz=4000000
)

# 初始化显示屏
disp.begin()

# 创建一个图像对象
width = disp.width
height = disp.height
image = Image.new('RGB', (width, height))
draw = ImageDraw.Draw(image)

# 填充背景颜色
draw.rectangle((0, 0, width, height), outline=0, fill=(0, 0, 0))

# 加载字体
font = ImageFont.load_default()

# 定义显示的文本
text = "Hello World"

# 计算文本的位置
text_size = draw.textsize(text, font)
text_x = (width - text_size[0]) // 2
text_y = (height - text_size[1]) // 2

# 绘制文本
draw.text((text_x, text_y), text, font=font, fill=(255, 255, 255))

# 显示图像
disp.display(image)
```

### 6. 运行脚本

将上述 Python 脚本保存为 `hello_world.py`,然后在命令行中运行:

```bash
python3 hello_world.py
```

### 7. 验证显示

运行脚本后,ST7735 屏幕应该会显示 "Hello World" 这几个字。如果一切正常,这意味着你成功地在树莓派 3B 上驱动了 ST7735 显示屏并显示了文本。

### 总结

通过这些步骤,你可以在树莓派 3B 上成功驱动 ST7735 LCD 屏幕,并在屏幕上显示 "Hello World"。你可以进一步定制显示的内容或创建更复杂的图形界面来适应你的项目需求。

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

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

相关文章

猛兽财经:AMD股票值得长期投资吗?

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 过去三年对AMD来说可谓压力山大&#xff0c;由于个人电脑(PC)市场的疲软&#xff0c;AMD的股价一直承受着巨大的压力&#xff08;AMD的股价在过去三年中仅上涨了44%&#xff0c;远远低于费城半导体指数56%的涨幅&#xff…

快速申请公网、内网IP地址SSL证书

在当今社会&#xff0c;网络安全越来越重要。SSL证书不仅能够提供加密的数据传输&#xff0c;还能增强用户信任度&#xff0c;提升搜索引擎排名等。但是只有IP地址可以用来申请SSL证书吗&#xff1f;答案当然是可以的&#xff0c;而且申请也非常容易。下面是快速申请流程&#…

SpringBoot3核心特性-数据访问

目录 传送门前言整合SSM场景一、创建SSM整合项目二、配置数据源三、配置MyBatis四、CRUD编写五、自动配置原理六、快速定位生效的配置七、扩展&#xff1a;整合其他数据源1、Druid 数据源2、附录&#xff1a;示例数据库 传送门 SpringMVC的源码解析&#xff08;精品&#xff0…

如何通过工业交换机增加网络带宽?

在现代工业环境中&#xff0c;网络的稳定性和带宽的充足性显得尤为重要。随着设备的增加和数据流量的增长&#xff0c;单一的网络带宽往往难以满足企业对于高效数据传输的需求。因此&#xff0c;如何通过工业交换机来增加网络带宽&#xff0c;成为了技术人员关注的重点。 首先&…

新手使用住宅代理有哪些常见误区?

作为新手&#xff0c;在使用住宅代理时往往会陷入一些常见误区&#xff0c;这些误区不仅可能影响到使用效果&#xff0c;甚至可能会带来安全风险。今天将与大家探讨新手在使用住宅代理时可能会遇到的几个关键误区&#xff0c;并提供相应的解决方案。误区一&#xff1a;盲目追求…

「合诚」× 企企通SRM项目启动,高分子新材料和健康产业高新技术企业将奔赴数智采购新征程

为拉通产业链上下游&#xff0c;优化提升整体效率&#xff0c;帮助企业变革采购管理方式&#xff0c;推动化工新材料行业高质量发展&#xff0c;近日&#xff0c;合诚技术股份有限公司&#xff08;以下简称“合诚”&#xff09;携手企企通成功举办了SRM项目启动会&#xff0c;双…

微电网能量管理系统在企业光伏电站的应用

发展背景&#xff1a; 在全球不可再生能源稀缺的背景下各个国家都在大力发展可再生能源&#xff0c;因此光伏行业应需而生且迅速发展了起来。能源转型中的光伏储能是指将光伏发电与储能技术相结合&#xff0c;以解决太阳能发电的间歇性和不稳定性问题&#xff0c;实现更稳定、…

怎么使用PPT倒计时插件?这款在线PPT工具,堪称办公必备!

在进行ppt演示时&#xff0c;为了更好地把控演示时间&#xff0c;有些人会在演示的同时设置一个倒计时&#xff0c;但Office的ppt本身没有提供倒计时功能&#xff0c;想要实现这一目的&#xff0c;就得在现有的基础上安装倒计时插件。 ppt倒计时插件 目前可用的免费ppt倒计时…

如何判断全面预算和EPM软件架构是否符合技术规范?

以全面预算管理软件为代表的企业绩效管理EPM软件&#xff0c;已经日益成为企业数字化智慧化管理的核心软件系统。国际企业采用了30多年的EPM系统&#xff0c;也逐渐被国内企业所熟识。全面预算管理软件的作用不仅仅是预算编报&#xff0c;还是整个企业实现高效经营分析和快速决…

基于PCL实现RGB-D图像转换为点云

原理: RGB 和 depth图已经对齐了,也就是 depth 图中某个位置的深度值在 RGB图中同样的位置处就是它对应的颜色。假设相机内参矩阵为: 则RGB-D图像转换为点云代码如下: for (int m = 0; m < depth.rows; m++)for (int n = 0

英飞凌HSM内核开发-CSM模块配置

CsmGeneral CsmJob CsmKey CsmQueue CsmPrimitive

最新保姆级教程

如何使用 WildCard 服务注册 Claude3 随着 Claude3 的震撼发布&#xff0c;最强 AI 模型的桂冠已不再由 GPT-4 独揽。Claude3 推出了三个备受瞩目的模型&#xff1a;Claude 3 Haiku、Claude 3 Sonnet 以及 Claude 3 Opus&#xff0c;每个模型都展现了卓越的性能与特色。其中&a…

Python+Selenium 通过添加cookies或token解决网页上验证码登录问题

cookie或token可以保存登录信息&#xff0c;当我们拿到cookie后&#xff0c;可以通过向浏览器发送cookie中记录的数据&#xff0c;直接变成登录状态&#xff0c;不需要再登录。 下面举个栗子 1、先把正常的登录方式码一下&#xff1a; browser webdriver.Chrome(executable_…

颈动脉斑块的MR图像分割

颈动脉斑块的MR图像分割是一个复杂的图像处理过程&#xff0c;它结合了医学影像学和计算机视觉技术。以下是一个基于一般流程的描述&#xff0c;包括可能的步骤和示例代码&#xff08;使用Python和OpenCV库&#xff09;&#xff0c;但请注意&#xff0c;实际应用中可能需要针对…

心脑血管科曹启富主任医师:血压高降不下来?找准这三个方向真的降下来了

高血压&#xff0c;这一影响超过3亿国人健康的慢性病&#xff0c;常常让人倍感困扰。尽管在医生的指导下科学用药&#xff0c;并通过调整饮食和生活习惯&#xff0c;大多数患者都能将血压控制在适宜水平&#xff0c;但在日常生活中&#xff0c;我们仍可能遇到血压突然升高的情况…

NFV架构

1&#xff09;NFV的背景 来自IT界的启示&#xff0c;给网络产业带来了网络架构和设备架构两个层面的思考。网络架构层面引入对SDN控制器的思考&#xff0c;设备架构层面引入对设备部署形态的思考&#xff08;NFV&#xff09;。 网络功能虚拟化被称为NFV&#xff08;Network Fu…

9月新机首发:骁龙芯片+超大电池,游戏玩家的终极选择

随着秋风送爽的9月到来&#xff0c;智能手机和电子设备市场也迎来了新一轮的热潮。8月份的新机发布热潮刚刚退去&#xff0c;9月份的新机已经迫不及待地揭开了神秘的面纱。在众多备受期待的产品中&#xff0c;红魔品牌抢先官宣&#xff0c;两款全新的游戏平板将在9月5日正式亮相…

OV通配符证书具体申请流程

OV通配符HTTPS证书&#xff0c;也称为OV泛域名证书&#xff0c;是一种经过严格身份验证的证书类型&#xff0c;能够同时保护主域名以及主域名下所有二级子域名&#xff0c;为多个网站提供信息加密和身份认证服务。其申请过程相对于DV类型的证书会多几个步骤&#xff1a; 一、选…

“AIGC+开发安全”领域标杆厂商|海云安入选《2024网络安全十大创新方向》报告

近日&#xff0c;由国内信息安全领域知名权威媒体数说安全编写的《2024网络安全十大创新方向》报告&#xff08;以下简称“《报告》”&#xff09;正式发布。《报告》涵盖了一系列网络安全领域的前沿技术和新兴解决方案&#xff0c;针对每个创新方向进行了技术解读、核心能力、…

【Leetcode:2024. 考试的最大困扰度 + 滑动窗口】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…