目录

前言

一、Uart Device介绍

1 常用API介绍

1.1 uart_configure

1.2 uart_get

1.3 uart_tx

1.4 uart_tx_abort

1.5 uart_rx_enable

1.6 uart_poll_in

1.7 uart_poll_out

1.8  uart_callback_set

1.9 uart_irq_callback_set(旧版)

1.9.2 回调函数介绍

2.0 uart_irq_callback_user_data_set

2.1 uart_irq_tx_enable

2.2 uart_irq_tx_disable

2.3 uart_irq_rx_enable

2.2 uart_irq_rx_disable

2.3 uart_irq_tx_ready

2.4 uart_irq_update

2.2 参数介绍

2.3 注释

2.5 uart_irq_rx_ready

2.2 参数介绍

2.5 uart_irq_tx_ready

2.2 参数介绍

2.5 IRQ相关函数使用事项

2.6 uart_fifo_fill

2.7 uart_fifo_fill

2.8 uart_drv_cmd

2 结构体介绍

1. uart_config

1.3 位相关枚举

2. uart_event

2.1 结构体原型

2.2 主要成员介绍

3 开发注意事项

4 示例


前言

Uart实现原理与理论知识请参考这篇文章:UART工作原理详解

一、Uart Device介绍

1 常用API介绍

1.1 uart_configure

1.1.1 函数介绍

函数原型

作用

返回值

int uart_configure(const struct device* dev, const struct uart_config* cfg) 配置uart设备 0成功,非0失败

1.1.2 参数介绍

参数名

类型

作用

dev const struct device* 指向Uart设备驱动指针
cfg const struct uart_config* 指向配置结构体的指针

1.2 uart_get

1.2.1 函数介绍

函数原型

作用

返回值

int uart_config_get(const struct device* dev, struct uart_config* cfg) 获取当前Uart设备的属性,如波特率之类的 0成功,非0失败

1.2.2 参数介绍

参数名

类型

作用

dev const struct device* 指向Uart设备驱动指针
cfg struct uart_config* 指向配置结构体的指针,会将Uart设备属性写入到这个结构体的成员变量中

1.3 uart_tx

1.3.1 函数介绍

函数原型

作用

返回值

int uart_tx(const struct device* dev, const uint8_t* buf, size_t len, int32_t timeout) 向串口写入数据 0成功,非0失败

1.3.2 参数介绍

参数名

类型

作用

dev const struct device* 指向Uart设备驱动指针
buf const uint8_t* 要写入的数据
len size_t 写入数据的长度
timeout int32_t 超时等待时长,毫秒为单位

1.4 uart_tx_abort

1.4.1 函数介绍

函数原型

作用

返回值

int uart_tx_abort(const struct device *dev) 终止当前串口数据的发送 0成功,非0失败

1.4.2 参数介绍

参数名

类型

作用

dev const struct device * 指向Uart设备驱动指针

1.5 uart_rx_enable

1.5.1 函数介绍

函数原型

作用

返回值

int uart_rx_enable(const struct device *dev, uint8_t *buf, size_t len, int32_t timeout) 从串口接收数据 0成功,非0失败

1.5.2 参数介绍

参数名

类型

作用

dev const struct device * 指向Uart设备驱动指针
buf uint8_t * 指向接收缓冲区的指针
len size_t 接收缓冲区的大小
timeout int32_t 超时时间

1.6 uart_poll_in

1.6.1 函数介绍

函数原型

作用

返回值

int uart_poll_in(const struct device *dev, unsigned char *p_char) 在轮询的模式下接收数据的输入 0成功,非0失败

1.6.2 参数介绍

参数名

类型

作用

dev const struct device * 指向Uart设备驱动指针
p_char unsigned char * 指向unsigned char类型的指针

1.6.3 注释

轮询模式是指每隔一段时间就去读一下缓冲区是否有数据,这个函数每次只能读入一个字节的字符

此函数需要配合循环使用,这个函数的作用就是去检查UART LSR寄存器中的DR位,这个位表示是否有新的数据到来,如果为1则有数据到了,则从里面读入一个字节数据出来,需要注意它不是阻塞函数,需要用户使用while循环配合使用

1.7 uart_poll_out

1.7.1 函数介绍

函数原型

作用

返回值

void uart_poll_out(const struct device *dev, unsigned char out_char) 轮询的模式下向串口输出一个字符 无返回值

1.7.2 参数介绍

参数名

类型

作用

