基于OpenMV与STM32的数据通信项目(代码开源)

news2024/11/21 2:36:17

前言:本文为手把手教学 OpenMV 与 STM32 的数据通信项目教程,本教程使用 STM32F103C8T6 OpenMV 进行操作。 OpenMV 是非常强大的计算机视觉实现工具,自身提供了非常多的视觉项目案例,编程与使用门槛极低。为了进一步增强作品的功能与创意性,往往需要将 OpenMV 的视觉与 STM32 的控制融合,本篇博客将为读者朋友教学使用 UART 串口构建两者的快速数据通信。希望本篇博客能给读者朋友的工程项目或科研生活给予些许帮助,敬礼Respect!!!(篇末代码开源!)

实验硬件:OpenMV;STM32F103C8T6;0.96寸OLED;杜邦线若干

项目实物图:

项目效果图:

引脚连接:

OpenMV 与 STM32 引脚:

OpenMV.Rx -> STM32.PA9

OpenMV.Tx -> STM32.PA10

STM32 与 0.96寸OLED 引脚:

STM32.PA6 -> OLED.SCL

STM32.PA7 -> OLED.SDA

STM32.VCC -> OLED.VCC

STM32.GND -> OLED.GND

一、OpenMV概述

1.1 OpenMV

OpenMV 是一个开源、功能强大的机器视觉模块。通常以 STM32F767/STM32H743/STM32F427 为 CPU 核心,集成 OV7725 等欧姆龙系列摄像头芯片,在小巧的硬件模块上,用C语言高效地实现了核心机器视觉算法,并提供 MicroPython 编程接口,拥有专属的编程平台 OpenMV IDE 程序。创客或电赛选手往往忠爱使用 OpenMV 为自己的产品和发明增加有特色的竞争力。作者补充:实话实说目前 OpenMV 在计算机视觉上的帮助确实很大,可是考虑到如今的 OpenMV 的售价是非常不合适的!

OpenMV 的整体设计小巧,使用门槛低,使得它拥有很强的 "视觉DIY” 属性OpenMV 还拥有丰富的外设资源,例如:UART、I2C、SPI、PWM、ADC、DAC以及GPIO等接口,方便扩展外围功能。USB接口用于连接电脑上的集成开发环境 OpenMV IDE,协助完成编程、调试和更新固件等工作。TF卡槽支持大容量的TF卡,可以用于存放程序和保存照片等。

作者推荐 OpenMV 学习网站:

官方网站:Download – OpenMV

OpenMV中国官方代理(星瞳科技):序言 · OpenMV中文入门教程

1.2 OpenMV项目

中国 OpenMV 官方代理是星瞳科技,星瞳科技在其官网提供了超多详细且丰富的 OpenMV 使用案例,例如:特征点检测、测距、扫描识别、寻找色块、模板匹配、颜色形状识别与人脸识别等

上述图片中的案例都是可以借助 OpenMV 进行实现的,当然考虑到 STM32F7/STM32H7 等系列 CPU 算力的上限,可能输出图像像素以及 FPS 并不是特别优秀的。有能力和专研精神的读者朋友可以尝试高级的计算机视觉开发工具,例如:Jeston Nano、K210、K510、RK3568、RK3588与树莓派4/5B系列等(部分产品的性能与算力非常有竞争力)!

补充提醒:本项目中使用 OpenMV 的数字识别作为案例,进行与 STM32 之间的数据通信!

二、博客项目概述

2.1 OpenMV的Mnist数字识别

OpenMV 提供了超级多的计算机视觉的案例,作者选择常用的 mnist 数字识别项目作为 OpenMV 终端处理的事件(电赛送药小车题目与之类似),该案例可以直接通过星瞳科技官网进行获取(老旧版本的 OpenMV 可能需要升级固件才能使用该案例):

案例地址:Mnist数字识别 · OpenMV中文入门教程

作者手上的 OpenMV OpenMV3 R1,CPU 的处理性能非常一般。官方在 OpenMV4 H7 Plus上面运行大概每秒 45 帧,在 OpenMV4 H7上面运行大概每秒 25 帧左右。mnist 数字识别案例使用了 CNN 卷积神经网络进行识别,例程利用 mnis t数字数据集,自行训练神经网络得到手写数字识别神经网络模型,性能和准确率很高(可以直接使用案例的权重文件即可)。

