micropython驱动ST7789v 2.4寸液晶显示中文

2023-11-15

一、ST7789v介绍

 ST7789v是小尺寸液晶中常用的驱动芯片,作者手里的是网上买的一块2.4寸液晶模组,接口

 为SPI接口。

网上能找到这个芯片的micropython驱动,这不是本文的重点。

本文的重点是如何利用这个驱动,并使用字库的方法来显示汉字。

我曾经有一篇文章,介绍如何使用unicode字模库在屏幕上显示汉字,如果你对这个方法还不是很了解,可以看一下我之前这篇文章。使用micropython(ESP8266、ESP32)驱动SES 2.66寸墨水屏显示中文_esp8266驱动墨水屏_f4t0x的博客-CSDN博客

二、st7789v原驱动

这个驱动可以在网上找到,我把源码贴下来。

"""
Copyright (c) 2020, 2021 Russ Hughes

This file incorporates work covered by the following copyright and
permission notice and is licensed under the same terms:

The MIT License (MIT)

Copyright (c) 2019 Ivan Belokobylskiy

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.

The driver is based on devbis' st7789py_mpy module from
https://github.com/devbis/st7789py_mpy.

This driver adds support for:

- 320x240, 240x240 and 135x240 pixel displays
- Display rotation
- Hardware based scrolling
- Drawing text using 8 and 16 bit wide bitmap fonts with heights that are
  multiples of 8.  Included are 12 bitmap fonts derived from classic pc
  BIOS text mode fonts.
- Drawing text using converted TrueType fonts.
- Drawing converted bitmaps

"""

import time
from micropython import const
import ustruct as struct

# commands
ST7789_NOP = const(0x00)
ST7789_SWRESET = const(0x01)
ST7789_RDDID = const(0x04)
ST7789_RDDST = const(0x09)

ST7789_SLPIN = const(0x10)
ST7789_SLPOUT = const(0x11)
ST7789_PTLON = const(0x12)
ST7789_NORON = const(0x13)

ST7789_INVOFF = const(0x20)
ST7789_INVON = const(0x21)
ST7789_DISPOFF = const(0x28)
ST7789_DISPON = const(0x29)
ST7789_CASET = const(0x2A)
ST7789_RASET = const(0x2B)
ST7789_RAMWR = const(0x2C)
ST7789_RAMRD = const(0x2E)

ST7789_PTLAR = const(0x30)
ST7789_VSCRDEF = const(0x33)
ST7789_COLMOD = const(0x3A)
ST7789_MADCTL = const(0x36)
ST7789_VSCSAD = const(0x37)

ST7789_MADCTL_MY = const(0x80)
ST7789_MADCTL_MX = const(0x40)
ST7789_MADCTL_MV = const(0x20)
ST7789_MADCTL_ML = const(0x10)
ST7789_MADCTL_BGR = const(0x08)
ST7789_MADCTL_MH = const(0x04)
ST7789_MADCTL_RGB = const(0x00)

ST7789_RDID1 = const(0xDA)
ST7789_RDID2 = const(0xDB)
ST7789_RDID3 = const(0xDC)
ST7789_RDID4 = const(0xDD)

COLOR_MODE_65K = const(0x50)
COLOR_MODE_262K = const(0x60)
COLOR_MODE_12BIT = const(0x03)
COLOR_MODE_16BIT = const(0x05)
COLOR_MODE_18BIT = const(0x06)
COLOR_MODE_16M = const(0x07)

# Color definitions
BLACK = const(0x0000)
BLUE = const(0x001F)
RED = const(0xF800)
GREEN = const(0x07E0)
CYAN = const(0x07FF)
MAGENTA = const(0xF81F)
YELLOW = const(0xFFE0)
WHITE = const(0xFFFF)

_ENCODE_PIXEL = ">H"
_ENCODE_POS = ">HH"
_DECODE_PIXEL = ">BBB"

_BUFFER_SIZE = const(256)

_BIT7 = const(0x80)
_BIT6 = const(0x40)
_BIT5 = const(0x20)
_BIT4 = const(0x10)
_BIT3 = const(0x08)
_BIT2 = const(0x04)
_BIT1 = const(0x02)
_BIT0 = const(0x01)

# Rotation tables (width, height, xstart, ystart)[rotation % 4]

WIDTH_320 = [(240, 320,  0,  0),
             (320, 240,  0,  0),
             (240, 320,  0,  0),
             (320, 240,  0,  0)]

WIDTH_240 = [(240, 240,  0,  0),
             (240, 240,  0,  0),
             (240, 240,  0, 80),
             (240, 240, 80,  0)]

WIDTH_135 = [(135, 240, 52, 40),
             (240, 135, 40, 53),
             (135, 240, 53, 40),
             (240, 135, 40, 52)]

# MADCTL ROTATIONS[rotation % 4]
ROTATIONS = [0x00, 0x60, 0xc0, 0xa0]


def color565(red, green=0, blue=0):
    """
    Convert red, green and blue values (0-255) into a 16-bit 565 encoding.
    """
    try:
        red, green, blue = red  # see if the first var is a tuple/list
    except TypeError:
        pass
    return (red & 0xf8) << 8 | (green & 0xfc) << 3 | blue >> 3


def _encode_pos(x, y):
    """Encode a postion into bytes."""
    return struct.pack(_ENCODE_POS, x, y)


def _encode_pixel(color):
    """Encode a pixel color into bytes."""
    return struct.pack(_ENCODE_PIXEL, color)


