[IMX] 05.串口 - UART
目录
1.通信格式
2.电平标准
3.IMX UART 模块
4.时钟寄存器 - CCM_CSCDR1
5.控制寄存器
5.1.UART_UCR1
5.2.UART_UCR2
5.3.UART_UCR3
6.状态寄存器
6.1.UART_USR1
6.2.UART_USR2
7.FIFO 控制寄存器 - UART_UFCR
8.波特率寄存器
8.1.分母 - UART_UBIR
8.2.分子 - UART_UBMR
9.波特率计算
10.接收数据寄存器 - UART_URXD
11.发送数据寄存器 - UART_UTXD
12.代码实现
串口全称串行接口,也称为 COM 接口,串行接口指的是数据一个接一个的按顺序传输
串口的通信线路很简单,使用两条线即可实现双向通信,一条用于发送,一条用于接收
串口是一种常用的工业接口,通信的距离较远,但是速度相对较低,I.MX6U 自带的 UART 外设就是串口的一种
UART 全称是 UniversalAsynchronous Receiver/Trasmitter,即异步串行收发器
USART 全称是 Universal Synchronous/Asynchronous Receiver/Transmitter,即同步/异步串行收发器,相比 UART 多了一个同步的功能,在硬件上体现出来的就是多了一条时钟线
一般 USART 可以作为 UART 使用的,即不使用其同步的功能
1.通信格式
UART 作为串口的一种,其工作原理是将数据按一位接一位的进行传输,发送和接收各用一 条线,因此通过 UART 接口与外界相连最少需要三条线:TXD (发送)、RXD (接收) 和 GND(地线)
串口的通信格式如下所示:
图中各个位的含义如下:
-
空闲位:数据线在空闲状态时为逻辑 “1” 状态(高电平),表示没有数据线空闲,没有数据传输;
-
起始位:当要传输数据时先传输一个逻辑 “0”,也就是将数据线电平拉低,表示开始数据传输;
-
数据位:数据位就是实际要传输的数据,数据位可选择 5~8 位,一般按照字节传输数据,一个字节占 8 位,因此数据位通常为 8 位,低位在前,先传输,高位最后传输;
-
奇偶校验位:对数据中为 “1” 的位进行奇偶校验,可以不使用奇偶校验功能;
-
停止位:数据传输完成标志位,停止位的位数可以选择 1 位、1.5 位或 2 位的高电平,一般选择 1 位停止位;
-
波特率:波特率是 UART 数据传输的速率,即每秒传输的数据位数,一般选择 9600、19200、115200 等;
2.电平标准
UART 接口电平有 TTL 和 RS-232 两种标准
一般开发板上都有 TXD 和 RXD 引脚,引脚的低电平表示逻辑 0,高电平表示逻辑 1,这个就是 TTL 电平
RS-232 采用差分线,-3 ~ -15V 表示逻辑 1,+3 ~ +15V 表示逻辑 0
下图所示的就是 TTL 电平的接口:
上面图片中的模块为 USB 转 TTL 模块,TTL 接口部分有 VCC、GND、RXD、TXD、 RTS 和 CTS 引脚,使用时通过杜邦线和其他模块的 TTL 接口相连即可
RS-232 电平标准需要使用 DB9 接口,I.MX6U-ALPHA 开发板上的 COM3 (UART3) 口就是 RS-232 接口:
由于现在的电脑都没有 DB9 接口了,取而代之的是 USB 接口,所以就催生出了很多 USB 转串口 TTL 芯片,比如 CH340、PL2303 等,通过这些芯片可以实现串口 TTL 转 USB
I.MX6U-ALPHA 开发板使用 CH340 芯片完成 UART1 和电脑之间的连接,只需要一条USB 线即可:
3.IMX UART 模块
I.MX6U 一共有 8 个 UART 模块,主要特性如下:
-
兼容 TIA/EIA-232F 标准,速度最高可到 5Mbit/s;
-
支持串行 IR 接口,兼容 IrDA,最高可到 115.2Kbit/s;
-
支持 9 位或者多节点模式 (RS-485);
-
1 或 2 位停止位;
-
可编程的奇偶校验 (奇校验和偶校验);
-
自动波特率检测 (最高支持 115.2Kbit/s);
4.时钟寄存器 - CCM_CSCDR1
UART 的时钟源由寄存器 CCM_CSCDR1 的 UART_CLK_SEL[6] 位选择:
UART_CLK_SEL 为 0 时 UART 的时钟源为 pll3_80m (80MHz)
UART_CLK_SEL 为 1 时 UART 的时钟源为 osc_clk (24M)
一般选择 pll3_80m 作为 UART 的时钟源
寄存器 CCM_CSCDR1 的 UART_CLK_PODF[5:0] 位是 UART 的时钟分频值,可设置 0~63,分别对应 1~64 分频,一般设置为 1 分频,因此最终进入 UART 的时钟频率为 80MHz
5.控制寄存器
UART_UCR1 ~ UART_UCR4 这四个寄存器用于配置 UART 模块的相关功能,如自动波特率使能、奇偶校验模式等
5.1.UART_UCR1
其中,重点关注如下几个位域:
-
ADBR[14]:自动波特率检测使能,为 0 时关闭自动波特率检测,为 1 时使能自动波特率检测;
-
UARTEN[0]:UART 使能,为 0 时关闭 UART,为 1 时使能 UART;
5.2.UART_UCR2
其中,重点关注如下几个位域:
-
IRTS[14]:为 0 时使用 RTS 引脚功能,为 1 时忽略 RTS 引脚;
-
PREN[8]:奇偶校验使能,为 0 时关闭奇偶校验,为 1 时使能奇偶校验;
-
PROE[7]:奇偶校验模式选择,开启奇偶校验后,若该位为 0 则使用偶校验,为 1 使用奇校验;
-
STOP[6]:停止位数量,为 0 表示使用 1 位停止位,为 1 表示使用 2 位停止位;
-
WS[5]:数据位长度,为 0 时选择 7 位数据位,为 1 时选择 8 位数据位;
-
TXEN[2]:发送使能位,为 0 时关闭 UART 的发送功能,为 1 时打开 UART 的发送功能;
-
RXEN[1]:接收使能位,为 0 时关闭 UART 的接收功能,为 1 时打开 UART 的接收功能;
-
SRST[0]:软件复位,向该位写 0 复位 UART,为 1 时表示复位完成,复位完成后此位会自动置 1,表示复位完成,只能向该位写 0,写 1 会被忽略;
5.3.UART_UCR3
这里只关注 RXDMUXSEL[2],该位用于设置复用输入,但是 IMX UART 使用 MUXED 模式,因此该位始终为 1
6.状态寄存器
6.1.UART_USR1
例程未使用该寄存器
6.2.UART_USR2
其中,主要关注一下位域:
-
TXDC[3]:发送完成标志位,为 1 时表明发送缓冲 TxFIFO 和移位寄存器为空,即发送完成,向 TxFIFO 写入数据此位就会自动清零;
-
RDR[0]:数据接收标志位,为 1 时表明至少接收到一个数据,从寄存器 UART_URXD 接收到数据后此位会自动清零;
7.FIFO 控制寄存器 - UART_UFCR
其中,关注 RFDIV[9:7] 位域,其用于设置时钟源的分频系数:
-
0b000:6 分频;
-
0b001:5 分频;
-
0b010:4 分频;
-
0b011:3 分频;
-
0b100:2 分频;
-
0b101:1 分频;
-
0b110:7 分频;
-
0b111:保留
这里需要注意的是,分频系数和位域的值不是一一对应的关系
8.波特率寄存器
8.1.分母 - UART_UBIR
BRM(Binary Rate Multiplier)用于生成 16x 的波特率
UART_UBIR 寄存器的 INC[15:0] 位域存储计算波特率的分母:
8.2.分子 - UART_UBMR
UART_UBMR 寄存器的 MOD[15:0] 存储计算波特率的分子:
9.波特率计算
波特率的计算公式如下:
-
Ref Freq:经过分频进入 UART 的时钟频率;
-
UBMR:寄存器 UART_UBMR 中的值,分子;
-
UBIR:寄存器 UART_UBIR 中的值,分母;
通过 UART_UFCR 的 RFDIV 位、UART_UBMR 和 UART_UBIR 寄存器中的值即可计算波特率,例如,要设置 UART 的波特率为 115200,则可以设置 RFDIV 为 0x5 (0b101),即 1 分频,因此 RefFreq = 80MHz,设置 UBIR = 71,UBMR = 3124,根据公式可得:
10.接收数据寄存器 - UART_URXD
其中关注 RX_DATA[7:0] 位域,其中保存接收到的数据,读取该位域即可获得接收的数据,在 7-bit 模式下,最高位强制为 0,在 8-bit 模式下,全部的 8-bit 均为有效数据位
11.发送数据寄存器 - UART_UTXD
TX_DATA[7:0] 保存将要发送的数据,在 7-bit 模式下忽略最高位,在 8-bit 模式下,全部的 8-bit 均为有效位,数据发送时从最低位开始发送,仅当 UART_USR1.TRDY 为 1 时才允许向 TX_DATA[7:0] 写入数据,防止产生冲突
12.代码实现
// uart.h#ifndef _UART_H
#define _UART_H#include "nxp.h"// 函数声明
void uart_init(void);
void uart_io_init(void);
void uart_disable(UART_Type *base);
void uart_enable(UART_Type *base);
void uart_soft_reset(UART_Type *base);
void uart_set_baudrate(UART_Type *base, uint32_t baudrate, uint32_t clk);// 注意,在 stdio.h SDK 中会使用下面这三个接口
// 因此两边的函数定义一定要保持一致
void putc(unsigned char c);
void puts(char *str);
unsigned char getc(void);// 下面这个函数用于防止编译器报错
void raise(int sig_nr);#endif /* _UART_H */
// uart.c#include "uart.h"/* 初始化串口 UART1 使用的 IO 引脚 */
void uart_io_init(void)
{/* 初始化 IO 复用* UART1_RX_DATA 引脚功能选择为 UART1_RXD(配置 IOMUXC_SW_MUX_CTL_PAD_UART1_RX_DATA 寄存器)* UART1_TX_DATA 引脚功能选择为 UART1_TXD(配置 IOMUXC_SW_MUX_CTL_PAD_UART1_TX_DATA 寄存器)*/IOMUXC_SetPinMux(IOMUXC_UART1_TX_DATA_UART1_TX, 0);IOMUXC_SetPinMux(IOMUXC_UART1_RX_DATA_UART1_RX, 0);/* 配置 UART1_RXD 和 UART1_TXD 引脚的电气特性* 配置 IOMUXC_SW_PAD_CTL_PAD_UART1_TX_DATA 寄存器* 配置 IOMUXC_SW_PAD_CTL_PAD_UART1_RX_DATA 寄存器* 这两个引脚的电气特性一样,相关位域的配置如下:* HYS[16]:使能迟滞比较器,0b0,禁用* PUS[15:14]:上拉/下拉电阻值,0b00,下拉* PUE[13]:引脚状态保持,0b0,不保持引脚电平值* PKE[12]:状态保持器使能,0b1,使能* ODE[11]:开漏输出使能,0b0,禁用* SPEED[7:6]:IO 速率,0b10,100MHz* DSE[5:3]:IO 驱动能力,0b110,R0/6* SRE[0]:压摆率,0b0,低压摆率* 因此,最终要写入寄存器的值为:0x000010B0*/IOMUXC_SetPinConfig(IOMUXC_UART1_TX_DATA_UART1_TX, 0x000010B0);IOMUXC_SetPinConfig(IOMUXC_UART1_TX_DATA_UART1_RX, 0x000010B0);
}/* 启用指定的 UART 模块 */
void uart_enable(UART_Type *base)
{/* 向 UART_UCR1 寄存器的 UARTEN[0] 位写 1 使能 UART 模块 */base->UCR1 |= (0b1 << 0);
}/* 禁用指定的 UART 模块 */
void uart_disable(UART_Type *base)
{/* 向 UART_UCR1 寄存器的 UARTEN[0] 位写 0 禁用 UART 模块 */base->UCR1 &= ~(0b1 << 0);
}/* UART 复位 */
void uart_soft_reset(UART_Type *base)
{/* 向 UART_UCR2 寄存器的 SRST[0] 位写 0 发送 UART 模块复位请求* 复位完成后,SRST[0] 会自动恢复为 1*/base->UCR2 &= ~(0b1 << 0);/* 等待复位完成 */while (!(base->UCR2 & 0x00000001)) {}
}/* 设置 UART 的波特率 */
void uart_set_baudrate(UART_Type *base, uint32_t baudrate, uint32_t clk)
{uint32_t numerator = 0; /* 分子 */uint32_t denominator = 0; /* 分母 */uint32_t divisor = 0;uint32_t refFreqDiv = 0;uint32_t divider = 0;uint64_t baudDiff = 0;uint64_t tempNumerator = 0;uint64_t tempDenominator = 0;/* 计算最大的除数 */numerator = clk;denominator = baudrate << 4;divisor = 1;while (denominator != 0){divisor = denominator;denominator = numerator % denominator;numerator = divisor;}numerator = clk / divisor;denominator = (baudrate << 4) / divisor;/* numerator ranges from 1 ~ 7 * 64k *//* denominator ranges from 1 ~ 64k */if ((numerator > (UART_UBIR_INC_MASK * 7)) || (denominator > UART_UBIR_INC_MASK)){uint32_t m = (numerator - 1) / (UART_UBIR_INC_MASK * 7) + 1;uint32_t n = (denominator - 1) / UART_UBIR_INC_MASK + 1;uint32_t max = m > n ? m : n;numerator /= max;denominator /= max;if (0 == numerator){numerator = 1;}if (0 == denominator){denominator = 1;}}divider = (numerator - 1) / UART_UBIR_INC_MASK + 1;switch (divider){case 1:refFreqDiv = 0x05;break;case 2:refFreqDiv = 0x04;break;case 3:refFreqDiv = 0x03;break;case 4:refFreqDiv = 0x02;break;case 5:refFreqDiv = 0x01;break;case 6:refFreqDiv = 0x00;break;case 7:refFreqDiv = 0x06;break;default:refFreqDiv = 0x05;break;}/* Compare the difference between baudRate_Bps and calculated baud rate.* Baud Rate = Ref Freq / (16 * (UBMR + 1)/(UBIR+1)).* baudDiff = (srcClock_Hz/divider)/( 16 * ((numerator / divider)/ denominator).*/tempNumerator = clk;tempDenominator = (numerator << 4);divisor = 1;/* get the approximately maximum divisor */while (tempDenominator != 0){divisor = tempDenominator;tempDenominator = tempNumerator % tempDenominator;tempNumerator = divisor;}tempNumerator = clk / divisor;tempDenominator = (numerator << 4) / divisor;baudDiff = (tempNumerator * denominator) / tempDenominator;baudDiff = (baudDiff >= baudrate) ? (baudDiff - baudrate) : (baudrate - baudDiff);if (baudDiff < (baudrate / 100) * 3){base->UFCR &= ~UART_UFCR_RFDIV_MASK;base->UFCR |= UART_UFCR_RFDIV(refFreqDiv);base->UBIR = UART_UBIR_INC(denominator - 1); // 要先写 UBIR 寄存器,然后再写 UBMR 寄存器base->UBMR = UART_UBMR_MOD(numerator / divider - 1);}
}/* UART1 初始化,波特率 115200 */
void uart_init(void)
{/* 初始化串口 IO 引脚 */uart_io_init();/* 初始化 UART1 */uart_disable(UART1); /* 先禁用 UART1 */uart_soft_reset(UART1); /* 复位 UART1 *//* 清除 UCR1 寄存器 */UART1->UCR1 = 0;/* 关闭自动波特率检测:UART1_UCR1.ADBR[14] 置 0 */UART1->UCR1 &= (0b1 << 14);/* 配置 UART:UART_UCR2 寄存器* IRTS[14]:1,忽略 RTS 引脚* PREN[8]: 0,关闭奇偶校验校验* STPB[6]: 0,1 位停止位* WS[5]: 1,8-bit 数据位* TXEN[2]: 1,使能发送* RXEN[1]: 1,使能接收*/UART1->UCR2 |= (0b1 << 14) | (0b1 << 5) | (0b1 << 2) | (0b1 << 1);/* 配置 UART1_UCR3 寄存器,将 RXDMUXSEL[2] 设置为 1(该位必须始终为 1) */UART1->UCR3 |= (0b1 << 2);/* 设置波特率 */
#if 0/** 波特率计算公式: BaudRate = RefFreq / (16 * (UBMR + 1) / (UBIR+1))* 如果要设置波特率为 115200,则使用如下参数:* RefFreq = 80MHz,寄存器 UART_UFCR 的 RFDIV[9:7] = 0b101, 表示 1 分频* UBMR = 3124* UBIR = 71* 因此,波特率 = 80000000 / (16 * (3124 + 1) / (71 + 1))* = 80000000 / (16 * 3125 / 72)* = (80000000 * 72) / (16 * 3125)* = 115200*/UART1->UFCR = (0b101 << 7); /* refFreq = ipg_clk / 1 = 80MHz */UART1->UBIR = 71;UART1->UBMR = 3124;
#endif/* 也可以通过以下函数计算并设置波特率 */
// #if 0uart_set_baudrate(UART1, 115200, 80000000); /* 设置波特率 */
// #endif/* 串口使能 */uart_enable(UART1);
}/* 通过串口发送一个字符 */
void putc(unsigned char c)
{/* 等待上一次发送完成 */while (!(UART1->USR2 & 0x00000008)) {}/* 发送字符:将字符值(ASCII 码)写入 UTXD 寄存器 */UART1->UTXD = (c & 0xFF);
}/* 发送字符串 */
void puts(char *str)
{char *p = str;while (*p){putc(*p);p++;}
}/* 接收一个字符 */
unsigned char getc(void)
{/* 等待接收完成 */while (!(UART1->USR2 & 0x00000001)) {}/* 返回接收到的字符 */return UART1->URXD;
}/* 该函数仅用于防止编译器报错 */
void raise(int sig_nr)
{}
相关文章:

[IMX] 05.串口 - UART
目录 1.通信格式 2.电平标准 3.IMX UART 模块 4.时钟寄存器 - CCM_CSCDR1 5.控制寄存器 5.1.UART_UCR1 5.2.UART_UCR2 5.3.UART_UCR3 6.状态寄存器 6.1.UART_USR1 6.2.UART_USR2 7.FIFO 控制寄存器 - UART_UFCR 8.波特率寄存器 8.1.分母 - UART_UBIR 8.2.分子 -…...

使用Tkinter写一个发送kafka消息的工具
文章目录 背景工具界面展示功能代码讲解运行环境创建GUI程序搭建前端样式编写功能实现代码 背景 公司是做AR实景产品的,近几年无人机特别的火,一来公司比较关注低空经济这个新型领域,二来很多政企、事业单位都采购了无人机用于日常工作。那么…...

MongoDB 与 EF Core 深度整合实战:打造结构清晰的 Web API 应用
题纲 MongoDB 字符串连接 URIC# 连接字符串实例 实现一个电影信息查询 demo创建项目创建实体实现 DbContext 上下文仓储实现服务实现控制器实现服务注册快照注入数据库连接配置1. 注册配置类2. 注入 IOptionsSnapshot<MongoDbSettings>3. 配置文件 appsettings.json 示例…...
JAVA|后端编码规范
目录 零、引言 一、基础 二、集合 三、并发 四、日志 五、安全 零、引言 规范等级: 【强制】:强制遵守,来源于线上历史故障,将通过工具进行检查。【推荐】:推荐遵守,来源于日常代码审查、开发人员反馈…...

重写B站(网页、后端、小程序)
1. 网页端 1.1 框架 Vue ElementUI axios 1.2 框架搭建步骤 搭建Vue 1.3 配置文件 main.js import {createApp} from vue import ElementUi from element-plus import element-plus/dist/index.css; import axios from "axios"; import router from…...

文档债务拖累交付速度?5大优化策略文档自动化
开发者在追求开发速度的过程中,往往会忽视文档的编写,如省略设计文档、代码注释或API文档等。这种做法往往导致在后期调试阶段需要花费三倍以上的时间来理解代码逻辑,进而形成所谓的文档债务,严重拖累交付速度并造成资源浪费。而积…...

【数据结构与算法】LeetCode 每日三题
如果你已经对数据结构与算法略知一二,现在正在复习数据结构与算法的一些重点知识 ------------------------------------------------------------------------------------------------------------------------- 关注我🌈,每天更新总结文章…...

基于深度学习的电力负荷预测研究
一、深度学习模型框架 在当今数字化时代,基于深度学习的电力负荷预测研究正成为保障电力系统稳定、高效运行的关键领域。其模型构建是一个复杂而精妙的过程,涉及多学科知识与前沿技术的融合应用。首先,要明确电力负荷预测的目标,…...

篇章十 消息持久化(二)
目录 1.消息持久化-创建MessageFileManger类 1.1 创建一个类 1.2 创建关于路径的方法 1.3 定义内部类 1.4 实现消息统计文件读写 1.5 实现创建消息目录和文件 1.6 实现删除消息目录和文件 1.7 实现消息序列化 1. 消息序列化的一些概念: 2. 方案选择…...

【IDEA】删除/替换文件中所有包含某个字符串的行
目录 前言 正则表达式 示例 使用方法 前言 在日常开发中,频繁地删除无用代码或清理空行是不可避免的操作。许多开发者希望找到一种高效的方式,避免手动选中代码再删除的繁琐过程。 使用正则表达式是处理字符串的一个非常有效的方法。 正则表达式 …...

基于深度学习的不良驾驶行为为识别检测
一.研究目的 随着全球汽车保有量持续增长,交通安全问题日益严峻,由不良驾驶行为(如疲劳驾驶、接打电话、急加速/急刹车等)引发的交通事故频发,不仅威胁生命财产安全,还加剧交通拥堵与环境污染。传统识别方…...
FD+Mysql的Insert时的字段赋值乱码问题
方法一 FDQuery4.SQL.Text : INSERT INTO 信息表 (中心, 分组) values(:中心,:分组); FDQuery4.Params[0].DataType : ftWideString; //必须加这个数据类型的定义,否则会有乱码 FDQuery4.Params[1].DataType : ftWideString; //ftstring就不行,必须是…...

第十周作业
一、CSRF 1、DVWA-High等级 2、使用Burp生成CSRF利用POC并实现攻击 二、SSRF:file_get_content实验,要求获取ssrf.php的源码 三、RCE 1、 ThinkPHP 2、 Weblogic 3、Shiro...

Python操作PDF书签详解 - 添加、修改、提取和删除
目录 简介 使用工具 Python 向 PDF 添加书签 添加书签 添加嵌套书签 Python 修改 PDF 书签 Python 展开或折叠 PDF 书签 Python 提取 PDF 书签 Python 删除 PDF 书签 简介 PDF 书签是 PDF 文件中的导航工具,通常包含一个标题和一个跳转位置(如…...
One-shot和Zero-shot的区别以及使用场景
Zero-shot是模型在没有任务相关训练数据的情况下进行预测,依赖预训练知识。 One-shot则是提供一个示例,帮助模型理解任务。两者的核心区别在于是否提供示例,以及模型如何利用这些信息。 在机器学习和自然语言处理中,Zero-Shot 和…...
微软 Build 2025:开启 AI 智能体时代的产业革命
在 2025 年 5 月 19 日的微软 Build 开发者大会上,萨提亚・纳德拉以 "我们已进入 AI 智能体时代" 的宣言,正式拉开了人工智能发展的新纪元。这场汇聚了奥特曼、黄仁勋、马斯克三位科技领袖的盛会,不仅发布了 50 余项创新产品&#…...

集星獭 | 重塑集成体验:新版编排重构仿真电商订单数据入库
概要介绍 新版服务编排以可视化模式驱动电商订单入库流程升级,实现订单、客户、库存、发票、发货等环节的自动化处理。流程中通过循环节点、判断逻辑与数据查询的编排,完成了低代码构建业务逻辑,极大提升订单处理效率与业务响应速度。 背景…...

多模态大语言模型arxiv论文略读(八十八)
MammothModa: Multi-Modal Large Language Model ➡️ 论文标题:MammothModa: Multi-Modal Large Language Model ➡️ 论文作者:Qi She, Junwen Pan, Xin Wan, Rui Zhang, Dawei Lu, Kai Huang ➡️ 研究机构: ByteDance, Beijing, China ➡️ 问题背景…...
创建Workforce
创建你的Workforce 3.3.1 简单实践 1. 创建 Workforce 实例 想要使用 Workforce,首先需要创建一个 Workforce 实例。下面是最简单的示例: from camel.agents import ChatAgent from camel.models import ModelFactory from camel.types import Model…...
Cribl 中 Parser 扮演着重要的角色 + 例子
先看文档: Parser | Cribl Docs Parser The Parser Function can be used to extract fields out of events or reserialize (rewrite) events with a subset of fields. Reserialization will preserve the format of the events. For example, if an event contains comma…...

WebSocket 从入门到进阶实战
好记忆不如烂笔头,能记下点东西,就记下点,有时间拿出来看看,也会发觉不一样的感受. 聊天系统是WebSocket的最佳实践,以下是使用WebSocket技术实现的一个聊天系统的关键代码,可以通过这些关键代码ÿ…...

CSS:vertical-align用法以及布局小案例(较难)
文章目录 一、vertical-align说明二、布局案例 一、vertical-align说明 上面的文字介绍,估计大家也看不懂 二、布局案例...
Linux 正则表达式 扩展正则表达式 gawk
什么是正则表达式 正则表达式是我们所定义的模式模板(pattern template),Linux工具用它来过滤文本。Linux工具(比如sed编辑器或gawk程序)能够在处理数据时,使用正则表达式对数据进行模式匹配。如果数据匹配…...

Java转Go日记(五十四):gin路由
1. 基本路由 gin 框架中采用的路由库是基于httprouter做的 地址为:https://github.com/julienschmidt/httprouter package mainimport ("net/http""github.com/gin-gonic/gin" )func main() {r : gin.Default()r.GET("/", func(c …...

【解决】自己的域名任何端口都访问不到,公网地址正常访问,服务器报错500。
一、问题描述 后端项目部署在服务器上,通过域名访问接口服务器报错500,通过浏览器访问域名的任何端口都是无法访问此网站。 但是通过公网地址访问是可以正常访问到的,感觉是域名出现了问题 二、解决过程 先说结论:问题原因是…...
探秘鸿蒙 HarmonyOS NEXT:Navigation 组件的全面解析
鸿蒙 ArkTS 语言中 Navigation 组件的全面解析 一、引言 本文章基于HarmonyOS NEXT操作系统,API12以上的版本。 在鸿蒙应用开发中,ArkTS 作为一种简洁、高效的开发语言,为开发者提供了丰富的组件库。其中,Navigation 组件在构建…...
订单导入(常见问题和sql)
1.印章取行,有几行取几行 union select PARAM07 name, case when regexp_count(PO_PARAM_20, chr(10)) > 0 then substr(PO_PARAM_20, 0, instr(PO_PARAM_20, chr(10)) - 1) else PO_PARAM_20 end value,PO_ID …...
PyTorch中diag_embed和transpose函数使用详解
torch.diag_embed 是 PyTorch 中用于将一个向量(或批量向量)**嵌入为对角矩阵(或批量对角矩阵)**的函数。它常用于图神经网络(GNN)或线性代数中生成对角矩阵。 函数原型 torch.diag_embed(input, offset0,…...
算法分析与设计实验:找零钱问题的贪心算法与动态规划解决方案
在计算机科学中,贪心算法和动态规划是两种常用的算法设计策略。本文将通过一个经典的找零钱问题,详细讲解这两种算法的实现和应用。我们将会提供完整的C代码,并对代码进行详细解释,帮助读者更好地理解和掌握这两种算法。 问题描述…...

制作 MacOS系统 の Heic动态壁纸
了解动态桌面壁纸 当macOS 10.14发布后,会发现系统带有动态桌面壁纸,设置后,我们的桌面背景将随着一天从早上、到下午、再到晚上的推移而发生微妙的变化。 虽然有些软件也有类似的动态变化效果,但是在新系统中默认的HEIC格式的动…...