★运行目录前,将官网提供的 mnist 数字识别的 trained.tflite 文件下载到电脑,并复制到 OpenMV 的存储中。

mnist数字识别代码:

# This code run in OpenMV4 H7 or OpenMV4 H7 Plus

import sensor, image, time, os, tf

sensor.reset()                         # Reset and initialize the sensor.
sensor.set_pixformat(sensor.GRAYSCALE)    # Set pixel format to RGB565 (or GRAYSCALE)
sensor.set_framesize(sensor.QVGA)      # Set frame size to QVGA (320x240)
sensor.set_windowing((240, 240))       # Set 240x240 window.
sensor.skip_frames(time=2000)          # Let the camera adjust.

clock = time.clock()
while(True):
    clock.tick()
    img = sensor.snapshot().binary([(0,64)])
    for obj in tf.classify("trained.tflite", img, min_scale=1.0, scale_mul=0.5, x_overlap=0.0, y_overlap=0.0):
        output = obj.output()
        number = output.index(max(output))
        print(number)
    print(clock.fps(), "fps")

案例测试:

2.2 项目整体说明

OpenMV 集成了非常多的库函数,常用的数据通信使用 UART 串口,本篇博客就以 UART 通信为例。

本项目利用 OpenMV 的数字识别案例进行数字识别,将识别到的数字信息通过 OpenMV UART 串口发送至 STM32F103C8T6。而 STM32F103C8T6 通过 I2C 协议将 OpenMV 传输过来的数字信息显示在 0.96 寸的 OLED 屏幕上。该项目的整体实现还是非常简单,特别是计算机视觉的数字识别部分,OpenMV 直接封装为案例,极大地方便研发人员的后续使用。当然,本篇博客最核心部分是 OpenMVSTM32 的通信部分的处理,包含数据包的处理编程!

三、传输数据包协议

3.1 数据包通信概述

传输完全体数据包可以包含:帧头、地址信息、数据类型、数据长度、数据块、校验码、帧尾正常情况下,考虑到传输速率问题不会使用完全体数据包。大多数情况下,工程师仅使用简版数据包:帧头数据字节长度帧尾

传输数据包的过程包含 2 个部分:(1) 数据包编码,上文所说的数据包组成;(2) 数据包解析,下文所说的数据包解析;

传输数据过程中的数据包解析通常有 2 种方式:(1)、中断内部解析;(2)、中断外部解析;

第一种方法:中断服务函数内部直接解析使用,该方法适用于数据帧简单,数据复杂程度低的情况。可以满足中断函数的快进快出,该方法可以使整个项目代码框架简洁,方便后期纠错改正!!!

第二种方法:中断服务函数外部解析使用,该方法适用于数据帧繁杂,数据复杂程度高的情况。该情况下,往往无法满足中断服务函数的快进快出,容易卡死在中断内部。这种情况下,工程师可以在中断中只接收数据,随后通过 extern 全局变量将数据在外部进行解析处理。实际工程中,该方法使用可能性高,希望读者朋友可以完全掌握该技能!!!

本篇博客项目使用中断内部解析数据包的方法,该方法也是作者电赛常用手段之一(部分情况下解析完的数据可能需要数据融合或是滤波处理,该情况使不适合在中断服务函数中解析的)

3.2 数据包传输(HEX方式)

数据包传输方式是机器设备间通信最常见的方法,数据包传输方式一般分为 3 种:(1) 固定包长,含帧头帧尾;(2) 可变包长,含帧头帧尾;(3) 可变包长,含数据字节长度及帧头帧尾;详情如下图所示:

作者补充说明:上图中的帧头为 0xFE,帧尾为 0xEF;这里的帧头和帧尾是可以自定义的,但通常情况下会选择帧头为 0xFE,帧尾为 0xEF,这是为什么呢?

答:通常帧头和帧尾的设计需要避免与通信过程中的数据具有相似性,不然容易导致误把通信数据当初帧头帧尾进行处理,从而解析出错误的数据!当然,复杂的数据包帧头也可以不局限于 1 个字节,读者朋友可以根据自己实际情况设计。作者项目使用直接使用了帧头为 0xFE,帧尾为 0xEF 的数据包进行传输!

四、CubeMX配置

1、RCC配置外部高速晶振(精度更高)——HSE;

2、SYS配置:Debug设置成Serial Wire否则可能导致芯片自锁);

