六、 通用异步收发器UART
6.1 UART简介
UART(Universal Asynchronous Receiver/Transmitter,通用异步收发传输器)是一种用于异步串行通信的硬件设备。它通过两根信号线(TX 和 RX)实现全双工通信,广泛应用于微控制器、计算机和外设之间的数据传输,尽管传输速率和距离有限,但在短距离通信中应用广泛。
全双工:一种通信方式,允许数据在双方之间同时双向传输。
6.2 UART工作原理
6.2.1发送信号:
发送端将并行数据转换为串行数据,按数据帧格式通过 TX 线发送。
6.2.2接收信号:
接收端检测起始位,按波特率采样数据位,校验后存储有效数据。
6.2.3数据帧结构:
起始位:标志数据帧的开始,通常为低电平。
数据位:数据位是UART帧中实际传输的数据部分。数据位的数量可以是5、6、7或8位,最常见的设置是8位。每个数据位可以是0或1,表示二进制数据的一部分。数据位的数量决定了每次传输的数据量。例如,8位数据位可以传输一个完整的ASCII字符。
校验位(可选):用于错误检测,可以是奇校验、偶校验或无校验。将数据位加上校验位,1的位数为偶数(偶校验),1的位数4为奇数(奇校验)。
停止位:标志数据帧的结束,通常为高电平。
6.2.4 波特率
由于UART异步通信,数据传输时间需要确定。同一字符内相邻位间的时间间隔是确定的,这涉及到UART传输速率的概念—波特率
波特率的单位是bps,全称是bit per second,意为每秒钟传输的bit数量。
波特率9600bps,代表每秒钟传输bit的数量为9600,那么传输1bit数据的时间就是1/9600=104us,波特率115200bps,代表传输1bit数据的时间是8us。
6.3 UART寄存器
6.3.1 接收缓存寄存器 U0RBR
包含最早接收到的字符,先接收LSB(最低有效位,第0位),然后依次接收8位,如果不足8位,MSB用0填充。
while((LPC_UART -> LSR & 0x01) == 0); // 等待接收标志置位
data_buf = LPC_UART -> RBR; // 保存接收到的数据
6.3.2 发送保持寄存器 U0THR
Tx FIFO 中的最高字节。 它是Tx FIFO中的最新字符,通过总线接口写入, LSB作为发送的第一位。
LPC_UART -> THR = data; // 发送数据
while((LPC_UART -> LSR & 0x40) == 0); // 等待数据发送完毕
6.3.3 中断使能寄存器 U0IER
U0IER用于使能4个UART中断源
位 | 1开启中断,0禁止中断 |
0 | 接收中断使能,还控制着字符接收超时中断 |
1 | 发送中断使能,THRE中断 |
2 | 接收线状态中断使能,使能UART的Rx线线状态中断 |
8 | 自动波特率结束中断 |
9 | 自动波特率超时中断 |
其他 | 保留 |
6.3.4 中断标志寄存器 U0IIR
位 | 功能描述 |
0 | 中断标志,U0IIR[0]为低电平有效 0至少有一个中断在等待处理 1没有等待处理的中断 |
3:1 | 中断标志 011:接收线状态(RLS) 010:接收数据可用(RDA) 110:字符超时指示器(CTI) 001:THRE中断 000:MODEM中断 |
7:6 | FIFO使能,等效于U0FCR[0] |
8 | 自动波特率中断结束标志 |
9 | 自动波特率超时中高端 |
其他 | 保留 |
根据U0IIR[3:0]的状态中断处理程序救恩那个确定中断源以及如何有效清除中断
在推出中断服务程序之前,必须读取U0IIR来清除中断
U0IIR位[3:0] | 中断原因 | 复位操作 |
0110RLS接收线状态 | 溢出错误OE、奇偶错误PE、帧错误FE、间隔中断BI | 读U0LSR复位 |
0100RDA接收数据 | 接收数据可用或达到FIFO触发点 | 读U0LSR复位或者触发条件不足会自动复位 |
1100CT1字符超时 | Rx FIFO中有字符,并且有一段时间没有字符输入或移出 | U0RBR读操作复位 |
0010THRE | 发送FIFO空 | U0IIR读操作复位或者THR写操作复位 |
6.3.5 FIFO控制寄存器 U0FCR
控制Rx FIFO和Tx FIFO
位 | 功能 写1进行相应操作 |
0 | FIFO使能 1使能 0禁用 该位任意变化会使FIFO清空 |
1 | Rx FIFO 复位 |
2 | Tx FIFO复位 |
7:6 | 这两个位决定了Rx FIFO激活前必须写入的字符数量 00:1字节 01:4字节 10:8字节 11:14字节 |
其他 | 保留 |
6.3.6 线控制寄存器 U0LCR
决定了要发送和接收的数据字符格式
位 | 描述 | |
1:0 | 子长度选择 数据位个数(不包括校验位) | 00:5位字符长度 01:6位字符长度 10:7位字符长度 11:8位字符长度 |
2 | 停止位 | 0:1个停止位 1:2个停止位 |
3 | 奇偶校验使能 | 1:使能 |
5:4 | 奇校验:一个字节中1的个数为奇数 偶校验:一个字节中1的个数为偶数 不满足的在校验位置1 | 00:奇校验 01:偶校验 10:强制1奇偶校验 // 强制校验位为1 11:强制0奇偶校验 |
6 | 间隔控制 | 为1时强制使输出引脚UART TXD为逻辑0 |
7 | 输出锁存访问位 | 1使能除数锁存器的访问 |
31:8 | 保留 |
6.3.7 线状态寄存器 U0LSR
位 | 1有效0无效 |
0 | U0RBR包含有效数据 |
1 | 溢出错误OE |
2 | 奇偶错误PE |
3 | 帧错误FE |
4 | 间隔中断BI |
5 | 发送FIFO空 |
6 | 0:U0THR或U0TSR包含有效数据 1:发送器为空 |
7 | 至少一个Rx FIFO错误 |
31:8 | 保留 |
6.3.8 高速缓存寄存器 U0SCR
就光存点东西,对UART无影响
位 | |
7:0 | 可读可写的字节 |
6.3.9 除数锁存LSB和MSB寄存器 U0DLL 和 U0DLM
波特率发生器的一部分,与小数分频器一起使用,来分频UART_PCLK时钟以产生波特率时钟
LSB和MSB分别[7:0]位存数
在不适用小数分频器的情况下,目标波特率为
U0DLM:U0DLL 是U0DLM当高8位和U0DLL当低8位拼接成的16位除数
(0x0000被当成0x0001,除数不为0)
示例代码如下:
LPC_UART -> LCR = 0x80; // 使能除数锁存访问位
LPC_UART -> DLM = Fpclk / 16 / baud / 256;
LPC_UART -> DLL = Fpclk / 16 / baud % 256;
6.3.10 小数分频寄存器 U0FDR
3:0 | DIVADDVAL 产生波特率的预分频除数值,为0看公式就知道没作用 |
7:4 | MULVAL 波特率预分频乘数值,必须大于等于1 |
31:8 | 保留 |
小数分频系数
使用小数分频后,波特率计算公式为
需要满足的数值条件:
1、0<MULVAL<=15
2、0<=DIVADDVAL<15
3、DIVADDVAL < MULVAL
这里有个算法来设置UART分频器,根据要求的波特率和时钟频率带入算法得到FRest的值,查表找近似的MULVAL,DIVADDVAL,再根据公式反算出MSB和LSB
6.4 简单收发
实现简单收发
软件使用微软商店的串口调试助手,或者XCOM什么的
移植上次的工程,新建两个文件即可
main.c
#include <LPC11xx.h>
#include "LED.h"
#include "Button.h"
#include "TIMER.h"
#include "UART.h"
#include "string.h"int main(void)
{LED_Init();LED_ON();UART_Init();// 定义要发送的数据char message[] = "Hello, UART!";// 计算数据长度,不包括结束符 '\0'int length = strlen(message);// 调用UART_Send函数发送数据UART_Send(message, length); while (1){}
}
UART.c
注释掉的部分为发送中断,不如直接发送,少用
#include "UART.h"
#include <string.h>
#include <stdbool.h>
uint8_t SendBuf[BUFFER_SIZE];
uint8_t RcvBuf[BUFFER_SIZE];void UART_Init()
{LPC_SYSCON->SYSAHBCLKCTRL |= (1UL << 6) | (1UL << 16); //使能GPIO和IO配置时钟LPC_IOCON->PIO1_6 = (1UL << 0); // RxDLPC_IOCON->PIO1_7 = (1UL << 0); // TxDLPC_SYSCON->SYSAHBCLKCTRL |= (1UL << 12); // 使能UART时钟LPC_SYSCON->UARTCLKDIV = (4UL << 0); // CCLK除以4LPC_UART->LCR = 0x83; //0b 1000 0011 使能对除数锁存寄存器的访问 无校验 停止位1, 数据位8// 根据小数分频流程,DLest = 4 则 低八位为4,高八位为0LPC_UART->DLL = 4; LPC_UART->DLM = 0;LPC_UART->FDR = 0x85; //FR 1.627 DIVADDVAL 5, MULVAL 8 查表LPC_UART->LCR = 0x03; // DLAB = 0LPC_UART->IER = 0x01; // 开启接收中断 0位接收LPC_UART->FCR = 0x81; // 8B触发,即接收到8字节触发RDA中断NVIC_EnableIRQ(UART_IRQn); // 开串口中断
}volatile int send_count = 0;
volatile int send_index = 0; // 当前发送索引
volatile bool send_complete = false; // 发送完成标志
volatile int rcv_index = 0; // 接收索引发送数据函数
//void UART_Send(uint8_t data[], int length)
//{
// // ... 拷贝数据到发送缓冲区 ...
// int i;
// send_index = 0;
// send_count = length;
// send_complete = false;
//
// if (length > BUFFER_SIZE)
// length = BUFFER_SIZE; // 限制发送数据长度// for (i = 0; i < length; i++)
// SendBuf[i] = data[i]; // 将数据拷贝到发送缓冲区
//
// send_index = 0; // 重置发送索引
// send_complete = false; // 重置发送完成标志// // 启动发送
// LPC_UART->THR = SendBuf[send_index++]; // 发送第一个字节// // 使能发送中断 (假设是通过设置某个寄存器实现的)
// LPC_UART->IER |= (1 << 1); // 使能 THRE 中断
//}/*
*发送字符串
*/
void UART_Send(char str[], int lenght)
{int i;for(i = 0; i < lenght; i ++){LPC_UART->THR= str[i]; while((LPC_UART->LSR & 0X40) == 0);//等待数据发送完成}
}// 检查发送状态
bool UART_IsSendComplete(void)
{return send_complete; // 返回发送是否完成的状态
}void UART_IRQHandler(void)
{int i;switch(LPC_UART->IIR & 0x0f){
// case 0x02: // THRE中断 即UART发送中断
// if (send_count > 0) {
// LPC_UART->THR = SendBuf[send_index++];
// send_count--;
// } else {
// // 发送完成
// LPC_UART->IER &= ~(1 << 1); // 禁用 THRE 中断
// send_complete = true;
// }
// break;case 0x04: // RDA(接收数据可用)中断// 读取最多8字节数据,直到接收缓冲区为空或读取完8字节for(i = 0; i < 8 && (LPC_UART->LSR & 0x01) == 1; i++) RcvBuf[i] = LPC_UART->RBR; // 从接收缓冲区读取数据并保存到RcvBufUART_Send((char *)RcvBuf, i); // 将接收到的数据通过UART发送回去break;case 0x0c: // CTI(字符超时)中断// 读取接收缓冲区中的所有数据,直到缓冲区为空for(i = 0; (LPC_UART->LSR & 0x01) == 1; i++)RcvBuf[i] = LPC_UART->RBR; // 从接收缓冲区读取数据并保存到RcvBufUART_Send((char *)RcvBuf, i); // 将接收到的数据通过UART发送回去break;default: break;}}
UART.h
#ifndef _UART_H_
#define _UART_H_#include "LPC11XX.H"#define BUFFER_SIZE 40
extern uint8_t SendBuf[BUFFER_SIZE];
extern uint8_t RcvBuf[BUFFER_SIZE];
extern uint8_t flag;
void UART_Init(void);
//void UART_Send(uint8_t data[],int lenght);
void UART_Send(char str[],int lenght);#endif
最后效果如下,发什么收什么
相关文章:
六、 通用异步收发器UART
6.1 UART简介 UART(Universal Asynchronous Receiver/Transmitter,通用异步收发传输器)是一种用于异步串行通信的硬件设备。它通过两根信号线(TX 和 RX)实现全双工通信,广泛应用于微控制器、计算机和外设之…...
基于Kotlin中Flow扩展重试方法
最近项目中统一采用Kotlin的Flow来重构了网络请求相关代码。 目前的场景是,接口在请求的时候需要一个accessToken值,因为此值会过期或者不存在,需要刷新,因此最终方案是在使用Flow请求的时候先获取accessToken值然后再进行接口请求…...
在 Open WebUI+Ollama 上运行 DeepSeek-R1-70B 实现调用
在 Open WebUI Ollama 上运行 DeepSeek-R1-70B 实现调用 您可以使用 Open WebUI 结合 Ollama 来运行 DeepSeek-R1-70B 模型,并通过 Web 界面进行交互。以下是完整的部署步骤。 1. 安装 Ollama Ollama 是一个本地化的大模型管理工具,它可以在本地运行 …...
速度超越DeepSeek!Le Chat 1100tok/s闪电回答,ChatGPT 4o和DeepSeek R1被秒杀?
2023年,当全球科技界还在ChatGPT引发的AI狂潮中沉浮时,一场来自欧洲的"静默革命"正悄然改变游戏规则。法国人工智能公司Mistral AI推出的聊天机器人Le Chat以"比ChatGPT快10倍"的惊人宣言震动业界,其背后承载的不仅是技术…...
如何使用C++将处理后的信号保存为PNG和TIFF格式
在信号处理领域,我们常常需要将处理结果以图像的形式保存下来,方便后续分析和展示。C提供了多种库来处理图像数据,本文将介绍如何使用stb_image_write库保存为PNG格式图像以及使用OpenCV库保存为TIFF格式图像。 1. PNG格式保存 使用stb_ima…...
2 CXX-Qt #[cxx_qt::bridge] 宏指南
#[cxx_qt::bridge] 宏是用于在 Rust 中创建一个模块,该模块能够桥接 Rust 和 Qt(通过 C)之间的交互。它允许你将 Rust 类型暴露给 Qt 作为 QObject、Q_SIGNAL、Q_PROPERTY 等,同时也能够将 Qt 的特性和类型绑定到 Rust 中…...
PHP函数介绍—get_headers(): 获取URL的响应头信息
概述:在PHP开发中,我们经常需要获取网页或远程资源的响应头信息。PHP函数get_headers()能够方便地获取目标URL的响应头信息,并以数组形式返回。本文将介绍get_headers()函数的用法,以及提供一些相关的代码示例。 get_headers()函…...
C#树图显示目录下所有文件以及文件大小(使用Stack元组来替换递归)
接上篇 C#树图显示目录下所有文件以及文件大小_c# 查看文件夹里面有多少文件-CSDN博客 上一篇我们使用递归的方法来实现绑定目录和文件到树图中,关键程序代码如下: 这里我们使用Stack的方式非递归方法来实现绑定目录和文件到树图: /// <summary>/// 递归方法ÿ…...
计算机毕业设计Python+Spark知识图谱医生推荐系统 医生门诊预测系统 医生数据分析 医生可视化 医疗数据分析 医生爬虫 大数据毕业设计 机器学习
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
机器学习:朴素贝叶斯分类器
贝叶斯决策论是概率框架下实施决策的基本方法,对分类任务来说,在所有相关概率都已知的理想情形下,贝叶斯决策论考虑如何基于这些概率和误判损失来选择最优的类别标记。 贝叶斯定理是贝叶斯决策论的基础,描述了如何根据新的证据更新先验概率,贝叶斯定理&…...
解决 keep-alive 缓存组件中定时器干扰问题
当使用 keep-alive 缓存组件时,组件中的定时器可能会在组件被缓存后继续运行,从而干扰其他组件的逻辑。为了避免这种情况,可以通过以下方法解决: 1. 在组件的 deactivated 钩子中清理定时器 keep-alive 为缓存的组件提供了 acti…...
1-portal认证功能
很多时候公共网络需要提供安全认证功能,比如我们去星巴克或者商场、酒店,我们连接wifi上网的时候, 需要认证后才可以上网。 用户可以主动访问已知的Portal认证网站,输入用户名和密码进行认证,这种开始Portal认证的方式…...
Kafka 的消费offset原来是使用ZK管理,现在新版本是怎么管理的?
目录 基于 ZooKeeper 管理消费 offset 原理 缺点 新版本基于内部主题管理消费 offset 原理 优点 示例代码(Java) 在 Kafka 早期版本中,消费者的消费偏移量(offset)是存储在 ZooKeeper 中的,但由于 ZooKeeper 并不适合高频读写操作,从 Kafka 0.9 版本开始,消费偏…...
LabVIEW图像水印系统
图像水印技术在数字图像处理中起着重要作用,它能够保护图像的版权、确保图像的完整性,并提供额外的信息嵌入。本项目旨在利用LabVIEW开发一个图像水印系统,实现图像水印的嵌入和提取功能,为数字图像处理提供便捷的工具。 一、项目…...
Bash (Bourne-Again Shell)、Zsh (Z Shell)
文章目录 1. 历史背景2. 主要区别3. 功能对比自动补全插件和主题路径扩展提示符定制 4. 性能5. 使用场景6. 如何切换 Shell7. 总结 以下是 Bash 和 Zsh 之间的主要区别,列成表格方便对比: 特性BashZsh默认Shell大多数Linux发行版默认ShellmacOS默认She…...
iOS AES/CBC/CTR加解密以及AES-CMAC
感觉iOS自带的CryptoKit不好用,有个第三方库CryptoSwift还不错,好巧不巧,清理过Xcode缓存后死活下载不下来,当然也可以自己编译个Framework,但是偏偏不想用第三方库了,于是研究了一下,自带的Com…...
蓝桥杯算法日记|贪心、双指针
3412 545 2928 2128 贪心学习总结: 1、一般经常用到sort(a,an);【a[n]】排序,可以给整数排,也可以给字符串按照字典序排序 2、每次选最优 双指针 有序数组、字符串、二分查找、数字之和、反转字…...
浅谈Java Spring Boot 框架分析和理解
Spring Boot是一个简化Spring开发的框架,它遵循“约定优于配置”的原则,通过内嵌的Tomcat、Jetty或Undertow等容器,使得开发者能够快速构建独立运行的、生产级别的基于Spring框架的应用程序。Spring Boot包含了大量的自动配置功能,…...
【系统架构设计师】操作系统 ③ ( 存储管理 | 页式存储弊端 - 段式存储引入 | 段式存储 | 段表 | 段表结构 | 逻辑地址 的 合法段地址判断 )
文章目录 一、页式存储弊端 - 段式存储引入1、页式存储弊端 - 内存碎片2、页式存储弊端 - 逻辑结构不匹配3、段式存储引入 二、段式存储 简介1、段式存储2、段表3、段表 结构4、段内地址 / 段内偏移5、段式存储 优缺点6、段式存储 与 页式存储 对比 三、逻辑地址 的 合法段地址…...
网络编程-day4-TPC之文件传输
服务器 #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <pthread.h> #include <semaphore.h> #includ…...
定制化APP:开启企业数字化转型新未来
在当今快速发展的数字时代,企业的生存与发展不仅依赖于其传统的运营模式,更需要借助创新的技术手段来提升效率、优化服务并创造价值。而定制化的移动应用程序(简称“定制化APP”)正是实现这一目标的重要工具之一。通过量身定制的应用程序,企业能够更好地满足自身独特的业务…...
JS宏进阶:XMLHttpRequest对象
一、概述 XMLHttpRequest简称XHR,它是一个可以在JavaScript中使用的对象,用于在后台与服务器交换数据,实现页面的局部更新,而无需重新加载整个页面,也是Ajax(Asynchronous JavaScript and XML)…...
点大商城V2-2.6.6源码全开源uniapp +搭建教程
一.介绍 点大商城V2独立开源版本,版本更新至2.6.6,系统支持多端,前端为UNiapp,多端编译。 二.搭建环境: 系统环境:CentOS、 运行环境:宝塔 Linux 网站环境:Nginx 1.21 MySQL 5.…...
Docker的深入浅出
目录 Docker引擎 Docker镜像 (镜像由多个层组成,每层叠加之后,从外部看来就如一个独立的对象。镜像内部是一个精简的操作系统(OS),同时还包含应用运行所必须的文件和依赖包) Docker容器 应用容器化--Docker化 最佳…...
导航守卫router.beforeEach
router.beforeEach 是一个全局前置守卫,在每次路由跳转之前都会触发。 //index.jsrouter.beforeEach((to, from, next) > {// 打印即将要进入的目标路由信息console.log(即将要进入的目标路由信息:, to)// 打印当前正要离开的路由信息console.log(当前正要离开的…...
Perl语言的软件开发工具
Perl语言的软件开发工具 引言 在当今软件开发的世界中,随着互联网的快速发展和信息技术的不断进步,编程语言和开发工具的选择变得尤为重要。特别是在处理大量数据、实现快速原型以及网络编程等领域,Perl语言凭借其独特的优势而受到广泛青睐…...
在 Linux 系统下,解压 `.tar.gz`
在 Linux 系统下,解压 .tar.gz 文件通常使用 tar 命令。.tar.gz 文件是一种压缩归档文件,它首先使用 tar 命令将多个文件打包为一个 .tar 文件,然后再使用 gzip 压缩生成 .tar.gz 文件。 解压 .tar.gz 文件的命令 要解压 .tar.gz 文件,可以使用以下命令: tar -xzvf fil…...
Deepseek
1.Deepseek是什么? deepseek是一家人工智能科技公司所开发的能够进行人工智能对话的一个应用,它的主要目标是大规模的研发与应用。deepseek-R1是它的开源推理模型,主要负责处理复杂任务并且可以免费使用。 2.Deepseek可以做什么? Deepseek…...
oracle如何查询历史最大进程数?
oracle如何查询历史最大进程数? SQL> desc dba_hist_resource_limitName Null? Type---------------------------------------------------- -------- ------------------------------------SNAP_ID …...
强一致性算法:Raft
目录 什么是 Raft 算法? Leader的选举 投票分裂后的选举过程 Raft算法日志复制过程 修复不一样的日志 数据安全性的保证 什么是 Raft 算法? Raft 算法是一种是一种用于管理复制日志的强一致性算法,用于保证分布式系统中节点数据的一致…...
8.flask+websocket
http是短连接,无状态的。 websocket是长连接,有状态的。 flask中使用websocket from flask import Flask, request import asyncio import json import time import websockets from threading import Thread from urllib.parse import urlparse, pars…...
是德科技 | PCIe 7.0 互连— PCIe的尽头会是光吗?
伴随大语言模型和相关训练系统迅猛增长、对非结构化数据处理的需求急剧上升,市场对算力的需求也是呈指数级增加。PCIe作为计算机和服务器中使用广泛的高速数据传输技术发展迅猛,今年4月份PCI-SIG已经批准 Draft 0.5版基础规范,目前0.7版本基础…...
Aitken 逐次线性插值
Aitken 逐次线性插值 用 Lagrange 插值多项式 L n ( x ) L_n(x) Ln(x)计算函数近似值时,如需增加插值节点,那么原来算出的数据均不能利用,必须重新计算。为克服这个缺点,可用逐次线性插值方法求得高次插值。 令 I i 1 , i 2…...
Orange 开源项目介绍
Orange 开源项目 项目兼容单体架构与微服务架构两种模式,集成了包括部门管理、用户管理、菜单配置、角色分配、字典维护以及日志记录在内的多种系统管理功能。 项目体验 Orange 官网: http://hengzq.cn在线体验: http://tiny.hengzq.cn项目文档: http://hengzq.cn/…...
【高级架构师】多线程和高并发编程(三):锁(下)深入ReentrantReadWriteLock
文章目录 4、深入ReentrantReadWriteLock4.1 为什么要出现读写锁4.2 读写锁的实现原理4.3 写锁分析4.3.1 写锁加锁流程概述4.3.2 写锁加锁源码分析4.3.3 写锁释放锁流程概述&释放锁源码 4.4 读锁分析4.4.1 读锁加锁流程概述4.4.1.1 基础读锁流程4.4.1.2 读锁重入流程4.4.1.…...
如何在Node.js中使用中间件处理请求
Node.js作为一种基于事件驱动、非阻塞I/O模型的运行环境,广泛用于构建高性能的Web应用。在Node.js中,处理中间件是处理HTTP请求和响应的一个常见方式,特别是在使用Express框架时,中间件扮演着至关重要的角色。本文将介绍如何在Nod…...
Kotlin 2.1.0 入门教程(十三)异常、Nothing
创建自定义异常 可以通过创建继承内置 Exception 类来定义自定义异常。这允许你创建更符合应用程序需求的特定错误类型。 要创建一个自定义异常,可以定义一个继承 Exception 的类: class MyException : Exception("My message")在这个例子中…...
Unity 打造游戏资源加密解密系统详解
在游戏开发中,保护游戏资源不被轻易破解和盗用至关重要。本文将详细介绍如何在 Unity 中打造一个游戏资源加密解密系统,并提供技术详解和代码实现。 一、加密方案选择 1.1 对称加密 优点: 加密解密速度快,适合加密大量数据。 缺点: 密钥管…...
HarmonyOS Next 方舟字节码文件格式介绍
在开发中,可读的编程语言要编译成二进制的字节码格式才能被机器识别。在HarmonyOS Next开发中,arkts会编译成方舟字节码。方舟字节码长什么样呢?我们以一个demo编译出的abc文件: 二进制就是长这样,怎么去理解呢&…...
二层、三层小总结
一、网络隔离 1、物理隔离。搭建两套完全独立的网络,这也是最土豪最安全的做法。 2、二层隔离。使用Vlan隔离,使用不同Vlan或者Pvlan等。 3、三层隔离。路由隔离。 4、设备特性隔离。比如端口隔离swichport protected,或者ACL等。 5、安全…...
Window系统通过Docker本地安装ollama和deepseek
在 Windows 系统上安装 Ollama 和 DeepSeek 的步骤如下: 安装 Ollama 安装 WSL(Windows Subsystem for Linux): 如果还没有安装 过WSL的(安装过的你直接跳过就行了),可以按照以下步骤进行安装&…...
云原生后端|实践?
云原生(Cloud Native)是一种构建和运行应用程序的方法,它充分利用云计算的优势,包括弹性、可扩展性、高可用性和自动化运维。云原生后端开发通常涉及微服务架构、容器化、持续集成/持续部署(CI/CD)、服务网…...
1.1 Spring生态全景解读
1.1 Spring生态全景解读 1.1.1 Spring Framework发展历程与技术演进(深度解析版) 技术演进路线图与里程碑事件: 2003.10 - Spring 1.0 发布→ 核心特性:XML Bean配置、AOP基础支持→ 企业痛点:解决EJB复杂性问题&am…...
跨境商家系统搭建||反向海淘系统的搭建
反向海淘系统的搭建主要涉及以下几个方面的工作: 一、需求分析 在搭建反向海淘系统之前,首先需要进行需求分析。这包括明确系统的目标用户群体,了解他们的购物习惯、需求和期望。同时,还需要分析市场上的竞争对手,了…...
LeetCode数学相关算法题(1)【C语言版】
2520. 统计能整除数字的位数 给你一个整数 num ,返回 num 中能整除 num 的数位的数目。 如果满足 nums % val 0 ,则认为整数 val 可以整除 nums 。 示例 1: 输入:num 7 输出:1 解释:7 被自己整除&…...
云消息队列 ApsaraMQ Serverless 演进:高弹性低成本、更稳定更安全、智能化免运维
如今,消息队列已成为分布式架构中不可或缺的关键服务,为电商、物联网、游戏和教育等行业,提供了异步解耦、集成、高性能和高可靠的核心价值。 过去一年,我们发布了云消息队列 ApsaraMQ 全系列产品 Serverless 化,面向…...
github - 使用
注册账户以及创建仓库 要想使用github第一步当然是注册github账号了, github官网地址:https://github.com/。 之后就可以创建仓库了(免费用户只能建公共仓库),Create a New Repository,填好名称后Create,之后会出现一些仓库的配置信息,这也是一个git的简单教程。 Git…...
cmos晶体管
CMOS晶体管 一、PMOS和NMOS介绍 PN结: P-type和N-type组合在一起,变成一个PN结(二极管)。在P端给高电压,N端给低电压时,可以导通。否则不导通。 NMOS:有四个端口:gate、source、…...
pip3命令全解析:Python3包管理工具的详细使用指南
pip3命令全解析:Python3包管理工具的详细使用指南 一、基本使用二、升级和更新三、其他常用命令四、换源操作五、注意事项六、帮助信息pip3命令使用说明 pip3 是 Python 3 的包管理工具,用于安装、升级和卸载 Python 3 的包。以下是 pip3 的常用命令及详细说明: 一、基本使…...
统计 product 表中 detail 字段包含 xxx 的产品数量
您可以使用以下 SQL 查询语句来统计 product 表中 detail 字段包含 oss.kxlist.com 的产品数量: SELECT COUNT(*) FROM product WHERE INSTR(detail, oss.kxlist.com) > 0;mysql> SELECT COUNT(*)-> FROM product-> WHERE INSTR(detail, oss.kxlist.co…...