dev const struct device * 指向Uart设备驱动指针
out_char unsigned char 输出的字符

1.7.3 注释

此函数会向数据缓存器里写一个字节,然后查UART LSR寄存器中的TEMT和THRE两个位是否为0,只有这两个位为0时则代表数据发送寄存器里已经有数据了以及已经做好了发送准备可以进行发送了,然后开始发送,它也不是阻塞函数,需要用户配合while循环来使用,目的就是为了达到轮询的效果

1.8  uart_callback_set

1.8.1 函数介绍

函数原型

作用

返回值

static inline int uart_callback_set(const struct device *dev, uart_callback_t callback, void *user_data) 设置事件处理回调函数 0成功,非0失败

1.8.2 参数介绍

参数名

类型

作用

dev const struct device * 指向Uart设备驱动指针
callback uart_callback_t 回调函数,原型:void uart_call (const struct device *dev, struct uart_event* evt,void* user_data)
user_data void * 要传递的参数

1.8.3 回调函数介绍

1.8.3.1 函数介绍

函数原型

作用

返回值

void uart_call (const struct device *dev, struct uart_event* evt,void* user_data) uart事件回调

1.8.3.2 参数介绍

这些参数会在回调时由uart驱动传递进来

参数名

类型

作用

dev const struct device * 指向Uart设备驱动指针
evt struct uart_event* 发生的事件
user_data void* 传递参数

1.9 uart_irq_callback_set(旧版)

1.9.1 函数介绍

函数原型

作用

返回值

static inline void uart_irq_callback_set(const struct device *dev, uart_irq_callback_user_data_t cb) 设置IRQ中断回调函数

1.9.2 参数介绍

参数名

类型

作用

dev const struct device * 指向Uart设备驱动指针
cb uart_irq_callback_user_data_t 回调函数原型

1.9.2 回调函数介绍

1.9.2.1 函数介绍

函数原型

作用

返回值

static void func_irq(const struct device *dev, void *user_data) 当UART硬件产生中断时回调的函数

1.9.2.2 参数介绍

参数名

类型

作用

dev const struct device * 产生中断的Uart设备驱动
user_data void * 传递的数据指针

1.9.3 注释

这个函数不支持传递数据指针

2.0 uart_irq_callback_user_data_set

2.1 函数介绍

函数原型

作用

返回值

static inline void uart_irq_callback_user_data_set(const struct device *dev, uart_irq_callback_user_data_t cb, void *user_data) 设置IRQ回调函数,支持传递参数

2.2 参数介绍

参数名

类型

作用

dev const struct device * 指向Uart设备驱动指针
cb uart_irq_callback_user_data_t 回调函数原型
user_data void * 传递参数

2.3 注释

回调参数原型参考uart_irq_callback_set函数介绍

2.1 uart_irq_tx_enable

2.1 函数介绍

函数原型

作用

返回值

void uart_irq_tx_enable(const struct device *dev) 将IER(中断使能寄存器)寄存器中的TX开启,允许产生TX中断

2.2 参数介绍

参数名

类型

作用

dev const struct device * 指向Uart设备驱动指针

2.2 uart_irq_tx_disable

2.1 函数介绍

函数原型

作用

返回值

void uart_irq_tx_disable(const struct device *dev) 将IER(中断使能寄存器)寄存器中的TX关闭,禁止产生TX中断

2.2 参数介绍

参数名

类型

作用

dev const struct device * 指向Uart设备驱动指针

2.3 uart_irq_rx_enable

2.1 函数介绍

函数原型

作用

返回值

void uart_irq_rx_enable(const struct device *dev) 将IER(中断使能寄存器)寄存器中的RX开启,允许产生RX中断

2.2 参数介绍

参数名

类型

作用

dev const struct device * 指向Uart设备驱动指针

2.2 uart_irq_rx_disable

2.1 函数介绍

函数原型

作用

返回值

void uart_irq_rx_disable(const struct device *dev) 将IER(中断使能寄存器)寄存器中的RX关闭,禁止产生RX中断

2.2 参数介绍

参数名

类型

作用

dev const struct device * 指向Uart设备驱动指针

2.3 uart_irq_tx_ready

2.1 函数介绍

函数原型

作用

返回值

static inline int uart_irq_tx_ready(const struct device *dev) 检查TX的Ready位是否有效,即判断TX FIFO输入缓冲区是否可以接收新的数据 可以写入返回1,不能写入返回0

2.2 参数介绍

参数名

类型

作用

dev const struct device * 指向Uart设备驱动指针