3、USART1配置:设置UART1串口;波特率:115200;开启UART串口中断;

4、I2C配置:设置I2C1与 0.96 寸OLED进行通信;

5、时钟树配置

6、工程配置

五、代码与解析

5.1 OpenMV数据发生端代码

5.1.1 OpenMV的串口数据传输

星瞳科技官网提供了 OpenMV 的串口 UART 的使用案例,升级到最新版固件就可以直接运行。作者使用 CH340 芯片将串口数据上传至电脑终端进行测试(读者朋友搞工程的时候,也建议按部就班的搭建和完善代码流程)。

OpenMV 串口通信代码:

# This code run in OpenMV4 H7 or OpenMV4 H7 Plus

import sensor, image, time, os, tf
from pyb import UART

sensor.reset()                         # Reset and initialize the sensor.
sensor.set_pixformat(sensor.GRAYSCALE)    # Set pixel format to RGB565 (or GRAYSCALE)
sensor.set_framesize(sensor.QVGA)      # Set frame size to QVGA (320x240)
sensor.set_windowing((240, 240))       # Set 240x240 window.
sensor.skip_frames(time=2000)          # Let the camera adjust.

#OpenMV串口UART传输数据
uart = UART(3, 115200)                 # 实例化一个串口3,波特率为115200,必须与STM32接收端保持一致

clock = time.clock()
while(True):
    clock.tick()
    img = sensor.snapshot().binary([(0,64)])
    for obj in tf.classify("trained.tflite", img, min_scale=1.0, scale_mul=0.5, x_overlap=0.0, y_overlap=0.0):
        output = obj.output()
        number = output.index(max(output))
        print(number)
    print(clock.fps(), "fps")
    uart.write("Hello World!\r")

5.1.2 OpenMV发送端完整代码

在上述官方提供的 OpenMV2 个例程代码的基础上结合项目实际情况进行编写代码。OpenMV 只能传输十六进制的数据给 STM32,否则 STM32 将收不到数据,就是单片机和 OpenMV 都能正常和电脑通信,但是两者结合就不能正常通信。十六进制数据的实现主要通过 bytearray() 这个函数,代码格式如下:OUT_DATA =bytearray([0x2C,0x12,cx,cy,cw,ch,0x5B])

代码解析:通过定义 Sending_Data() 函数,进行 OpenMV 端的数据发送。在 mnist 数字识别的 while 函数的 for 循环中将识别到的 number 数据包持续 Sending_Data() 发送到 STM32 开发板上。

mnist.py代码:

# This code run in OpenMV4 H7 or OpenMV4 H7 Plus

import sensor, image, time, os, tf
from pyb import UART

sensor.reset()                         # Reset and initialize the sensor.
sensor.set_pixformat(sensor.GRAYSCALE)    # Set pixel format to RGB565 (or GRAYSCALE)
sensor.set_framesize(sensor.QVGA)      # Set frame size to QVGA (320x240)
sensor.set_windowing((240, 240))       # Set 240x240 window.
sensor.skip_frames(time=2000)          # Let the camera adjust.

#OpenMV串口UART传输数据
uart = UART(3, 115200)                 # 实例化一个串口3,波特率为115200,必须与STM32接收端保持一致

#定义数据包发送函数
def Sending_Data(Num):
    global uart;
    OutData = bytearray([0xFE,0xBC,Num,0xEF])   #构建发送数据的数据包
    uart.write(OutData);   #必须要传入一个字节数组
    
clock = time.clock()
while(True):
    clock.tick()
    img = sensor.snapshot().binary([(0,64)])
    for obj in tf.classify("trained.tflite", img, min_scale=1.0, scale_mul=0.5, x_overlap=0.0, y_overlap=0.0):
        output = obj.output()
        number = output.index(max(output))
        Sending_Data(number)
        print(number)
    print(clock.fps(), "fps")

mnist数字识别数据传输:

5.2 STM32数据接收端代码

5.2.1 0.96寸OLED代码

本篇博客项目中使用 0.96OLED 将 OpenMV 识别的 mnist 数字结果进行输出,0.96 寸的 OLED 驱动代码可以参考作者的另一篇博客。考虑到博客篇幅有限,0.96 OLED 驱动就不详细赘述了,希望读者朋友可以自行掌握!

