【硬件模块】SHT20温湿度传感器
SHT20是一个用IIC通信的温湿度传感器。我们知道这个就可以了。
它支持的电压范围是2.1~3.6V,推荐是3V,所以如果我们的MCU是5V的,那么就得转个电压才能用了。
IIC常见的速率有100k,400k,而SHT20是支持400k的(0.4MHz)。
SHT20的命令有上面几个,不放中文的原因是中文翻译的好烂,我直接解释一下这些是什么意思吧。
命令从上到下分别是触发温度测量(hold master),触发湿度测量(hold master),触发温度测量(no hold master),触发湿度测量(no hold master),写用户寄存器,读用户寄存器,软件复位。
其中hold master 和 no hold master 的意思就是,如果是hold,那么在测量过程中SHT20仍会霸占着IIC的总线,IIC总线上的其他设备无法占用,而no hold就是测量过程中SHT20不占用IIC总线了,一般我们用no hold master,但如果IIC总线上就SHT20一个设备,那么其实无所谓用哪一种。
而读写用户寄存器实际上就是读写配置。
一般来说要修改的就是bit0和bit7,这俩是决定我们温湿度的精度的,默认是00,也就是温度的精度是14bit,湿度的精度是12bit。除非是对采样时间有要求,否则一般情况我们是不用修改的。
接着看看时序图。从时序图可以得知SHT20的IIC从机地址是100 000,加上写命令就是0x80,加上读命令就是0x81。
我们要获取温湿度的话,首先先发送从机地址+写,接着我们发送触发测量的命令,等待测量完毕之后再发送从机地址+读,等到SHT20给我们了ACK回应之后,我们接收3个byte,分别是数据的高8位,数据的低8位,CRC校验码。如果不需要CRC校验,那么我们只需要读取前两个byte即可。
SHT20的CRC校验多项式是x8+x5+x4+1。
我们可以使用在线网站帮我们计算(或者需要在运行时校验的话就按照CRC校验的规则自己写个校验函数)。
CRC在线计算crc在线计算,循环冗余校验在线计算https://www.lddgo.net/encrypt/crc
另外在数据的低8位中的最后两位,是状态位,如果是“00”,那么表示这个数据是温度,如果是“10”则表示这个数据是湿度,但是这个其实没啥用,因为读出啥数据取决于我们之前发送的测量命令,我们要做的就是将最后两位清零,因为最大分辨率为14bit。
得到数据之后我们还需要做些处理。
湿度按照上面这个公式进行计算。
温度按照下面这个公司进行计算。
测量读取温湿度的流程就是上面这些。
读取修改用户寄存器(配置)的流程也大差不大。
如果是要读取,那么先发送从机地址+写,发送读取指令,然后再发送从机地址+读,接着接收一个byte即可。
如果是要修改,那么发送从机地址+读,发送写入指令,接着发送我们要修改的内容即可。
下面是ESP32使用ESP-IDF通过硬件I2C操作SHT20的完整示例代码。
#include <stdio.h>
#include "driver/gpio.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"#include "driver/i2c.h"#define SHT20_SCL 5
#define SHT20_SDA 6float SHT20_getVal(uint8_t command) {i2c_cmd_handle_t container = i2c_cmd_link_create();i2c_master_start(container);i2c_master_write_byte(container, 0x80, true);if (command == 'w') i2c_master_write_byte(container, 0xF3, true);else i2c_master_write_byte(container, 0xF5, true);i2c_master_stop(container);i2c_master_cmd_begin(I2C_NUM_0, container, 100 / portTICK_PERIOD_MS);i2c_cmd_link_delete(container);vTaskDelay(100 / portTICK_PERIOD_MS);uint8_t data_H = 0, data_L = 0;uint8_t CRC = 0;container = i2c_cmd_link_create();i2c_master_start(container);i2c_master_write_byte(container, 0x81, true);i2c_master_read_byte(container, &data_H, I2C_MASTER_ACK);i2c_master_read_byte(container, &data_L, I2C_MASTER_ACK);i2c_master_read_byte(container, &CRC, I2C_MASTER_NACK);i2c_master_stop(container);i2c_master_cmd_begin(I2C_NUM_0, container, 100 / portTICK_PERIOD_MS);i2c_cmd_link_delete(container);double res = ((uint16_t)data_H << 8 | data_L) & 0xFFFC; // 把最后两位去掉,因为分辨率为14bitif (command == 'w') return (res / 65536.0) * 175.72 - 46.85;return (res / 65536.0) * 125.0 - 6;
}void SHT20_init(void) {i2c_config_t i2c_initer = {.clk_flags = 0, // 默认时钟源.master.clk_speed = 4e5, // 400k.mode = I2C_MODE_MASTER, // 主机.scl_io_num = SHT20_SCL,.scl_pullup_en = true,.sda_io_num = SHT20_SDA,.sda_pullup_en = true};i2c_param_config(I2C_NUM_0, &i2c_initer);i2c_driver_install(I2C_NUM_0, I2C_MODE_MASTER, 0, 0, 0);
}void app_main(void) {SHT20_init();float w,s;while (1) {w = SHT20_getVal('w');s = SHT20_getVal('s');printf("T is %f ℃ RH is %f%%\r\n", w , s);vTaskDelay(1000 / portTICK_PERIOD_MS);}
}
下面是GD32使用硬件I2C操作SHT20的完整示例代码。里面涉及串口的部分可以删除,串口只是为了把数据打印出来方便观察,也可以查看我往期的文章了解GD32的串口怎么使用。
【GD32】07 - UART串口通信_gd32 uart自发自收-CSDN博客文章浏览阅读1.4k次,点赞27次,收藏20次。根据之前STM32串口的经验,我们可以将printf重定向到串口上,在STM32中我们直接重写fputc,然后在Keil的设置中勾选Use MicroLlB就行了,但是在GD32F407中勾选Use MicroLlB在编译后会有两个错误。发送数据,注意这边参数的取值范围,发送数据的范围居然是0~0x1FF,类型是uint32_t。今天我用的型号是GD32F407,用其他型号的小伙伴在使用UART的时候注意一下自己手上板子的资源就行,我们使用固件库就算是不同型号其实也是没有什么太大差别的。_gd32 uart自发自收https://blog.csdn.net/m0_63235356/article/details/139904819
#include "board.h"
#include <stdio.h>
#include "Z_UART.h"float SHT20_GetData(uint8_t command){uint16_t res = 0;i2c_start_on_bus(I2C0); //起始时序while(!i2c_flag_get(I2C0,I2C_FLAG_SBSEND) ); //等待起始位发送完. 这个不用手动清除标志位i2c_master_addressing(I2C0, 0x80, I2C_TRANSMITTER); //发送从机地址(0x80)+写命令(0)while(!i2c_flag_get(I2C0,I2C_FLAG_ADDSEND) ); //等待从机发送完毕之后得到回应(即从机地址正确)i2c_flag_clear(I2C0,I2C_FLAG_ADDSEND); //清除标志位while(!i2c_flag_get(I2C0,I2C_FLAG_TBE)); //等待发送缓冲区空if(command == 'w') i2c_data_transmit(I2C0,0xF3); //发送数据,发送SHT20的指令,F3为获取温度,F5为获取湿度else i2c_data_transmit(I2C0,0xF5);while(!i2c_flag_get(I2C0,I2C_FLAG_BTC) ); //等待字节传输完毕i2c_stop_on_bus(I2C0); //发送结束时序uint8_t count = 0; //计数,因为SHT20采集数据需要时间,我们设置个超时时间do{i2c_start_on_bus(I2C0); //起始时序while(!i2c_flag_get(I2C0,I2C_FLAG_SBSEND)); //等待起始位发送完毕i2c_master_addressing(I2C0, 0x80, I2C_RECEIVER);//发送从机地址(0x80)+读命令(1)delay_ms(10); //延时10msif(++count >= 10) return 0; //超过100ms我们就算读取失败}while(!i2c_flag_get(I2C0,I2C_FLAG_ADDSEND)); //等待回应i2c_flag_clear(I2C0,I2C_FLAG_ADDSEND); //清除标志位i2c_ack_config(I2C0, I2C_ACK_ENABLE); //开启应答while(!i2c_flag_get(I2C0,I2C_FLAG_RBNE) ); //等待接收缓冲区不为空res = i2c_data_receive (I2C0); //读取SHT传来的数据的高8位res <<= 8;i2c_ack_config(I2C0, I2C_ACK_DISABLE); //关闭应答,因为我们就获取俩8bit数据while(!i2c_flag_get(I2C0,I2C_FLAG_RBNE) ); //等待接收缓冲区不为空res |= i2c_data_receive (I2C0); //读取SHT传来的数据的低8位i2c_stop_on_bus(I2C0); //结束时序res &= 0xFFFC; //清除最后两位,这是SHT20要求的//根据指令的不同(获取温度/湿度)来计算数据if(command == 'w') return ((res / 65536.0) * 175.72 - 46.85);return (( res / 65536.0) * 125 - 6);
}int main(void){board_init();//初始化串口,为了将结果打印到串口助手上,不懂怎么操作的小伙伴可以看看上一篇文章Z_UART_Init();//开启时钟rcu_periph_clock_enable(RCU_I2C0);rcu_periph_clock_enable(RCU_GPIOB);//初始化硬件IIC的引脚gpio_af_set(GPIOB, GPIO_AF_4,GPIO_PIN_8|GPIO_PIN_9);gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO_PIN_8|GPIO_PIN_9);gpio_output_options_set(GPIOB, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ,GPIO_PIN_8|GPIO_PIN_9);i2c_deinit(I2C0); //复位IIC0i2c_clock_config(I2C0, 100000, I2C_DTCY_2); //设置IIC速率为100ki2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0X80); //设置SHT20的七位地址i2c_ack_config(I2C0, I2C_ACK_ENABLE); //使能应答i2c_enable(I2C0); //使能IICprintf("hello world!\r\n");while (1){printf("%f\t%f\r\n",SHT20_GetData('w'),SHT20_GetData('s'));delay_ms(1000);}
}
下面是STM32使用软件I2C操作SHT20的完整示例代码,其中延时函数需要自己准备,OLED的部分可以删除,是用来观察数据的,可以拿串口来代替。也可以查阅我往期的文章了解STM32利用滴答定时器实现的延时函数,以及串口、OLED的使用。
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"#define SCL_Pin GPIO_Pin_0
#define SDA_Pin GPIO_Pin_1void Z_I2C_Init(void){RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_InitTypeDef itd;itd.GPIO_Mode=GPIO_Mode_Out_OD; itd.GPIO_Pin=SCL_Pin|SDA_Pin; itd.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&itd);GPIO_WriteBit(GPIOA,SCL_Pin,Bit_SET); //SCL和SDA默认都是高电平GPIO_WriteBit(GPIOA,SDA_Pin,Bit_SET); //因此初始化后设为高电平
}void Z_I2C_SetSCL(uint8_t signal){if(signal==1) GPIO_WriteBit(GPIOA,SCL_Pin,Bit_SET);else GPIO_WriteBit(GPIOA,SCL_Pin,Bit_RESET);Delay_us(5); //防止电平翻转过快,因此加上延时
}void Z_I2C_SetSDA(uint8_t signal){if(signal==1) GPIO_WriteBit(GPIOA,SDA_Pin,Bit_SET);else GPIO_WriteBit(GPIOA,SDA_Pin,Bit_RESET);Delay_us(5);
}uint8_t Z_I2C_GetSDA(void){return GPIO_ReadInputDataBit(GPIOA,SDA_Pin);
}void Z_I2C_Start(void){Z_I2C_SetSDA(1);Z_I2C_SetSCL(1);Z_I2C_SetSDA(0);Z_I2C_SetSCL(0);
}void Z_I2C_End(){Z_I2C_SetSDA(0);Z_I2C_SetSCL(1);Z_I2C_SetSDA(1);
}void Z_I2C_SendByte(uint8_t byte){Z_I2C_SetSCL(0);for(int i=0;i<8;++i){if((byte&0x80)==0) Z_I2C_SetSDA(0);else Z_I2C_SetSDA(1);byte<<=1;Z_I2C_SetSCL(1);Z_I2C_SetSCL(0);}
}uint8_t Z_I2C_ReveiceByte(){uint8_t data=0x00;Z_I2C_SetSDA(1);for(int i=0;i<8;++i){Z_I2C_SetSCL(1);if(Z_I2C_GetSDA()==1) data|=(0x80>>i);Z_I2C_SetSCL(0);}return data;
}void Z_I2C_SendACK(uint8_t ack){if(ack==0) Z_I2C_SetSDA(0);else Z_I2C_SetSDA(1);Z_I2C_SetSCL(1);Z_I2C_SetSCL(0);
}uint8_t Z_I2C_ReveiceACK(){Z_I2C_SetSDA(1);Z_I2C_SetSCL(1);uint8_t ack=Z_I2C_GetSDA();Z_I2C_SetSCL(0);return ack;
}#define WENDU_COMMAND 0xF3
#define SHIDU_COMMAND 0xF5uint16_t STH20_WData=0;
uint16_t STH20_SData=0;void Z_STH20_GetData(char command){Z_I2C_Start();Z_I2C_SendByte(0x80);if(Z_I2C_ReveiceACK()!=0) return;if(command=='w') Z_I2C_SendByte(WENDU_COMMAND); //发送命令else Z_I2C_SendByte(SHIDU_COMMAND);if(Z_I2C_ReveiceACK()!=0) return;int count=0;do{Z_I2C_Start();Z_I2C_SendByte(0x81);Delay_ms(10);if(++count>=10) return;}while(Z_I2C_ReveiceACK()!=0);if(command=='w'){STH20_WData=0; //数据清零STH20_WData|=Z_I2C_ReveiceByte(); //获取数据高位Z_I2C_SendACK(0);STH20_WData<<=8;STH20_WData|=Z_I2C_ReveiceByte(); //获取数据低位Z_I2C_SendACK(0);uint8_t check=Z_I2C_ReveiceByte(); //获取CRC校验位Z_I2C_End();STH20_WData&=0xFFFC; //清除最后两位return;}else{STH20_SData=0; //数据清零STH20_SData|=Z_I2C_ReveiceByte(); //获取数据高位Z_I2C_SendACK(0);STH20_SData<<=8;STH20_SData|=Z_I2C_ReveiceByte(); //获取数据低位Z_I2C_SendACK(0);uint8_t check=Z_I2C_ReveiceByte(); //获取CRC校验位Z_I2C_End();STH20_SData&=0xFFFC; //清除最后两位return ;}
}int main(void){OLED_Init();Z_I2C_Init();while(1){Z_STH20_GetData('w');Z_STH20_GetData('s');double wendu=STH20_WData;wendu=(wendu/65536.0)*175.72-46.85;OLED_ShowNum(1,1,(int)wendu%100,2);OLED_ShowChar(1,3,'.');OLED_ShowNum(1,4,((int)(wendu*100)%100),2);OLED_ShowNum(2,1,STH20_WData,6);double shidu=STH20_SData;shidu=(shidu/65536.0)*125-6;OLED_ShowNum(3,1,(int)shidu%100,2);OLED_ShowChar(3,3,'.');OLED_ShowNum(3,4,((int)(shidu*100)%100),2);OLED_ShowNum(4,1,STH20_SData,6);Delay_ms(500);}
}
相关文章:

【硬件模块】SHT20温湿度传感器
SHT20是一个用IIC通信的温湿度传感器。我们知道这个就可以了。 它支持的电压范围是2.1~3.6V,推荐是3V,所以如果我们的MCU是5V的,那么就得转个电压才能用了。 IIC常见的速率有100k,400k,而SHT20是支持400k的(…...

Redhat 8,9系(复刻系列) 一键部署Oracle23ai rpm
Oracle23ai前言 Oracle Database 23ai Free 让您可以充分体验 Oracle Database 的能力,世界各地的企业都依赖它来处理关键任务工作负载。 Oracle Database Free 的资源限制为 2 个 CPU(前台进程)、2 GB 的 RAM 和 12 GB 的磁盘用户数据。该软件包不仅易于使用,还可轻松下载…...
SIPp uac.xml 之我见
https://sipp.sourceforge.net/doc/uac.xml.html 这个 uac.xml 有没有问题呢? 有! 问题之一是: <recv response"200" rtd"true" rrs"true"> 要加 rrs, 仔细看注释就能看到 问题之二是࿱…...

引领智能家居新风尚,WTN6040F门铃解决方案——让家的呼唤更动听
在追求高效与便捷的智能家居时代,每一个细节都承载着我们对美好生活的向往。WTN6040F,作为一款专为现代家庭设计的低成本、高性能门铃解决方案,正以其独特的魅力,悄然改变着我们的居家生活体验。 芯片功能特点: 1.2.4…...
Android 蓝牙服务启动
蓝牙是Android设备中非常常见的一个feature,设备厂家可以用BT来做RC、连接音箱、设备本身做Sink等常见功能。如果一些设备不需要BT功能,Android也可以通过配置来disable此模块,方便厂家为自己的设备做客制化。APP操作设备的蓝牙功能ÿ…...

【安全系列--处理挖矿】
现象:我们云上waf提示有台服务器存在挖矿行为 解决思路: 1、查看服务器的进程情况 top发现服务的CPU使用率非常高 2、使用性能分析工具perf查看占用的cpu进程 sudo apt install linux-tools-common发现一些kernel进程存在异常 3、使用find查一下这…...

SpringBoot集成Thymeleaf模板引擎,为什么使用(详细介绍)
学习本技术第一件事:你为什么要使用,解决什么问题的? 1.为什么使用(使用背景)? 首先应用场景是单体项目,如果是前后端分离就不用关注这个了,因为单体项目你前后端都是写在一个项目…...

Docker突然宣布:涨价80%
从11月15日起,Docker的付费订阅中Pro和Team的价格都将大幅上调:Pro从原来的5美元每月激增到9美元每月,直接涨了80%;而Team也从之前的9美元每月来到15美元每月,涨价66.7%。只有Business保持此前的24美元每月不变。 同时…...

工厂方法模式和抽象工厂模式
工厂方法模式 一个工厂只能创建一种产品 工厂方法模式的结构 工厂方法模式包含以下4个角色 Product(抽象产品) ConcreteProduct(具体产品) Factory(抽象工厂) ConcreteFactory(具体工厂…...
【星海出品】go语言环境兼install
官网 https://golang.google.cn/dl/ go的安装包下载地址 https://go.dev/dl/ set GO111MODULEon //是否以Go modules的模式运行项目 auto,on,off set GOARCHamd64 //目标可执行程序操作系统构架 包括 386,amd64,arm set GOBIN //项目的第三方可执行文件目…...
Spring 源码解读:自定义实现BeanPostProcessor的扩展点
引言 在Spring的生命周期管理中,BeanPostProcessor是一个非常重要的扩展点。它允许开发者在Bean初始化的前后插入自定义的逻辑,从而实现更灵活的Bean管理。BeanPostProcessor是Spring框架中用于对Bean实例进行修改的机制之一。通过实现该接口࿰…...
Spring Boot-分布式系统问题
Spring Boot 在分布式系统中的常见问题及解决方案 随着互联网的发展,系统规模和复杂度越来越大,分布式系统成为应对高并发、大数据量场景的重要架构选择。Spring Boot 作为一种轻量级的开发框架,广泛应用于构建微服务和分布式系统中。然而&a…...
面试题总结(三) -- 内存管理篇
面试题总结(三) – 内存管理篇 文章目录 面试题总结(三) -- 内存管理篇<1> C 中堆内存和栈内存的区别是什么?<2> 如何在 C 中手动管理内存(new/delete 操作符)?<3> C 中内存泄漏的原因和避免方法<4> 谈谈…...
Qt 定时器-定时备份
定时备份 在Qt 中,可以使用QTimer类来实现定时备份功能。以下是一个示例代码,每隔一段时间自动执行备份操作: #include <QTimer>QTimer timer; int backupInterval 24 * 60 * 60 * 1000;//备份间隔为24小时connect(&timer, &…...

天融信把桌面explorer.exe删了,导致开机之后无windows桌面,只能看到鼠标解决方法
win10开机进入桌面,发现桌面无了,但是可以ctrlaltdelete调出任务管理器 用管理员权限打开cmd,输入: sfc /scanfilec:\windowslexplorer.exe 在运行C:\windows\Explorer.exe;可以进入桌面,但是隔离几秒钟…...

视频分割操作教程
1、打开剪映 2、点击开始创作上面的“”,选择视频,点击添加按钮,导入一个视频素材到剪映 3、滑动视频,让视频竖线到合适位置 4、点击视频,出现白色边框 5、点击工具栏“分割”,然后点击需要删除的视频部分 …...
唯品会大数据面试题及参考答案(3万字长文)
synchronized 和 volatile 的区别 synchronized是 Java 中的关键字,用于实现同步机制,确保在同一时刻只有一个线程可以访问被它修饰的代码块或方法。volatile也是 Java 中的关键字,主要用于保证变量的可见性。 功能方面: synchronized可以保证原子性、可见性和有序性。它通…...
使用容器技术快速入门MinIO
使用容器技术快速入门MinIO 使用容器技术(docker或者podman)快速部署一个单节点单磁盘 MinIO 服务器,用于对MinIO对象存储及其兼容 S3 的 API 层进行早期的开发和评估。 1. 准备工作 机器已经安装了 Podman 或者 Docker 。 对用于持久卷的…...
ros2教程(一):使用python和C++发布摄像头原始图像和压缩图像
1. 使用python发布图像 在ROS 2中,可以通过使用rclpy库来发布压缩图像和原始图像。发布原始图像可以使用sensor_msgs.msg.Image消息类型,压缩图像则使用sensor_msgs.msg.CompressedImage消息类型。 #!/usr/bin/env python3# function: usbcam publish r…...

【自动化测试】UI自动化的分类、如何选择合适的自动化测试工具以及其中appium的设计理念、引擎和引擎如何工作
引言 UI自动化测试主要针对软件的用户界面进行测试,以确保用户界面元素的交互和功能符合预期 文章目录 引言一、UI自动化的分类1.1 基于代码的自动化测试1.2 基于录制/回放的自动化测试1.3 基于框架的自动化测试1.4 按测试对象分类1.5 按测试层次分类1.6 按测试执行…...

Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...

select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...

springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用
一、方案背景 在现代生产与生活场景中,如工厂高危作业区、医院手术室、公共场景等,人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式,存在效率低、覆盖面不足、判断主观性强等问题,难以满足对人员打手机行为精…...