2.4 uart_irq_update

2.1 函数介绍

函数原型

作用

返回值

int uart_irq_update(const struct device *dev) 更新中断标志位 成功返回1,否则返回0

2.2 参数介绍

参数名

类型

作用

dev const struct device * 指向Uart设备驱动指针

2.3 注释

在硬件中断开发时我们是需要手动更新中断标志位的,这个函数的作用就是如此

2.5 uart_irq_rx_ready

2.1 函数介绍

函数原型

作用

返回值

static inline int uart_irq_rx_ready(const struct device *dev) 检查RX Ready位是否为1,即检查输入缓冲区是否有新的数据来 返回1则代表有新数据可以读取,非1则无数据

2.2 参数介绍

参数名

类型

作用

dev const struct device * 指向Uart设备驱动指针

2.5 uart_irq_tx_ready

2.1 函数介绍

函数原型

作用

返回值

static inline int uart_irq_tx_ready(const struct device *dev) 检查TX Ready位是否为1,即检查输出缓冲区是否有新的数据可以输出 返回1则代表有新数据可以输出,非1则无数据

2.2 参数介绍

参数名

类型

作用

dev const struct device * 指向Uart设备驱动指针

2.5 IRQ相关函数使用事项

在使用IRQ相关的函数时,Zephry要求在中断处理函数中,先调用uart_irq_update更新中断标志寄存器,然后调用uart_irq_tx_ready或uart_irq_rx_ready来检查输入输出是否有效,然后在进行相关读写操作

其次uart_irq_callback_set与uart_callback_set是不同的,uart_irq_callback_set是用来设置硬件方面的中断的回调,uart_callback_set是用来Zephry Uart驱动内部回调事件,比如Uart驱动写入了一个数据它自己会产生一个消息为DONE,即写入完成的事件然后回调函数并将事件传入

2.6 uart_fifo_fill

2.1 函数介绍

函数原型

作用

返回值

static inline int uart_fifo_fill(const struct device *dev, const uint8_t *tx_data, int size) 向FIFO缓冲区写入数据 返回写入字节长度

2.2 参数介绍

参数名

类型

作用

dev const struct device * 指向Uart设备驱动指针
tx_data const uint8_t * 输入缓冲区指针
size int 缓冲区大小

2.7 uart_fifo_fill

2.1 函数介绍

函数原型

作用

返回值

static inline int uart_fifo_read(const struct device *dev, uint8_t *rx_data, const int size) 从FIFO缓冲区读取数据 返回读取字节长度

2.2 参数介绍

参数名

类型

作用

dev const struct device * 指向Uart设备驱动指针
rx_data const uint8_t * 接收数据缓冲区指针
size int 缓冲区大小

2.8 uart_drv_cmd

2.1 函数介绍

函数原型

作用

返回值

int uart_drv_cmd(const struct device* dev, uint32_t cmd, uint32_t p) 向串口发送命令 0成功,非0失败

2.2 参数介绍

参数名

类型

作用

dev const struct device* 指向Uart设备驱动指针
cmd uint32_t 命令
p uint32_t 命令附加参数

2.3 注释

该函数需要驱动程序实现uart命令,详细请参考Zephry Uart驱动

2 结构体介绍

1. uart_config

1.1 结构体原型

struct uart_config {uint32_t baudrate;uint8_t parity;uint8_t stop_bits;uint8_t data_bits;uint8_t flow_ctrl;
};

1.2 成员介绍

成员名

类型

作用

baudrate uint32_t 波特率
parity uint8_t 奇偶校验位
stop_bits uint8_t 停止位
data_bits uint8_t 数据位
flow_ctrl uint8_t 流控制位

1.3 位相关枚举

1.3.1 奇偶校验位:uart_config_parity

枚举定义

作用

UART_CFG_PARITY_NONE

无奇偶校验位
UART_CFG_PARITY_ODD 奇校验位,1为奇数校验位为0,偶数校验位为1
UART_CFG_PARITY_EVEN 偶校验位,1为奇数校验位为1,偶数校验位为0
UART_CFG_PARITY_MARK 校验位始终为1
UART_CFG_PARITY_SPACE 校验位始终为0

1.3.2 停止位:uart_config_stop_bits

枚举定义

作用

UART_CFG_STOP_BITS_0_5 停止位为0或5个BIT
UART_CFG_STOP_BITS_1 停止位为1个BIT
UART_CFG_STOP_BITS_1_5 停止位为1或5个BIT
UART_CFG_STOP_BITS_2 停止位为2个BIT