博客地址:http://t.csdnimg.cn/gDcev

5.2.2 STM32接收端完整代码

代码解析:本篇项目代码中 STM32 接收端关键操作都是依赖于 HAL_UART_RxCpltCallback() 函数实现的。OpenMV STM32 数据传输过程中的解码在中断回调函数中直接通过 OpenMV_Data_Receive() 函数实现。USART1_RXbuff 变量为 USART1 开启后持续传输的数据,将该变量放入 OpenMV_Data_Receive()  进行解码。

★核心函数 OpenMV_Data_Receive() 解析:

OpenMVSTM32 数据传输稍微复杂点的其实就是 STM32 接收端的解码过程,常规情况下 OpenMV 发送端的数据是一组数据包。这组数据包的组成是程序员自己定义的,比如作者 OpenMV 端的数据包格式为:0xFE,0xBC,Num,0xEF。其中,0xFE,0xBC 为帧头Num 为需要解码出的真正数据0xEF 为帧尾

STM32 接收端需要根据 OpenMV 发送端的数据包格式进行解码,HAL_UART_Receive_IT() 函数稳定将接收到的数据赋值 USART1_RXbuff ,通过 OpenMV_Data_Receive() 函数进行解码。根据上述 OpenMV 发送端的代码,可以得出需要首先解码帧头的 0xFE 与 0xBCOpenMV_Data_Receive() 函数中定义 RxBuffer[4] 数组来接收每一帧的数据(作者每一帧数据有 4 个字节数据,读者朋友可以根据实际情况设置数组大小),设置 RxState 状态位来递进判断是否正确接收到目标数据。在成功接收到 2 个帧头数据之后,通过 OLED_ShowNum() 函数将 OpenMV 识别出的数字显示出来。

 关键点:串口接收中断回调函数

/* USER CODE BEGIN PTD */
	uint8_t USART1_RXbuff;  //中断数据接收缓冲区
/* USER CODE END PTD */
    HAL_UART_Receive_IT(&huart1,(void *)&USART1_RXbuff,1);		/* 开启串口中断接收 */
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  uint16_t tempt;
  if(huart->Instance==USART1)
  {
    tempt=USART1_RXbuff;
    OpenMV_Data_Receive(tempt);
  }
  HAL_UART_Receive_IT(&huart1,(void *)&USART1_RXbuff,1);			//再次开启中断接收
}
/* USER CODE END 4 */

openmv.h:

#ifndef __OPENMV_H
#define __OPENMV_H

#include "stm32f1xx.h"

void OpenMV_Data_Receive(int16_t OpenMV_Data);		/* STM32接收端处理OpenMV传输的数据 */

#endif

openmv.c:

/********************************* (C) COPYRIGHT **********************************
* File Name						    : openmv.c
* Author							: 混分巨兽龙某某
* Version							: V1.0.0
* Data								: 2023/11/03
* Contact							: QQ:1178305328
* Description					    : OpenMV and STM32 Communication Files
***********************************************************************************/
#include "openmv.h"
#include "usart.h"
#include "stdio.h"
#include "oled.h"

static uint8_t Number = 0;

/* STM32接收端处理OpenMV传输的数据 */
void OpenMV_Data_Receive(int16_t OpenMV_Data)
{
	/* 计数变量 */
	static uint8_t RxCounter=0;			//计数变量
	/* 数据接收数组 */
	static uint16_t RxBuffer[4]={0};
	/* 数据传输状态位 */
	static uint8_t RxState = 0;	
	
	/* 判断数据是否为有效数据,解码 */
	if(RxState == 0 && OpenMV_Data == 0xFE)				//0xFE帧头
	{
		RxState = 1;																//状态位改变
		RxBuffer[RxCounter++] = OpenMV_Data;				//将数据放入接收数组
	}
	else if(RxState == 1 && OpenMV_Data == 0xBC)	//0xBC帧头
	{
		RxState = 2;																//状态位改变
		RxBuffer[RxCounter++] = OpenMV_Data;				//将数据放入接收数组
	}
	else if(RxState == 2)													//读取目标数据(根据实际情况处理)
	{
		RxBuffer[RxCounter++] = OpenMV_Data;				//将数据放入接收数组
		if(RxCounter>=3||OpenMV_Data == 0xEF)
		{
			RxState = 3;															//状态位改变
			Number = RxBuffer[RxCounter-1];
			
			/* OLED显示目标数字 */
			OLED_ShowNum(65,4,Number,3,16);
		}
	}
	else if(RxState == 3)													//检测是否接收到标志位
	{
		if(RxBuffer[RxCounter-1] == 0xEF)
		{
			/* 计数和状态位归零 */
			RxCounter = 0;
			RxState = 0;
		} 
		else 		//接收错误
		{
			/* 计数和状态位归零 */
			RxCounter = 0;
			RxState = 0;
			/* 清空存放数据的数组 */
			for(int i = 0;i < 4; i++)
			{
				RxBuffer[i] = 0x00;
			}
		}
	}
	else			//整体的接收异常
	{
		/* 计数和状态位归零 */
		RxCounter = 0;
		RxState = 0;
		/* 清空存放数据的数组 */
		for(int i = 0;i < 4; i++)
		{
			RxBuffer[i] = 0x00;
		}		
	}
}

 项目:

六、项目视频

OpenMV与STM32数据传输演示视频

七、代码开源

代码地址: 基于OpenMV与STM32的数据传输项目代码资源-CSDN文库

如果积分不够的朋友,点波关注评论区留下邮箱,作者无偿提供源码和后续问题解答。求求啦关注一波吧 !!!

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

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

相关文章

【阅读笔记】Chain of LoRA

一、论文信息 1 论文标题 Chain of LoRA: Efficient Fine-tuning of Language Models via Residual Learning 2 发表刊物 arXiv2023 3 作者团队 Department of Computer Science, Princeton University School of Computer Science and Engineering, Nanyang Technologic…

MySQL基础笔记(3)DML数据操作语句

顾名思义&#xff0c;全称是数据操作语言&#xff0c;用来对数据库中表的数据记录进行增删改操作~ 目录 一.添加数据 1.给指定字段添加数据 2.给全部字段添加数据 3.批量添加数据 二.修改数据 三.删除数据 一.添加数据 1.给指定字段添加数据 insert into 表名 (字段名…

区间预测 | Matlab实现CNN-BiLSTM-KDE的卷积双向长短期神经网络结合核密度估计多变量时序区间预测

区间预测 | Matlab实现CNN-BiLSTM-KDE的卷积双向长短期神经网络结合核密度估计多变量时序区间预测 目录 区间预测 | Matlab实现CNN-BiLSTM-KDE的卷积双向长短期神经网络结合核密度估计多变量时序区间预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.CNN-BiLSTM-KDE多…

【开源】基于JAVA语言的婚恋交友网站

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 会员管理模块2.3 新闻管理模块2.4 相亲大会管理模块2.5 留言管理模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 会员信息表3.2.2 新闻表3.2.3 相亲大会表3.2.4 留言表 四、系统展示五、核心代码5.…

第8章-第2节-Java中流的简单介绍

1、什么是流 我们可以先想象水流是怎样的&#xff1f;溪水不断流动&#xff0c;最终融入大海&#xff1b;我们今天的学习IO其实如同水流一样&#xff0c;当我们读取文件信息或者写入信息时&#xff0c;如同水流一样&#xff0c;不断读取或者写入&#xff0c;直到业务流程结束。…

【DolphinScheduler】datax读取hive分区表时,空分区、分区无数据任务报错问题解决

问题背景&#xff1a; 最近在使用海豚调度DolphinScheduler的Datax组件时&#xff0c;遇到这么一个问题&#xff1a;之前给客户使用海豚做的离线数仓的分层搭建&#xff0c;一直都运行好好的&#xff0c;过了个元旦&#xff0c;这几天突然在数仓做任务时报错&#xff0c;具体报…

Cylinder3D论文阅读

Cylindrical and Asymmetrical 3D Convolution Networks for LiDAR Segmentation&#xff08;2020年论文&#xff09; 作者&#xff1a;香港中文大学 论文链接&#xff1a;https://arxiv.org/pdf/2011.10033.pdf 代码链接&#xff1a;https://github.com/xinge008/Cylinder3D …

基于Springboot的课程答疑系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的课程答疑系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&…

e2studio开发磁力计LIS2MDL(2)----基于中断信号获取加速度数据

三轴加速度计LIS2DW12开发.2--轮基于中断信号获取加速度数据 概述视频教学样品申请源码下载新建工程工程模板保存工程路径芯片配置工程模板选择时钟设置UART配置UART属性配置设置e2studio堆栈e2studio的重定向printf设置R_SCI_UART_Open()函数原型回调函数user_uart_callback …