class ST7789():
    """
    ST7789 driver class

    Args:
        spi (spi): spi object **Required**
        width (int): display width **Required**
        height (int): display height **Required**
        reset (pin): reset pin
        dc (pin): dc pin **Required**
        cs (pin): cs pin
        backlight(pin): backlight pin
        rotation (int): display rotation
            - 0-Portrait
            - 1-Landscape
            - 2-Inverted Portrait
            - 3-Inverted Landscape
    """
    def __init__(self, spi, width, height, reset=None, dc=None,
                 cs=None, backlight=None, rotation=0):
        """
        Initialize display.
        """
        if height != 240 or width not in [320, 240, 135]:
            raise ValueError(
                "Unsupported display. 320x240, 240x240 and 135x240 are supported."
            )

        if dc is None:
            raise ValueError("dc pin is required.")

        self._display_width = self.width = width
        self._display_height = self.height = height
        self.xstart = 0
        self.ystart = 0
        self.spi = spi
        self.reset = reset
        self.dc = dc
        self.cs = cs
        self.backlight = backlight
        self._rotation = rotation % 4

        #self.hard_reset()
        #self.soft_reset()
        self.sleep_mode(False)

        self._set_color_mode(COLOR_MODE_65K | COLOR_MODE_16BIT)
        time.sleep_ms(50)
        self.rotation(self._rotation)
        self.inversion_mode(True)
        time.sleep_ms(10)
        self._write(ST7789_NORON)
        time.sleep_ms(10)
        if backlight is not None:
            backlight.value(1)
        self.fill(0)
        self._write(ST7789_DISPON)
        time.sleep_ms(500)

    def _write(self, command=None, data=None):
        """SPI write to the device: commands and data."""
        if self.cs:
            self.cs.off()

        if command is not None:
            self.dc.off()
            self.spi.write(bytes([command]))
        if data is not None:
            self.dc.on()
            self.spi.write(data)
            if self.cs:
                self.cs.on()

    def hard_reset(self):
        """
        Hard reset display.
        """
        if self.cs:
            self.cs.off()
        if self.reset:
            self.reset.on()
        time.sleep_ms(50)
        if self.reset:
            self.reset.off()
        time.sleep_ms(50)
        if self.reset:
            self.reset.on()
        time.sleep_ms(150)
        if self.cs:
            self.cs.on()

    def soft_reset(self):
        """
        Soft reset display.
        """
        self._write(ST7789_SWRESET)
        time.sleep_ms(150)

    def sleep_mode(self, value):
        """
        Enable or disable display sleep mode.

        Args:
            value (bool): if True enable sleep mode. if False disable sleep
            mode
        """
        if value:
            self._write(ST7789_SLPIN)
        else:
            self._write(ST7789_SLPOUT)

    def inversion_mode(self, value):
        """
        Enable or disable display inversion mode.

        Args:
            value (bool): if True enable inversion mode. if False disable
            inversion mode
        """
        if value:
            self._write(ST7789_INVON)
        else:
            self._write(ST7789_INVOFF)

    def _set_color_mode(self, mode):
        """
        Set display color mode.

        Args:
            mode (int): color mode
                COLOR_MODE_65K, COLOR_MODE_262K, COLOR_MODE_12BIT,
                COLOR_MODE_16BIT, COLOR_MODE_18BIT, COLOR_MODE_16M
        """
        self._write(ST7789_COLMOD, bytes([mode & 0x77]))

    def rotation(self, rotation):
        """
        Set display rotation.

        Args:
            rotation (int):
                - 0-Portrait
                - 1-Landscape
                - 2-Inverted Portrait
                - 3-Inverted Landscape
        """

        rotation %= 4
        self._rotation = rotation
        madctl = ROTATIONS[rotation]

        if self._display_width == 320:
            table = WIDTH_320
        elif self._display_width == 240:
            table = WIDTH_240
        elif self._display_width == 135:
            table = WIDTH_135
        else:
            raise ValueError(
                "Unsupported display. 320x240, 240x240 and 135x240 are supported."
            )

        self.width, self.height, self.xstart, self.ystart = table[rotation]
        self._write(ST7789_MADCTL, bytes([madctl]))

    def _set_columns(self, start, end):
        """
        Send CASET (column address set) command to display.

        Args:
            start (int): column start address
            end (int): column end address
        """
        if start <= end <= self.width:
            self._write(ST7789_CASET, _encode_pos(
                start+self.xstart, end + self.xstart))

    def _set_rows(self, start, end):
        """
        Send RASET (row address set) command to display.

        Args:
            start (int): row start address
            end (int): row end address
       """
        if start <= end <= self.height:
            self._write(ST7789_RASET, _encode_pos(
                start+self.ystart, end+self.ystart))

    def _set_window(self, x0, y0, x1, y1):
        """
        Set window to column and row address.

        Args:
            x0 (int): column start address
            y0 (int): row start address
            x1 (int): column end address
            y1 (int): row end address
        """
        self._set_columns(x0, x1)
        self._set_rows(y0, y1)
        self._write(ST7789_RAMWR)

    def vline(self, x, y, length, color):
        """
        Draw vertical line at the given location and color.

        Args:
            x (int): x coordinate
            Y (int): y coordinate
            length (int): length of line
            color (int): 565 encoded color
        """
        self.fill_rect(x, y, 1, length, color)

    def hline(self, x, y, length, color):
        """
        Draw horizontal line at the given location and color.

        Args:
            x (int): x coordinate
            Y (int): y coordinate
            length (int): length of line
            color (int): 565 encoded color
        """
        self.fill_rect(x, y, length, 1, color)

    def pixel(self, x, y, color):
        """
        Draw a pixel at the given location and color.

        Args:
            x (int): x coordinate
            Y (int): y coordinate
            color (int): 565 encoded color
        """
        self._set_window(x, y, x, y)
        self._write(None, _encode_pixel(color))

    def blit_buffer(self, buffer, x, y, width, height):
        """
        Copy buffer to display at the given location.

        Args:
            buffer (bytes): Data to copy to display
            x (int): Top left corner x coordinate
            Y (int): Top left corner y coordinate
            width (int): Width
            height (int): Height
        """
        self._set_window(x, y, x + width - 1, y + height - 1)
        self._write(None, buffer)

    def rect(self, x, y, w, h, color):
        """
        Draw a rectangle at the given location, size and color.

        Args:
            x (int): Top left corner x coordinate
            y (int): Top left corner y coordinate
            width (int): Width in pixels
            height (int): Height in pixels
            color (int): 565 encoded color
        """
        self.hline(x, y, w, color)
        self.vline(x, y, h, color)
        self.vline(x + w - 1, y, h, color)
        self.hline(x, y + h - 1, w, color)

    def fill_rect(self, x, y, width, height, color):
        """
        Draw a rectangle at the given location, size and filled with color.

        Args:
            x (int): Top left corner x coordinate
            y (int): Top left corner y coordinate
            width (int): Width in pixels
            height (int): Height in pixels
            color (int): 565 encoded color
        """
        self._set_window(x, y, x + width - 1, y + height - 1)
        chunks, rest = divmod(width * height, _BUFFER_SIZE)
        pixel = _encode_pixel(color)
        self.dc.on()
        if chunks:
            data = pixel * _BUFFER_SIZE
            for _ in range(chunks):
                self._write(None, data)
        if rest:
            self._write(None, pixel * rest)

    def fill(self, color):
        """
        Fill the entire FrameBuffer with the specified color.

        Args:
            color (int): 565 encoded color
        """
        self.fill_rect(0, 0, self.width, self.height, color)

    def line(self, x0, y0, x1, y1, color):
        """
        Draw a single pixel wide line starting at x0, y0 and ending at x1, y1.

        Args:
            x0 (int): Start point x coordinate
            y0 (int): Start point y coordinate
            x1 (int): End point x coordinate
            y1 (int): End point y coordinate
            color (int): 565 encoded color
        """
        steep = abs(y1 - y0) > abs(x1 - x0)
        if steep:
            x0, y0 = y0, x0
            x1, y1 = y1, x1
        if x0 > x1:
            x0, x1 = x1, x0
            y0, y1 = y1, y0
        dx = x1 - x0
        dy = abs(y1 - y0)
        err = dx // 2
        ystep = 1 if y0 < y1 else -1
        while x0 <= x1:
            if steep:
                self.pixel(y0, x0, color)
            else:
                self.pixel(x0, y0, color)
            err -= dy
            if err < 0:
                y0 += ystep
                err += dx
            x0 += 1

    def vscrdef(self, tfa, vsa, bfa):
        """
        Set Vertical Scrolling Definition.

        To scroll a 135x240 display these values should be 40, 240, 40.
        There are 40 lines above the display that are not shown followed by
        240 lines that are shown followed by 40 more lines that are not shown.
        You could write to these areas off display and scroll them into view by
        changing the TFA, VSA and BFA values.

        Args:
            tfa (int): Top Fixed Area
            vsa (int): Vertical Scrolling Area
            bfa (int): Bottom Fixed Area
        """
        struct.pack(">HHH", tfa, vsa, bfa)
        self._write(ST7789_VSCRDEF, struct.pack(">HHH", tfa, vsa, bfa))

    def vscsad(self, vssa):
        """
        Set Vertical Scroll Start Address of RAM.

        Defines which line in the Frame Memory will be written as the first
        line after the last line of the Top Fixed Area on the display

        Example:

            for line in range(40, 280, 1):
                tft.vscsad(line)
                utime.sleep(0.01)

        Args:
            vssa (int): Vertical Scrolling Start Address

        """
        self._write(ST7789_VSCSAD, struct.pack(">H", vssa))

    def _text8(self, font, text, x0, y0, color=WHITE, background=BLACK):
        """
        Internal method to write characters with width of 8 and
        heights of 8 or 16.

        Args:
            font (module): font module to use
            text (str): text to write
            x0 (int): column to start drawing at
            y0 (int): row to start drawing at
            color (int): 565 encoded color to use for characters
            background (int): 565 encoded color to use for background
        """
        for char in text:
            ch = ord(char)
            if (font.FIRST <= ch < font.LAST
                    and x0+font.WIDTH <= self.width
                    and y0+font.HEIGHT <= self.height):

                if font.HEIGHT == 8:
                    passes = 1
                    size = 8
                    each = 0
                else:
                    passes = 2
                    size = 16
                    each = 8

                for line in range(passes):
                    idx = (ch-font.FIRST)*size+(each*line)
                    buffer = struct.pack(
                        '>64H',
                        color if font.FONT[idx] & _BIT7 else background,
                        color if font.FONT[idx] & _BIT6 else background,
                        color if font.FONT[idx] & _BIT5 else background,
                        color if font.FONT[idx] & _BIT4 else background,
                        color if font.FONT[idx] & _BIT3 else background,
                        color if font.FONT[idx] & _BIT2 else background,
                        color if font.FONT[idx] & _BIT1 else background,
                        color if font.FONT[idx] & _BIT0 else background,
                        color if font.FONT[idx+1] & _BIT7 else background,
                        color if font.FONT[idx+1] & _BIT6 else background,
                        color if font.FONT[idx+1] & _BIT5 else background,
                        color if font.FONT[idx+1] & _BIT4 else background,
                        color if font.FONT[idx+1] & _BIT3 else background,
                        color if font.FONT[idx+1] & _BIT2 else background,
                        color if font.FONT[idx+1] & _BIT1 else background,
                        color if font.FONT[idx+1] & _BIT0 else background,
                        color if font.FONT[idx+2] & _BIT7 else background,
                        color if font.FONT[idx+2] & _BIT6 else background,
                        color if font.FONT[idx+2] & _BIT5 else background,
                        color if font.FONT[idx+2] & _BIT4 else background,
                        color if font.FONT[idx+2] & _BIT3 else background,
                        color if font.FONT[idx+2] & _BIT2 else background,
                        color if font.FONT[idx+2] & _BIT1 else background,
                        color if font.FONT[idx+2] & _BIT0 else background,
                        color if font.FONT[idx+3] & _BIT7 else background,
                        color if font.FONT[idx+3] & _BIT6 else background,
                        color if font.FONT[idx+3] & _BIT5 else background,
                        color if font.FONT[idx+3] & _BIT4 else background,
                        color if font.FONT[idx+3] & _BIT3 else background,
                        color if font.FONT[idx+3] & _BIT2 else background,
                        color if font.FONT[idx+3] & _BIT1 else background,
                        color if font.FONT[idx+3] & _BIT0 else background,
                        color if font.FONT[idx+4] & _BIT7 else background,
                        color if font.FONT[idx+4] & _BIT6 else background,
                        color if font.FONT[idx+4] & _BIT5 else background,
                        color if font.FONT[idx+4] & _BIT4 else background,
                        color if font.FONT[idx+4] & _BIT3 else background,
                        color if font.FONT[idx+4] & _BIT2 else background,
                        color if font.FONT[idx+4] & _BIT1 else background,
                        color if font.FONT[idx+4] & _BIT0 else background,
                        color if font.FONT[idx+5] & _BIT7 else background,
                        color if font.FONT[idx+5] & _BIT6 else background,
                        color if font.FONT[idx+5] & _BIT5 else background,
                        color if font.FONT[idx+5] & _BIT4 else background,
                        color if font.FONT[idx+5] & _BIT3 else background,
                        color if font.FONT[idx+5] & _BIT2 else background,
                        color if font.FONT[idx+5] & _BIT1 else background,
                        color if font.FONT[idx+5] & _BIT0 else background,
                        color if font.FONT[idx+6] & _BIT7 else background,
                        color if font.FONT[idx+6] & _BIT6 else background,
                        color if font.FONT[idx+6] & _BIT5 else background,
                        color if font.FONT[idx+6] & _BIT4 else background,
                        color if font.FONT[idx+6] & _BIT3 else background,
                        color if font.FONT[idx+6] & _BIT2 else background,
                        color if font.FONT[idx+6] & _BIT1 else background,
                        color if font.FONT[idx+6] & _BIT0 else background,
                        color if font.FONT[idx+7] & _BIT7 else background,
                        color if font.FONT[idx+7] & _BIT6 else background,
                        color if font.FONT[idx+7] & _BIT5 else background,
                        color if font.FONT[idx+7] & _BIT4 else background,
                        color if font.FONT[idx+7] & _BIT3 else background,
                        color if font.FONT[idx+7] & _BIT2 else background,
                        color if font.FONT[idx+7] & _BIT1 else background,
                        color if font.FONT[idx+7] & _BIT0 else background
                    )
                    self.blit_buffer(buffer, x0, y0+8*line, 8, 8)

                x0 += 8

    def _text16(self, font, text, x0, y0, color=WHITE, background=BLACK):
        """
        Internal method to draw characters with width of 16 and heights of 16
        or 32.

        Args:
            font (module): font module to use
            text (str): text to write
            x0 (int): column to start drawing at
            y0 (int): row to start drawing at
            color (int): 565 encoded color to use for characters
            background (int): 565 encoded color to use for background
        """
        for char in text:
            ch = ord(char)
            if (font.FIRST <= ch < font.LAST
                    and x0+font.WIDTH <= self.width
                    and y0+font.HEIGHT <= self.height):

                each = 16
                if font.HEIGHT == 16:
                    passes = 2
                    size = 32
                else:
                    passes = 4
                    size = 64

                for line in range(passes):
                    idx = (ch-font.FIRST)*size+(each*line)
                    buffer = struct.pack(
                        '>128H',
                        color if font.FONT[idx] & _BIT7 else background,
                        color if font.FONT[idx] & _BIT6 else background,
                        color if font.FONT[idx] & _BIT5 else background,
                        color if font.FONT[idx] & _BIT4 else background,
                        color if font.FONT[idx] & _BIT3 else background,
                        color if font.FONT[idx] & _BIT2 else background,
                        color if font.FONT[idx] & _BIT1 else background,
                        color if font.FONT[idx] & _BIT0 else background,
                        color if font.FONT[idx+1] & _BIT7 else background,
                        color if font.FONT[idx+1] & _BIT6 else background,
                        color if font.FONT[idx+1] & _BIT5 else background,
                        color if font.FONT[idx+1] & _BIT4 else background,
                        color if font.FONT[idx+1] & _BIT3 else background,
                        color if font.FONT[idx+1] & _BIT2 else background,
                        color if font.FONT[idx+1] & _BIT1 else background,
                        color if font.FONT[idx+1] & _BIT0 else background,
                        color if font.FONT[idx+2] & _BIT7 else background,
                        color if font.FONT[idx+2] & _BIT6 else background,
                        color if font.FONT[idx+2] & _BIT5 else background,
                        color if font.FONT[idx+2] & _BIT4 else background,
                        color if font.FONT[idx+2] & _BIT3 else background,
                        color if font.FONT[idx+2] & _BIT2 else background,
                        color if font.FONT[idx+2] & _BIT1 else background,
                        color if font.FONT[idx+2] & _BIT0 else background,
                        color if font.FONT[idx+3] & _BIT7 else background,
                        color if font.FONT[idx+3] & _BIT6 else background,
                        color if font.FONT[idx+3] & _BIT5 else background,
                        color if font.FONT[idx+3] & _BIT4 else background,
                        color if font.FONT[idx+3] & _BIT3 else background,
                        color if font.FONT[idx+3] & _BIT2 else background,
                        color if font.FONT[idx+3] & _BIT1 else background,
                        color if font.FONT[idx+3] & _BIT0 else background,
                        color if font.FONT[idx+4] & _BIT7 else background,
                        color if font.FONT[idx+4] & _BIT6 else background,
                        color if font.FONT[idx+4] & _BIT5 else background,
                        color if font.FONT[idx+4] & _BIT4 else background,
                        color if font.FONT[idx+4] & _BIT3 else background,
                        color if font.FONT[idx+4] & _BIT2 else background,
                        color if font.FONT[idx+4] & _BIT1 else background,
                        color if font.FONT[idx+4] & _BIT0 else background,
                        color if font.FONT[idx+5] & _BIT7 else background,
                        color if font.FONT[idx+5] & _BIT6 else background,
                        color if font.FONT[idx+5] & _BIT5 else background,
                        color if font.FONT[idx+5] & _BIT4 else background,
                        color if font.FONT[idx+5] & _BIT3 else background,
                        color if font.FONT[idx+5] & _BIT2 else background,
                        color if font.FONT[idx+5] & _BIT1 else background,
                        color if font.FONT[idx+5] & _BIT0 else background,
                        color if font.FONT[idx+6] & _BIT7 else background,
                        color if font.FONT[idx+6] & _BIT6 else background,
                        color if font.FONT[idx+6] & _BIT5 else background,
                        color if font.FONT[idx+6] & _BIT4 else background,
                        color if font.FONT[idx+6] & _BIT3 else background,
                        color if font.FONT[idx+6] & _BIT2 else background,
                        color if font.FONT[idx+6] & _BIT1 else background,
                        color if font.FONT[idx+6] & _BIT0 else background,
                        color if font.FONT[idx+7] & _BIT7 else background,
                        color if font.FONT[idx+7] & _BIT6 else background,
                        color if font.FONT[idx+7] & _BIT5 else background,
                        color if font.FONT[idx+7] & _BIT4 else background,
                        color if font.FONT[idx+7] & _BIT3 else background,
                        color if font.FONT[idx+7] & _BIT2 else background,
                        color if font.FONT[idx+7] & _BIT1 else background,
                        color if font.FONT[idx+7] & _BIT0 else background,
                        color if font.FONT[idx+8] & _BIT7 else background,
                        color if font.FONT[idx+8] & _BIT6 else background,
                        color if font.FONT[idx+8] & _BIT5 else background,
                        color if font.FONT[idx+8] & _BIT4 else background,
                        color if font.FONT[idx+8] & _BIT3 else background,
                        color if font.FONT[idx+8] & _BIT2 else background,
                        color if font.FONT[idx+8] & _BIT1 else background,
                        color if font.FONT[idx+8] & _BIT0 else background,
                        color if font.FONT[idx+9] & _BIT7 else background,
                        color if font.FONT[idx+9] & _BIT6 else background,
                        color if font.FONT[idx+9] & _BIT5 else background,
                        color if font.FONT[idx+9] & _BIT4 else background,
                        color if font.FONT[idx+9] & _BIT3 else background,
                        color if font.FONT[idx+9] & _BIT2 else background,
                        color if font.FONT[idx+9] & _BIT1 else background,
                        color if font.FONT[idx+9] & _BIT0 else background,
                        color if font.FONT[idx+10] & _BIT7 else background,
                        color if font.FONT[idx+10] & _BIT6 else background,
                        color if font.FONT[idx+10] & _BIT5 else background,
                        color if font.FONT[idx+10] & _BIT4 else background,
                        color if font.FONT[idx+10] & _BIT3 else background,
                        color if font.FONT[idx+10] & _BIT2 else background,
                        color if font.FONT[idx+10] & _BIT1 else background,
                        color if font.FONT[idx+10] & _BIT0 else background,
                        color if font.FONT[idx+11] & _BIT7 else background,
                        color if font.FONT[idx+11] & _BIT6 else background,
                        color if font.FONT[idx+11] & _BIT5 else background,
                        color if font.FONT[idx+11] & _BIT4 else background,
                        color if font.FONT[idx+11] & _BIT3 else background,
                        color if font.FONT[idx+11] & _BIT2 else background,
                        color if font.FONT[idx+11] & _BIT1 else background,
                        color if font.FONT[idx+11] & _BIT0 else background,
                        color if font.FONT[idx+12] & _BIT7 else background,
                        color if font.FONT[idx+12] & _BIT6 else background,
                        color if font.FONT[idx+12] & _BIT5 else background,
                        color if font.FONT[idx+12] & _BIT4 else background,
                        color if font.FONT[idx+12] & _BIT3 else background,
                        color if font.FONT[idx+12] & _BIT2 else background,
                        color if font.FONT[idx+12] & _BIT1 else background,
                        color if font.FONT[idx+12] & _BIT0 else background,
                        color if font.FONT[idx+13] & _BIT7 else background,
                        color if font.FONT[idx+13] & _BIT6 else background,
                        color if font.FONT[idx+13] & _BIT5 else background,
                        color if font.FONT[idx+13] & _BIT4 else background,
                        color if font.FONT[idx+13] & _BIT3 else background,
                        color if font.FONT[idx+13] & _BIT2 else background,
                        color if font.FONT[idx+13] & _BIT1 else background,
                        color if font.FONT[idx+13] & _BIT0 else background,
                        color if font.FONT[idx+14] & _BIT7 else background,
                        color if font.FONT[idx+14] & _BIT6 else background,
                        color if font.FONT[idx+14] & _BIT5 else background,
                        color if font.FONT[idx+14] & _BIT4 else background,
                        color if font.FONT[idx+14] & _BIT3 else background,
                        color if font.FONT[idx+14] & _BIT2 else background,
                        color if font.FONT[idx+14] & _BIT1 else background,
                        color if font.FONT[idx+14] & _BIT0 else background,
                        color if font.FONT[idx+15] & _BIT7 else background,
                        color if font.FONT[idx+15] & _BIT6 else background,
                        color if font.FONT[idx+15] & _BIT5 else background,
                        color if font.FONT[idx+15] & _BIT4 else background,
                        color if font.FONT[idx+15] & _BIT3 else background,
                        color if font.FONT[idx+15] & _BIT2 else background,
                        color if font.FONT[idx+15] & _BIT1 else background,
                        color if font.FONT[idx+15] & _BIT0 else background
                    )
                    self.blit_buffer(buffer, x0, y0+8*line, 16, 8)
            x0 += font.WIDTH

    def text(self, font, text, x0, y0, color=WHITE, background=BLACK):
        """
        Draw text on display in specified font and colors. 8 and 16 bit wide
        fonts are supported.

        Args:
            font (module): font module to use.
            text (str): text to write
            x0 (int): column to start drawing at
            y0 (int): row to start drawing at
            color (int): 565 encoded color to use for characters
            background (int): 565 encoded color to use for background
        """
        if font.WIDTH == 8:
            self._text8(font, text, x0, y0, color, background)
        else:
            self._text16(font, text, x0, y0, color, background)

    def bitmap(self, bitmap, x, y, index=0):
        """
        Draw a bitmap on display at the specified column and row

        Args:
            bitmap (bitmap_module): The module containing the bitmap to draw
            x (int): column to start drawing at
            y (int): row to start drawing at
            index (int): Optional index of bitmap to draw from multiple bitmap
                module

        """
        bitmap_size = bitmap.HEIGHT * bitmap.WIDTH
        buffer_len = bitmap_size * 2
        buffer = bytearray(buffer_len)
        bs_bit = bitmap.BPP * bitmap_size * index if index > 0 else 0

        for i in range(0, buffer_len, 2):
            color_index = 0
            for _ in range(bitmap.BPP):
                color_index <<= 1
                color_index |= (bitmap.BITMAP[bs_bit // 8]
                                & 1 << (7 - (bs_bit % 8))) > 0
                bs_bit += 1

            color = bitmap.PALETTE[color_index]
            buffer[i] = color & 0xff00 >> 8
            buffer[i + 1] = color_index & 0xff

        to_col = x + bitmap.WIDTH - 1
        to_row = y + bitmap.HEIGHT - 1
        if self.width > to_col and self.height > to_row:
            self._set_window(x, y, to_col, to_row)
            self._write(None, buffer)

    # @micropython.native
    def write(self, font, string, x, y, fg=WHITE, bg=BLACK):
        """
        Write a string using a converted true-type font on the display starting
        at the specified column and row

        Args:
            font (font): The module containing the converted true-type font
            s (string): The string to write
            x (int): column to start writing
            y (int): row to start writing
            fg (int): foreground color, optional, defaults to WHITE
            bg (int): background color, optional, defaults to BLACK
        """
        buffer_len = font.HEIGHT * font.MAX_WIDTH * 2
        buffer = bytearray(buffer_len)
        fg_hi = (fg & 0xff00) >> 8
        fg_lo = fg & 0xff

        bg_hi = (bg & 0xff00) >> 8
        bg_lo = bg & 0xff

        for character in string:
            try:
                char_index = font.MAP.index(character)
                offset = char_index * font.OFFSET_WIDTH
                bs_bit = font.OFFSETS[offset]
                if font.OFFSET_WIDTH > 1:
                    bs_bit = (bs_bit << 8) + font.OFFSETS[offset + 1]

                if font.OFFSET_WIDTH > 2:
                    bs_bit = (bs_bit << 8) + font.OFFSETS[offset + 2]

                char_width = font.WIDTHS[char_index]
                buffer_needed = char_width * font.HEIGHT * 2

                for i in range(0, buffer_needed, 2):
                    if font.BITMAPS[bs_bit // 8] & 1 << (7 - (bs_bit % 8)) > 0:
                        buffer[i] = fg_hi
                        buffer[i + 1] = fg_lo
                    else:
                        buffer[i] = bg_hi
                        buffer[i + 1] = bg_lo

                    bs_bit += 1

                to_col = x + char_width - 1
                to_row = y + font.HEIGHT - 1
                if self.width > to_col and self.height > to_row:
                    self._set_window(x, y, to_col, to_row)
                    self._write(None, buffer[:buffer_needed])

                x += char_width

            except ValueError:
                pass

    def write_width(self, font, string):
        """
        Returns the width in pixels of the string if it was written with the
        specified font

        Args:
            font (font): The module containing the converted true-type font
            string (string): The string to measure
        """
        width = 0
        for character in string:
            try:
                char_index = font.MAP.index(character)
                width += font.WIDTHS[char_index]

            except ValueError:
                pass

        return width

其中,st7789.text()方法就是显示ASCII字符了,你可能也发现了,遗憾的是,这个驱动只支持8*8和16*16的字符,并且不支持中文。

下面我们在这个驱动下面增加中文字符显示功能。

三、中文显示

如我之前那篇文章所述,显示中文得有字模库,取到字模库中要显示得汉字字模后,采用blit的方法显示出来。

我们注意到,前面那个驱动里,也正好有blit这个方法。

1.取字模库

依然采用前述那篇文章中的软件,提取unicode字模库。

要注意的是,为了编程方便,我们把unicode从0x0000-0xFFFF全部取出来,我用的SD卡存储字模库,所以没那么在乎存储空间的问题,如果你在意的话,只取中文部分0x4E00开始也没问题,只需在取到中文unicode码之后减掉0x4E00再去fileseek()即可。

这个是取模软件截图。

 取好字模库后,保存到flash或SD卡备用。

2.处理字模库

关于这一步,其实开始我也是不知道的,因为取模直接显示出来的中文字符出现了问题:

字符左右半边各自镜像于正常字符。比如下边这个“辉”字,中间为界,左半边和右半边各自左右翻转了。

 显示成了:

 不难看出,是取模方式的问题。横向取模是对的,但是每个字节高低位是反的。图中的字节H和L是反的,但是取模软件横向取模只有这一种方式,没有其他方式可选,那就只能自己处理下字模文件了。

 

 所以就有了下面这个小程序(随手写的,有些逻辑问题,不影响结果):

取模完成后,用程序把字模文件的每个字节高低顺序对调。
f=open('e:/fonts-unicode(0000-00FF)-w16-h32-b24.dzk','rb')
f1=open('e:/fonts-unicode(0000-00FF)-w16-h32-b24-inv8.dzk','wb')
buff=f.read(1)
a=buff[0]
cnt=0
writeBuff=bytearray(1)

while buff is not None:
    b=0x00
    #print("a=",a)
    for i in range(8):  
        b=(b&0xfe) | (0x01 & a)
        if i<7:
            b=b<<1
            a=a>>1
    #print("b=",b)
    writeBuff[0]=b
    f1.write(writeBuff)
    cnt+=1
    #print("cnt=",cnt)
    try:
        buff=f.read(1)
        a=buff[0]
    except:
        break
print("cnt=",cnt)
f1.flush()
f.close()
f1.close()

print("done")

 处理完成后的字模库文件终于可以用了。

3.显示中文

经过一番准备,终于可以干正事了。

ST7789v液晶屏幕上,一个像素点需要使用2个字节来表示该点的颜色,即RGB565,毕竟是彩色屏幕嘛。

 我们在字模库中取出的字模,实际是黑白像素字模,一个位对应一个像素点。这就需要我们做一个转换。字模库中取出一个位,我们判断是1的话,就用文字颜色(RGB565的2个字节)填充;如果是0的话,就用背景色填充。

原理清楚了,就可以直接上代码了。

注意程序中对中文字符和ASCII字符做了区别处理。这是因为在同等高度,比如都是high=32的情况下,ASCII字符不需要占用到32,只需要16就可以了,否则ASCII字符就周围空白很多就不好看了。所以中文字符和ASCII字符用了不同的字模库。

这段程序支持16和32两种字符。

encode_get_utf8_size和encode_utf8_to_unicode是用来把中文转为unicode编码的,之前那篇文章提到过。

    
    def stringCN(self,string, x0, y0, high=32,color=WHITE, background=BLACK):
        import gc
        gc.collect()
        high=high
        if high==16:
            fontFileCN=open('/sd/fonts-unicode(0000-FFFF)-w16-h16-b12-inv8.dzk','rb')
            fontFileEN=open('/sd/fonts-unicode(0000-00FF)-w8-h16-b12-inv8.dzk','rb')
            widthCN=16
            widthEN=8
        elif high==32:
            fontFileCN=open('/sd/fonts-unicode(0000-FFFF)-w32-h32-b24.dzk','rb')
            fontFileEN=open('/sd/fonts-unicode(0000-00FF)-w16-h32-b24-inv8.dzk','rb')
            widthCN=32
            widthEN=16
        else:
            print("unsupported font!")
            return
        
        #输入字符串长度,即字符数,一个中文/英文字符均算作1个
        i=0#i是string通过string=bytes(string,'utf-8')转换成字节串之后在每个循环中处理的位置
        scrPos=0#要显示的某个字符在屏幕X轴方向的位置
        string=bytes(string,'utf-8')
        #此时string的len已经和输入参数中的len不一样了,因为中文在输入时len为1,转换后len为3
        while i<len(string):
            utfbytes=self.encode_get_utf8_size(string[i])#单个字符的所占字节数,一般英文为1,中文为3
            #print(i,string[i],utfbytes,string[i:i+utfbytes])
            tmp=self.encode_utf8_to_unicode(string[i:i+utfbytes])#字符转码为unicode编码,0x0000~0xffff,常用中文在0x4e00~0x9fff,英文在0x0000~0x00ff
            #print(type(tmp),tmp)
            i+=utfbytes
            if utfbytes==1:
                width=widthEN
                fontFile=fontFileEN
            elif utfbytes==3:
                width=widthCN
                fontFile=fontFileCN
            else:
                print("utfbytes error,utfbytes=",utfbytes)
                return

            fontFile.seek(tmp*int(high*width/8))
            zimo=fontFile.read(int(high*width/8))
            buffer=bytearray(0)
            for pixByteIndex in range(int(high*width/8)):
                #print(pixByteIndex)
                for bitCounter in range(8):
                    #print(bitCounter)
                    #RGB565,一个像素点2字节,如果字模中像素点为0,就填充背景色,为1就填充color色
                    if (zimo[pixByteIndex] & 0x01<<bitCounter):
                        buffer.append(~((color&0xff00)>>8))
                        buffer.append(~(color&0x00ff))
                    else:
                        buffer.append(~((background & 0xff00)>>8))
                        buffer.append(~(background & 0x00ff))
            self.blit_buffer(buffer, x0+scrPos, y0, width=width, height=high)
            scrPos+=width
            
            
    def encode_get_utf8_size(self,utf):
        if utf < 0x80:
            return 1
        if utf >= 0x80 and utf < 0xC0:
            return -1
        if utf >= 0xC0 and utf < 0xE0:
            return 2
        if utf >= 0xE0 and utf < 0xF0:
            return 3
        if utf >= 0xF0 and utf < 0xF8:
            return 4
        if utf >= 0xF8 and utf < 0xFC:
            return 5
        if utf >= 0xFC:
            return 6

    def encode_utf8_to_unicode(self,utf8):
        utfbytes = self.encode_get_utf8_size(utf8[0])
        if utfbytes == 1:
            unic = utf8[0]
        if utfbytes == 2:
            b1 = utf8[0]
            b2 = utf8[1]
            if ((b2 & 0xE0) != 0x80):
                return -1
            unic = ((((b1 << 6) + (b2 & 0x3F)) & 0xFF) << 8) | (((b1 >> 2) & 0x07) & 0xFF)
        if utfbytes == 3:
            b1 = utf8[0]
            b2 = utf8[1]
            b3 = utf8[2]
            if (((b2 & 0xC0) != 0x80) or ((b3 & 0xC0) != 0x80)):
                return -1
            unic = ((((b1 << 4) + ((b2 >> 2) & 0x0F)) & 0xFF) << 8) | (((b2 << 6) + (b3 & 0x3F)) & 0xFF)

        if utfbytes == 4:
            b1 = utf8[0]
            b2 = utf8[1]
            b3 = utf8[2]
            b4 = utf8[3]
            if (((b2 & 0xC0) != 0x80) or ((b3 & 0xC0) != 0x80) or ((b4 & 0xC0) != 0x80)):
                return -1
            unic = ((((b3 << 6) + (b4 & 0x3F)) & 0xFF) << 16) | ((((b2 << 4) + ((b3 >> 2)
                                                                      & 0x0F)) & 0xFF) << 8) | ((((b1 << 2) & 0x1C) + ((b2 >> 4) & 0x03)) & 0xFF)
        if utfbytes == 5:
            b1 = utf8[0]
            b2 = utf8[1]
            b3 = utf8[2]
            b4 = utf8[3]
            b5 = utf8[4]
            if (((b2 & 0xC0) != 0x80) or ((b3 & 0xC0) != 0x80) or ((b4 & 0xC0) != 0x80) or ((b5 & 0xC0) != 0x80)):
                return -1
            unic = ((((b4 << 6) + (b5 & 0x3F)) & 0xFF) << 24) | (((b3 << 4) + ((b4 >> 2) & 0x0F) & 0xFF) << 16) | ((((b2 << 2) + ((b3 >> 4) & 0x03)) & 0xFF) << 8) | (((b1 << 6)) & 0xFF)
        if utfbytes == 6:
            b1 = utf8[0]
            b2 = utf8[1]
            b3 = utf8[2]
            b4 = utf8[3]
            b5 = utf8[4]
            b6 = utf8[5]

            if (((b2 & 0xC0) != 0x80) or ((b3 & 0xC0) != 0x80) or ((b4 & 0xC0) != 0x80) or ((b5 & 0xC0) != 0x80) or ((b6 & 0xC0) != 0x80)):
                return -1

            unic = ((((b5 << 6) + (b6 & 0x3F)) << 24) & 0xFF) | (((b5 << 4) + ((b6 >> 2) & 0x0F) << 16) & 0xFF) | ((((b3 << 2) + ((b4 >> 4) & 0x03)) << 8) & 0xFF) | ((((b1 << 6) & 0x40) + (b2 & 0x3F)) & 0xFF)

        return unic

OK,最终显示效果:

最后说一句,原驱动程序中使用了大量color if font.FONT[idx] & _BITx else background这种语句,个人感觉太笨重了,可以优化成循环语句,不过我也懒得去修改了。

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

micropython驱动ST7789v 2.4寸液晶显示中文 的相关文章

  • 当默认 pip 为 pip2 时,升级 pip3 的正确格式是什么?

    我为两者开发Python 2 and 3 因此 我必须同时使用pip2 and pip3 使用时pip3 我收到此升级请求 最后两行 pip3 install arrow Requirement already satisfied use
  • 用于查找列表/集合中唯一元素的代码

    根据上面阴影部分的面积应该代表 A XOR B XOR C XOR A AND B AND C 如何将其翻译成Python代码 代码必须与上述表达式中提供的集合操作密切相关 至少这是首选 该代码必须足够通用 能够处理 3 个以上的列表 UP
  • Python 异常 - args 属性如何自动设置?

    假设我定义了以下异常 gt gt gt class MyError Exception def init self arg1 pass 然后我实例化该类以创建异常对象 gt gt gt e MyError abc gt gt gt e ar
  • 管理 Tweepy API 搜索

    如果这是对之前在其他地方回答过的问题的粗略重复 请原谅我 但我不知道如何使用 tweepy API 搜索功能 是否有任何有关如何使用搜索推文的文档api search 功能 有什么方法可以控制返回的推文数量 结果类型等功能 由于某种原因 结
  • 如何使 Django ManyToMany “直通”查询更加高效?

    我使用的是 ManyToManyField 和 through 类 这会在获取事物列表时产生大量查询 我想知道是否有更有效的方法 例如 这里有一些描述书籍及其几位作者的简化类 它们通过角色类 定义 编辑器 插画家 等角色 class Per
  • 查找 python 数据框中每行的最高值

    我想找到每行中的最高值并返回 python 中该值的列标题 例如 我想找到每行的前两个 df A B C D 5 9 8 2 4 1 2 3 我希望我的输出看起来像这样 df B C A D 您可以使用字典理解来生成largest n数据帧
  • Python Pandas 从宽到长的格式更改以及列标题拆分

    我有一个包含以下列标题和行示例的表 Subject Test1 Result1 Test1 Result2 Test2 Result1 Test2 Result2 0 John 10 0 5 20 0 3 我想将其改造成 Subject l
  • 如何使用 boto3 从 AWS Cognito 获取经过身份验证的身份响应

    我想使用 boto3 获取访问 AWS 服务的临时凭证 用例是这样的 我的 Cognito 用户池中的用户登录到我的服务器 我希望服务器代码为该用户提供访问其他 AWS 服务的临时凭证 我有一个存储我的用户的 Cognito 用户池 我有一
  • 检查多维 numpy 数组的所有边是否都是零数组

    n 维数组有 2n 个边 1 维数组有 2 个端点 2 维数组有 4 个边或边 3 维数组有 6 个 2 维面 4 维数组有 8 个边 ETC 这类似于抽象 n 维立方体发生的情况 我想检查 n 维数组的所有边是否仅由零组成 以下是边由零组
  • Highcharts 奇怪的分组行为

    我正在使用延迟加载 http www highcharts com stock demo lazy loading加载 OHLC 数据的方法 在服务器端 我使用 Python MySQL 并有 4 个包含 OHLC 数据的表 时间间隔为 5
  • 将分布拟合到直方图

    I want to know the distribution of my data points so first I plotted the histogram of my data My histogram looks like th
  • Python代码执行时自动打开浏览器

    我正在 Python Flask 中实现 GUI Flask 的设计方式是 必须 手动 打开本地主机以及端口号 有没有一种方法可以使其自动化 以便在运行代码时自动打开浏览器 本地主机 我尝试使用 webbrowser 包 但它在会话终止后打
  • 获取 HTML 代码的结构

    我正在使用 BeautifulSoup4 我很好奇是否有一个函数可以返回 HTML 代码的结构 有序标签 这是一个例子 h1 Simple example h1 p This is a simple example of html page
  • Bottle 是否可以处理没有并发的请求?

    起初 我认为 Bottle 会并发处理请求 所以我编写了如下测试代码 import json from bottle import Bottle run request response get post import time app B
  • PyPI 上的轮子平台约束有什么限制吗?

    是否有任何地方 PEP 或其他地方 声明关于 Linux 轮子上传范围的限制 PyPI http pypi io 应该有 具体来说 上传是否被认为是可接受的做法linux x86 64轮子到 PyPI 而不是manylinux1 x86 6
  • Learning_rate 不是合法参数

    我正在尝试通过实现 GridSearchCV 来测试我的模型 但我似乎无法在 GridSearch 中添加学习率和动量作为参数 每当我尝试通过添加这些代码来执行代码时 我都会收到错误 这是我创建的模型 def define model op
  • 无法在 Windows 服务器上使 SVN 预提交脚本失败

    我正在编写一个 SVN pre commit bat 文件 该文件调用 Python 脚本来查询我们的问题跟踪系统 以确定用户提供的问题跟踪 ID 是否处于正确的状态 例如 打开 状态 并与正确的关联项目 SVN 服务器运行 Windows
  • 在Python中打开网站框架或图像

    所以我对 python 相当熟练 并且经常使用 urllib2 和 Cookies 来实现网站自动化 我刚刚偶然发现了 webbrowser 模块 它可以在默认浏览器中打开一个网址 我想知道是否可以从该 url 中仅选择一个对象并打开它 具
  • Python 可以替代 Java 小程序吗?

    除了制作用于物理模拟 如抛射运动 重力等 的教育性 Java 小程序之外 还有其他选择吗 如果你想让它在浏览器中运行 你可以使用PyJamas http pyjs org 这是一个 Python 到 Javascript 的编译器和工具集
  • 需要一个从 yaml 文件中提取内容并输出为 csv 文件的脚本

    我对 python 很陌生 但我很感激您帮助指导我创建一个简单的脚本 该脚本读取一堆 yaml 文件 同一目录中的大约 300 个文件 并从 yaml 文件并将其转换为 csv yaml 文件中内容的示例 code 9313 degrees

随机推荐

  • C++ STL编程轻松入门基础

    来源 天极网 作为C 标准不可缺少的一部分 STL应该是渗透在C 程序的角角落落里的 STL不是实验室里的宠儿 也不是程序员桌上的摆设 她的激动人心并非昙花一现 本教程旨在传播和普及STL的基础知识 若能借此机会为STL的推广做些力所能及的
  • 【华为OD机试真题2023B卷 JAVA&JS】解压报文

    华为OD2023 B卷 机试题库全覆盖 刷题指南点这里 解压报文 知识点栈 时间限制 1s 空间限制 256MB 限定语言 不限 题目描述 为了提升数据传输的效率 会对传输的报文进行压缩处理 输入一个压缩后的报文 请返回它解压后的原始报文
  • 讯飞版大模型来了,现场发布四大行业应用成果

    文章目录 人工智能福利文章 前言 SparkDesk讯飞星火认知大模型简介 语言理解 知识问答 逻辑推理 数学题解答 代码理解与编写 亲自体验 写在最后 创作者 全栈弄潮儿 个人主页 全栈弄潮儿的个人主页 个人社区 欢迎你的加入 全栈弄潮儿
  • 梯度下降的作用及分类

    一 介绍 梯度下降法是一个最优化算法 通常也称 最速下降法 常用于机器学习和人工智能中递归性逼近最小偏差模型 梯度下降的方向就是用负梯度方向为搜索方向 沿着梯度下降的方向求解极小值 在训练过程中 每次的正向传播都会得到输出值和真实值的损失值
  • keras使用callbacks后报错:tensorflow.python.framework.errors_impl.NotFoundError: Failed to create a direct

    参考 https stackoverflow com questions 59439124 keras tuner search function throws failed to create a newwriteablefile err
  • Maven引入本地jar包的方法分享

    转自 maven中如何包含本地jar包呢 有时候我们的jar包来源于maven仓库 有时候来源于本地仓库 有时候来源于本地文件 来源于仓库的文件 我们只需输入相应的坐标即可 那么jar包来源于本地文件 如何处理呢 下文笔者讲述maven中包
  • 二十三种设计模式第二十一篇--解释器模式

    解释器模式 Interpreter Pattern 是一种行为设计模式 它用于定义一种语言的语法结构和解释器 使得可以解释并执行特定的语法规则 该模式可以将复杂的语言表达式分解为更小的语法单元 并定义其解释过程 解释器模式的核心组成部分包括
  • NameError: global name ‘***‘ is not defined

    错误示范 class Solution object def fib self n type n int rtype int while n gt 0 if n 1 or n 2 return 1 else return fib n 1 f
  • 手把手带你实现Linux内核编译步骤及配置

    linux 系统体系结构 linux kernel体系结构 arm有7种工作模式 x86也实现了4个不同级别RING0 RING3 RING0级别最高 这样linux用户代码运行在RING3下 内核运行在RING0 这样系统本身就得到了 充
  • linux中把一个文件的内容复制到(或覆盖)另一个文件的末尾

    转载自 https blog csdn net u013991521 article details 80528647 问题描述 比如11的文件内容是 hello 22的文件内容是 world 将22的文件内容复制到11文件的末尾 11文件
  • python类的属性和实例的属性有什么区别

    在 Python 中 类属性和实例属性是两种不同类型的属性 它们在用途和作用域上有所不同 下面是关于它们的区别的详细解释 定义位置 类属性 定义在类的主体中 但在任何类方法之外 实例属性 通常在 init 方法或其他类方法中使用 self
  • 自动化测试工具软测界的不二之选,还不快速来了解

    目录 引言 前言 一 龙测AI TestOps云平台使用教程 1 如何登录龙测AI TestOps云平台 登录方法 登录方法 2 龙测AI TestOps云平台界面布局 3 龙测AI TestOps云平台菜单功能 创建项目 应用管理 设备管
  • 若依框架针对不同用户使用不同样式判断

    在开发中 有时候会针对不同用户使用不同样式 如果使用权限判断符的话会出现 请设置权限的问题 这样我们可以导入若依框架原本的权限判断函数 import checkPermi checkRole from utils permission 权限
  • Hibernate4与hibernate3主要区别与版本不一致导致的错误

    Hibernate版本改动 Hibernate4的改动较大只有spring3 1以上版本能够支持 Spring3 1取消了HibernateTemplate 因为Hibernate4的事务管理已经很好了 不用Spring再扩展了 这里简单介
  • 为何大量网站不能抓取?爬虫突破封禁的6种常见方法

    转载自 https www cnblogs com junrong624 p 5533655 html 在互联网上进行自动数据采集 抓取 这件事和互联网存在的时间差不多一样长 今天大众好像更倾向于用 网络数据采集 有时会把网络数据采集程序称
  • FileZilla - The free FTP solution

    FileZilla The free FTP solution https filezilla project org index php https www filezilla cn 1 Overview The FileZilla Cl
  • JavaScript重写Symbol(Symbol.iterator)实现迭代器(2)

    重写数组for of底层用的迭代器 for of 底层用Symbol Symbol iterator 迭代器 arr 底层用Symbol Symbol iterator 迭代器 示例图 代码 h1 对象遍历重写iterator接口2 h1
  • python中class用法实例

    python中class用法实例 https blog csdn net u010551600 article details 79126911 该程序的作用是找到studet txt文件中 GPA最高的那名同学 并打印出他的信息 程序运行
  • 【机器学习】神经网络介绍【转】

    深度学习 神经网络介绍 1 神经元 2 激活函数 3 感知机与多层网络 4 误差反向传播 参考 周志华 机器学习 神经网络是由具有适应性的简单单元组成的广泛并行互连的网络 它的组织能够模拟生物神经系统对真实世界物体所作出的交互反应 Koho
  • micropython驱动ST7789v 2.4寸液晶显示中文

    一 ST7789v介绍 ST7789v是小尺寸液晶中常用的驱动芯片 作者手里的是网上买的一块2 4寸液晶模组 接口 为SPI接口 网上能找到这个芯片的micropython驱动 这不是本文的重点 本文的重点是如何利用这个驱动 并使用字库的方