1.3.3 数据位: uart_config_data_bits

枚举定义

作用

UART_CFG_DATA_BITS_5 数据位为5BIT
UART_CFG_DATA_BITS_6 数据位为6BIT
UART_CFG_DATA_BITS_7 数据位为7BIT
UART_CFG_DATA_BITS_8 数据位为8BIT
UART_CFG_DATA_BITS_9 数据位为9BIT

1.3.4 流控制位:uart_config_flow_control

枚举定义

作用

UART_CFG_FLOW_CTRL_NONE 无流控制
UART_CFG_FLOW_CTRL_RTS_CTS RTS/CTS线有效
UART_CFG_FLOW_CTRL_DTR_DSR DTR/DSR线有效

流控制一旦开启,需要用户手动根据当前流方向来修改RTS/CTS或DTR/DSR线的高低电平

2. uart_event

2.1 结构体原型

struct uart_event {enum uart_event_type type;union uart_event_data {struct uart_event_tx tx;struct uart_event_rx rx;struct uart_event_rx_buf rx_buf;struct uart_event_rx_stop rx_stop;} data;
};

2.2 主要成员介绍

1. type

此成员是个枚举,它的值指向当前发生的事件,可以取如下值:

枚举定义

作用

枚举定义

作用

UART_TX_DONE 写入完成
UART_TX_ABORTED 超时写入,在调用uart_tx有个超时参数,当超时时会发送此事件
UART_RX_RDY 接收数据已经准备好处理
UART_RX_BUF_REQUEST 缓冲区切换接收,当一个缓冲区在接收时调用uart_rx_buf_rsp进行无缝切换接收时会产生这个事件
UART_RX_BUF_RELEASED, RX接收被禁用且此时可以进行启动时候产生的事件
UART_RX_DISABLED RX被禁用时产生的事件
UART_RX_STOPPED 由于外部原因,导致RX停止接收时产生的事件

2. uart_event_data

此成员是个联合体,当产生不同事件时它内部仅有一个成员有效

当产生tx相关事件时tx成员有效

rx相关时rx成员有效

产生stop时rx_stop有效

3 开发注意事项

Zephry针对不同的板子有不同的Uart驱动实现,都放在zephyrproject/zephyr/drivers/serial这个目录下打开可以看到有不同板子的实现

CMakeLists.txt         Kconfig.mcux_lpsci     Kconfig.test            uart_lpc11u6x.c       uart_rcar.c
Kconfig                Kconfig.mcux_lpuart    Kconfig.uart_sam        uart_lpc11u6x.h       uart_rom_esp32c3.c
Kconfig.altera_jtag    Kconfig.miv            Kconfig.usart_sam       uart_mcux.c           uart_rtt.c
Kconfig.apbuart        Kconfig.msp432p4xx     Kconfig.xlnx            uart_mcux_flexcomm.c  uart_rv32m1_lpuart.c
Kconfig.b91            Kconfig.native_posix   Kconfig.xmc4xxx         uart_mcux_iuart.c     uart_sam0.c
Kconfig.cc13xx_cc26xx  Kconfig.npcx           leuart_gecko.c          uart_mcux_lpsci.c     uart_sam.c
Kconfig.cc32xx         Kconfig.nrfx           serial_test.c           uart_mcux_lpuart.c    uart_sifive.c
Kconfig.cmsdk_apb      Kconfig.ns16550        uart_altera_jtag_hal.c  uart_miv.c            uart_stellaris.c
Kconfig.esp32          Kconfig.nuvoton        uart_apbuart.c          uart_msp432p4xx.c     uart_stm32.c
Kconfig.esp32c3_rom    Kconfig.pl011          uart_b91.c              uart_native_posix.c   uart_stm32.h
Kconfig.gecko          Kconfig.psoc6          uart_cc13xx_cc26xx.c    uart_npcx.c           uart_xlnx_ps.c
Kconfig.imx            Kconfig.rcar           uart_cc32xx.c           uart_nrfx_uart.c      uart_xlnx_uartlite.c
Kconfig.leuart_gecko   Kconfig.rtt            uart_cmsdk_apb.c        uart_nrfx_uarte.c     uart_xmc4xxx.c
Kconfig.litex          Kconfig.rv32m1_lpuart  uart_esp32.c            uart_ns16550.c        usart_sam.c
Kconfig.lpc11u6x       Kconfig.sam0           uart_gecko.c            uart_ns16550.h
Kconfig.mcux           Kconfig.sifive         uart_handlers.c         uart_nuvoton.c
Kconfig.mcux_flexcomm  Kconfig.stellaris      uart_imx.c              uart_pl011.c
Kconfig.mcux_iuart     Kconfig.stm32          uart_liteuart.c         uart_psoc6.c