如何计算指标波动贡献率?(附Pandas实现)

大家好&#xff0c;我是阿粥 “为什么这个月销售额提升了30%&#xff1f;” “为什么转化率又降了&#xff0c;同比竟然降低了42%&#xff0c;什么原因导致的呢&#xff1f;” 这些都是数据分析师在工作中经常会遇到的问题&#xff0c;甚至有些基础岗的数据分析师要花80%以上的…

FineBI实战项目一(14):订单销售总数分析开发

点击添加组件按钮&#xff0c;打开组件页面。 设置组件的属性&#xff0c;比如图标样式&#xff0c;指针值&#xff0c;目标值、颜色、大小、标签等。 点击下方切换到仪表盘。 点击仪表板中的左上方组件&#xff0c;添加组件到仪表盘。 编辑标题 第一个组件成功添加到仪表板。

一包多语言——使用FontForge合并字体

大家好&#xff0c;我是阿赵。   比较多游戏做了一个游戏包里面包含了多种语言&#xff0c;可以游戏内切换。这里分享一个合并多种语言字体的方法。 一、遇到的问题 假设我们游戏需要同时显示简体中文、泰文、老挝文三种语言。 解决方案有多种&#xff1a; 1、准备多种字体 …

Linux学习记录——삼십구 数据链路层协议

文章目录 1、了解数据链路层2、认识以太网3、认识MAC地址4、以太网报文5、局域网通信原理1、基本原理2、数据碰撞3、交换机4、ARP协议5、RARP协议6、局域网中间人 6、DNS&#xff08;简单介绍&#xff09;7、ICMP协议1、报文2、traceroute命令 7、NAT技术1、基本过程2、NAPT3、…

springboot基于Web的社区医院管理服务系统源码和论文

在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应用&#xff0c;其中包括社区医院管理服务系统的网络应用&#xff0c;在外国线上管理系统已经是很普遍的方式&#xff0c;不过国内的管理系统可能还处于起步阶段。社区医院管理服务系统具有社区医院信…

你了解计算机网络的发展历史吗?

1.什么是计算机网络 计算机网络是指将一群具有独立功能的计算机通过通信设备以及传输媒体被互联起来的&#xff0c;在通信软件的支持下&#xff0c;实现计算机间资源共享、信息交换或协同工作的系统。计算机网络是计算机技术与通信技术紧密结合的产物&#xff0c;两者的迅速发展…

Vue3组件库 -- element plus 树形选择器组件怎样显示已有的树形菜单?

<el-tree-selectv-model"form.topmneu":data"tableData":props"{ label: title, value: id }":render-after-expand"false"style"width: 100%"check-strictly/> 添加 :props "{ lable : 字段名 , value: 字段…

【计算机网络】TCP原理 | 可靠性机制分析(三)

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【网络编程】【Java系列】 本专栏旨在分享学习网络编程、计算机网络的一点学习心得&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目…

讲讲关于跨域的问题,什么是跨域?怎么办?

文章目录 什么是跨域如果非同源&#xff0c;共有三种行为受到限浏览器客户端和向服务器跨域请求的判定流程 跨域问题演示参考 以下内容为我结合他人知识进行的自我总结, 如有错误欢迎指出~ 什么是跨域 跨域就是不同的域名下的资源访问&#xff0c;会被浏览器的本地安全策略阻…

清晰讲解Cookie、Session、Token、JWT之间的区别

文章目录 什么是认证(Authentication)什么是授权(Authorization)什么是凭证(Credentials)什么是Cookie什么是SessionSession的痛点 Cookie 和 Session 的区别什么是Token(令牌)Acesss TokenRefresh Token Token 和 Session 的区别Token 与 Cookie什么是 JWT生成JWTJWT 的原理JW…

rime中州韵小狼毫 词组注释 滤镜

在rime中州韵小狼毫 联想词组 滤镜一文中&#xff0c;我们通过Filter滤镜功能配置了联想词组的功能&#xff0c;这使得我们在输入一些关键词汇时&#xff0c;可以联想补充一些附加的词组&#xff0c;例如我输入“手机”&#xff0c;就可以联想补充对应的手机号&#xff0c;如下…