可以看到许多uart开头的实现文件,如我们的是stm32的板子,对应的驱动实现就是uart_stm32.c这个文件,如果你在使用时出现了问题,可以到这个文件中去看下驱动实现,出现了什么问题

4 示例

这里我基于FIFO模式实现了一个LOOPBACK回环的代码,我的UART RX与TX是相连的,可供大家参考与使用

注意使用前需要在prj.conf中开启驱动

CONFIG_SERIAL=y
CONFIG_UART_ASYNC_API=y
CONFIG_UART_INTERRUPT_DRIVEN=y

完整实现代码:

#include <zephyr.h>
#include <sys/printk.h>
#include <device.h>
#include <drivers/uart.h>
#include <errno.h>
#include <string.h>
//Packaging structure
struct tx_data{uint8_t* data;size_t   len;size_t   msg;
}send_data;struct rx_data{uint8_t* data;size_t   len;size_t   msg;
}recv_data;static void uart_fifo_callback(const struct device *dev, void *user_data){static int tx_send_index;static int rx_recv_index;struct tx_data* tx_send_data = &send_data;struct rx_data* rx_recv_data = &recv_data;if(uart_irq_update(dev) !=1 ){return;}//if writeif(uart_irq_tx_ready(dev) && tx_send_index < tx_send_data->len && tx_send_data->msg == MSG_SEND){uart_fifo_fill(dev,(uint8_t*)&tx_send_data->data[tx_send_index++],SEND_LEN);if(tx_send_index >= tx_send_data->len){tx_send_index = 0;tx_send_data->msg = MSG_DONE;//Stop and interrupt manually after meeting the requirementsuart_irq_tx_disable(dev);}}//if readif(uart_irq_rx_ready(dev)){uart_fifo_read(dev,(uint8_t*)&rx_recv_data->data[rx_recv_index++],RECV_LEN);if(rx_recv_index >= rx_recv_data->len){uart_irq_rx_disable(dev);}}}
int uart_send(const struct device* dev,uint8_t* data,size_t len){if(dev == NULL || data == NULL || len == 0){return -1;}send_data.data = data;send_data.len  = len;send_data.msg  = MSG_SEND;//After the enable interrupt, judge whether to write or not                                                                      uart_irq_tx_enable(dev);k_sleep(K_MSEC(TIME_OUT));uart_irq_tx_disable(dev);if(send_data.msg != MSG_DONE) return -2;return 0;}int uart_recv(const struct device* dev,uint8_t* data,size_t len){if(dev == NULL || data == NULL || len == 0){return -1;}recv_data.data = data;recv_data.len  = len;recv_data.msg  = MSG_RECV;uart_irq_rx_enable(dev);k_sleep(K_MSEC(TIME_OUT));uart_irq_rx_disable(dev);if(send_data.msg != MSG_DONE) return -2;return 0;}void main(){printk("--- UART ---\n");uint8_t tx_buff[BUFF_LEN] = "hello word\r\n1";uint8_t rx_buff[BUFF_LEN] = {0};const struct device* dev = device_get_binding("UART_6");if(dev == NULL){ printk("ERROR bind\n");  return; }if(!device_is_ready(dev)) { printk("device is no ready\n"); return; }struct uart_config ut = {.baudrate = 115200,.parity =  UART_CFG_PARITY_NONE,.stop_bits = UART_CFG_STOP_BITS_1,.data_bits = UART_CFG_DATA_BITS_8,.flow_ctrl  =  UART_CFG_FLOW_CTRL_NONE,};if(uart_configure(dev,&ut) != 0) {printk("uart config error\n");return;}uart_irq_callback_set(dev,uart_fifo_callback);//writerecv_data.data = rx_buff;recv_data.len  = strlen(rx_buff);uart_send(dev,tx_buff,strlen(tx_buff));printk("%s",rx_buff);}

上述代码需要注意我没有写接收,因为是回环相接,当产生写入硬中断并写入后会立马产生RX中断

运行结果:

ing Zephyr OS build zephyr-v2.6.0-1753-g365ff6db9f02  ***
--- UART ---
hello word

Zephry Uart Device详解相关推荐

  1. Linux的tty架构及UART驱动详解

    Linux的tty架构及UART驱动详解 一.模块硬件学习 1.1. Uart介绍 通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),通常称 ...

  2. 基于Linux的tty架构及UART驱动详解

    一.模块硬件学习 1.1. Uart介绍 通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),通常称为UART,是一种异步收发传输器,是电脑硬 ...

  3. UART驱动程序详解(基于Linux)——注册过程

    参考内核源码:drivers\tty\serial\imx.c drivers\tty\serial\serial_core.c drivers\tty\tty_port.c drivers\tty\ ...

  4. TensorFlow之设备(device)详解

    对TensorFlow不了解的,猛的一看还以为TensorFlow是个设备什么的,其实本文要说的是Python的TensorFlow模块下一个叫device()的方法,即: import tensor ...

  5. tensorflow——960M显卡深度学习_报错no kernel image is available for execution on the device详解

    文章目录 消歧义 一.问题描述 二.解决方法 参考文章 消歧义 文中的算力一词指代 (Compute) Capability 一.问题描述 以下是配置: 配置 版本 显卡 Nvidia Geforce ...

  6. Linux usb 4. Device 详解

    文章目录 1. 简介 2. Platform Layer 2.1 Platform Device 2.2 Platform Driver 3. UDC/Gadget Layer 3.1 Gadget ...

  7. RK3399平台开发系列讲解(UART子系统)4.47、UART子系统详解

    平台 内核版本 安卓版本 RK3399 Linux4.4 Android7.1

  8. UART, SPI, IIC的详解及三者的区别和联系

    1.UART, SPI, IIC的详解 UART.SPI.IIC是经常用到的几个数据传输标准,下面分别总结一下: UART(Universal Asynchronous Receive Transmi ...

  9. PC 机 UART(NS8250)详解

    PC 机 UART(NS8250)详解 异步串行通信原理 两台计算机/设备进行数据交换,即通信,必须像人们对话一样使用同一种语言.在计算机通信术语中,我们把计算机/设备与计算机/设备之间的" ...

  10. FPGA串口(UART)通信协议制定与设计思路详解示例

    串口(UART)通信协议制定与设计思路详解 1 概述 本文用于描述规定的串口通信协议,以及传输内容. 2 项目关于串口的要求 a) 支持BIT自检,1路UART上报BIT信息: b) 1路UART接口 ...

最新文章

  1. 【Android 安全】DEX 加密 ( Application 替换 | Android 应用启动原理 | ActivityThread 源码分析 )
  2. c++ list 容器
  3. 前端学习(2615):数据映射map
  4. (转)Spring Boot 2 (五):Docker Compose + Spring Boot + Nginx + Mysql 实践
  5. windows查看linux文件工具,「实用工具」介绍几款Windows系统与Linux服务器传递文件的工具...
  6. Redis bind用法
  7. python concurrent.futures包使用,捕获异常
  8. 台达ms300变频器使用手册中文_台达ms300变频器说明书.doc
  9. QQ机器人:群成员自我禁言管理【最新beta2版本】
  10. 网页中插入背景音乐代码(html)
  11. IDEA This is not a valid Java qualified name问题解决
  12. 线性回归-误差项分析
  13. UnicodeDecodeError: ‘gb2312‘ codec can‘t decode byte 0xe9 in position 5632: illegal multibyte sequen
  14. 2021年CSS 实用手册
  15. Excel2013 基本用法(上)
  16. 简易支付验证:即时支付、签名的有效性和交易的完整性
  17. 人心比万物都诡诈,谁能识透呢?
  18. linux备忘录课程设计,linux备忘录
  19. 支付宝商户代扣(免密签约,免密扣款)
  20. EasyOcr光学字符识别 —— 筑梦之路

热门文章

  1. Java毕业设计-个性影片/电影推荐系统
  2. 会议论文投稿到接收流程【手里有粮心中不慌】
  3. Codeforce - 1040B - Shashlik Cooking(水题)
  4. sublime 中文乱码
  5. spring 使用注解遇到的问题
  6. Kaggle数据集Telco-Customer-Churn.csv特征相关性分析(用LabelEncoder编码)
  7. Vitalik 系统设计中的封装复杂性和系统复杂性
  8. ReentrantLock和AbstractQueuedSynchronizer的整体结构
  9. audio realtek 耳机没声_解决Realtek High Definition Audio 声卡前面板耳机无声音方法
  10. 联想Win10安装Ubuntu双系统教程