RK3568笔记三十八:DS18B20驱动开发测试

若该文为原创文章,转载请注明原文出处。

DS18B20驱动参考的是讯为电子的单总线驱动第十四期 | 单总线_北京迅为的博客-CSDN博客

博客很详细,具体不描述。

只是记录测试下DS18B20读取温度。

一、介绍

流程基本和按键驱动差不多,主要功能是获取DS18B20温度,使用ioctl修改配置寄存器从而改变分辨率的大小,总共支持9位、10位、11位、12位四种分辨率。

主要流程:

1、修改设备树

2、编写驱动程序

3、编写应用程序

4、测试

二、DS18B20原理

DS18B20传感器参数

测温范围为-55℃到+125℃,在-10℃到+85℃范围内误差为±0.4°。

返回16位二进制温度数值

主机和从机通信使用单总线,即使用单线进行数据的发送和接收

在使用中不需要任何外围元件,独立芯片即可完成工作。

掉电保护功能 DS18B20 内部含有 EEPROM ,通过配置寄存器可以设定数字转换精度和报警温度,在系统掉电以后,它仍可保存分辨率及报警温度的设定值。

每个DS18B20都有独立唯一的64位-ID,此特性决定了它可以将任意多的DS18b20挂载到一根总线上,通过ROM搜索读取相应DS18B20的温度值

宽电压供电,电压2.5V~5.5V

DS18B20返回的16位二进制数代表此刻探测的温度值,其高五位代表正负。如果高五位全部为1,则代表返回的温度值为负值。如果高五位全部为0,则代表返回的温度值为正值。后面的11位数据代表温度的绝对值,将其转换为十进制数值之后,再乘以0.0625即可获得此时的温度值。

把DS18B20的Data引脚接到P3_C4引脚上,接线如下:

三、编写设备树

修改的两个文件,一是rk3568-atk-evb1-ddr4-v10.dtsi, 二是rk3568-pinctrl.dtsi.

文件路径:/home/alientek/rk3568_linux_sdk/kernel/arch/arm64/boot/dts/rockchip/

rk3568-atk-evb1-ddr4-v10.dtsi

ds18b20_gpio:gpio3_b0 {compatible = "ds18b20";pinctrl-0 = <&ds18b20_gpio_ctrl>;pinctrl-names = "default";ds18b20-gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_HIGH>;status = "okay";};

rk3568-pinctrl.dtsi

ds18b20_gpio {/omit-if-no-ref/ds18b20_gpio_ctrl: ds18b20-gpio-ctrl {rockchip,pins =<3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>;};};

修改完成两个文件后,需要重新编译kernel并烧写boot.img .

烧写完成以后启动开发板。Linux 启动成功以后进入到/proc/device-tree/目录中查看是否有gpio3_b0节点

如果是其他引脚自行修改,测试发现,有一些引脚无法使用。

四、驱动程序

驱动程序直接拷贝讯为电子的。

1、ds18b20.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/kdev_t.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h> // 添加此头文件
#include <linux/delay.h>
#include <linux/uaccess.h>#define SET_RESOLUTION _IOW('A', 0, int)
#define READ_RESOLUTION _IOR('A', 1, int)#define SET_RESOLUTION_9 9
#define SET_RESOLUTION_10 10
#define SET_RESOLUTION_11 11
#define SET_RESOLUTION_12 12struct ds18b20_data
{dev_t dev_num;struct cdev ds18b20_cdev;struct class *ds18b20_class;struct device *ds18b20_device;struct gpio_desc *ds18b20_gpio;
};struct ds18b20_data *ds18b20;void ds18b20_reset(void)
{// 设置 GPIO 方向为输出,输出低电平gpiod_direction_output(ds18b20->ds18b20_gpio, 1);gpiod_set_value(ds18b20->ds18b20_gpio, 0);udelay(700); // 延迟 700 微秒// 设置 GPIO 输出高电平,并将 GPIO 方向设置为输入gpiod_set_value(ds18b20->ds18b20_gpio, 1);gpiod_direction_input(ds18b20->ds18b20_gpio);// 等待直到 GPIO 输入为低电平while (gpiod_get_value(ds18b20->ds18b20_gpio));// 等待直到 GPIO 输入为高电平while (!gpiod_get_value(ds18b20->ds18b20_gpio));udelay(480); // 延迟 480 微秒
}/*** 向 DS18B20 写入单个位(bit)* @param bit 要写入的位(bit),0 或 1*/
void ds18b20_writebit(unsigned char bit) {// 将 GPIO 方向设置为输出gpiod_direction_output(ds18b20->ds18b20_gpio, 1);// 将 GPIO 输出设置为指定的位(bit)gpiod_set_value(ds18b20->ds18b20_gpio, 0);// 若 bit 为 1,则延时 10 微秒if (bit){udelay(10);  // 将 GPIO 方向设置为输出gpiod_direction_output(ds18b20->ds18b20_gpio, 1);}// 延时 65 微秒udelay(65);// 将 GPIO 方向设置为输出gpiod_direction_output(ds18b20->ds18b20_gpio, 1);// 延时 2 微秒udelay(2);
}/*** 向 DS18B20 写入一个字节(byte)数据* @param data 要写入的字节数据*/
void ds18b20_writebyte(int data) {int i;for (i = 0; i < 8; i++) {// 逐位写入数据ds18b20_writebit(data & 0x01);data = data >> 1;}
}/*** 从 DS18B20 读取单个位(bit)* @return 读取到的位(bit),0 或 1*/
unsigned char ds18b20_readbit(void) {unsigned char bit;        gpiod_direction_output(ds18b20->ds18b20_gpio, 1);// 将 GPIO 方向设置为输出        gpiod_set_value(ds18b20->ds18b20_gpio, 0);// 将 GPIO 输出设置为低电平        udelay(2);// 延时 2 微秒        gpiod_direction_input(ds18b20->ds18b20_gpio);// 将 GPIO 方向设置为输入   udelay(10);// 延时 10 微秒       bit = gpiod_get_value(ds18b20->ds18b20_gpio);// 读取 GPIO 的值作为位(bit)       udelay(60);// 延时 60 微秒return bit;
}/*** 从 DS18B20 读取一个字节(byte)数据* @return 读取到的字节数据*/
int ds18b20_readbyte(void) {int data = 0;int i;for (i = 0; i < 8; i++) {// 读取单个位(bit)并根据位的位置进行左移操作data |= ds18b20_readbit() << i;}return data;
}/*** 从 DS18B20 读取温度值* @return 读取到的温度值*/
int ds18b20_readtemp(void) {int temp_l, temp_h, temp;   ds18b20_reset();// 复位 DS18B20    ds18b20_writebyte(0xCC);// 发送写入字节命令 0xCC(跳过 ROM)   ds18b20_writebyte(0x44);// 发送写入字节命令 0x44(启动温度转换)    mdelay(750);// 延时 750 微秒,等待温度转换完成ds18b20_reset();// 复位 DS18B20        ds18b20_writebyte(0xCC);// 发送写入字节命令 0xCC(跳过 ROM)       ds18b20_writebyte(0xBE);// 发送写入字节命令 0xBE(读取温度值)        temp_l = ds18b20_readbyte();// 读取温度低位字节        temp_h = ds18b20_readbyte();// 读取温度高位字节        temp_h = temp_h << 8;// 将温度高位字节左移 8 位temp = temp_h | temp_l;// 组合温度值return temp;
} /*** 设置 DS18B20 温度传感器的分辨率* @param args 分辨率参数*/
void set_resolution(int args) {ds18b20_reset();  // 复位 DS18B20 温度传感器ds18b20_writebyte(0xCC);  // 发送跳过 ROM 命令ds18b20_writebyte(0x4E);  // 发送写配置寄存器命令ds18b20_writebyte(60);  // 发送配置字节 1,设置温度上限阈值ds18b20_writebyte(10);  // 发送配置字节 2,设置温度下限阈值switch (args) {case SET_RESOLUTION_9:  // 设置分辨率为 9 位ds18b20_writebyte(0x1F);  // 发送配置字节 3,设置分辨率为 9 位break;case SET_RESOLUTION_10:  // 设置分辨率为 10 位ds18b20_writebyte(0x3F);  // 发送配置字节 3,设置分辨率为 10 位break;case SET_RESOLUTION_11:  // 设置分辨率为 11 位ds18b20_writebyte(0x5F);  // 发送配置字节 3,设置分辨率为 11 位break;case SET_RESOLUTION_12:  // 设置分辨率为 12 位ds18b20_writebyte(0x7F);  // 发送配置字节 3,设置分辨率为 12 位break;default:break;}
}/*** 检查参数的有效性* @param args 参数* @return 返回执行结果,成功返回 0,失败返回 -1*/
int check_args(int args) {int ret = -1;  // 返回值,默认为失败ds18b20_reset();  // 复位传感器ds18b20_writebyte(0xCC);  // 发送指令字节 0xCCds18b20_writebyte(0xBE);  // 发送指令字节 0xBEds18b20_readbyte();  // 读取一个字节ds18b20_readbyte();  // 读取一个字节ds18b20_readbyte();  // 读取一个字节ds18b20_readbyte();  // 读取一个字节switch (args) {case SET_RESOLUTION_9:if (ds18b20_readbyte() == 0x1F) {  // 读取一个字节并与 0x1F 进行比较ret = 0;  // 设置返回值为成功}break;case SET_RESOLUTION_10:if (ds18b20_readbyte() == 0x3F) {  // 读取一个字节并与 0x3F 进行比较ret = 0;  // 设置返回值为成功}break;case SET_RESOLUTION_11:if (ds18b20_readbyte() == 0x5F) {  // 读取一个字节并与 0x5F 进行比较ret = 0;  // 设置返回值为成功}break;case SET_RESOLUTION_12:if (ds18b20_readbyte() == 0x7F) {  // 读取一个字节并与 0x7F 进行比较ret = 0;  // 设置返回值为成功}break;default:break;}return ret;  // 返回结果
}/*** 读取分辨率。** @return 分辨率值*/
int read_resolution(void) {int ret;// 复位传感器ds18b20_reset();// 发送指令字节0xCC,跳过ROM操作,直接与单个设备通信ds18b20_writebyte(0xCC);// 发送指令字节0xBE,读取当前设备的配置寄存器ds18b20_writebyte(0xBE);// 读取4个字节的数据,但实际上只有最后一个字节是分辨率信息ds18b20_readbyte();ds18b20_readbyte();ds18b20_readbyte();ds18b20_readbyte();// 读取最后一个字节,即分辨率信息ret = ds18b20_readbyte();// 返回分辨率值return ret;
}int ds18b20_open(struct inode *inode, struct file *file)
{return 0;
}ssize_t ds18b20_read(struct file *file, char __user *buf, size_t size, loff_t *offs) {int ds18b20_temp;    ds18b20_temp = ds18b20_readtemp();// 从 DS18B20 读取温度值    // 将温度值复制到用户空间缓冲区if (copy_to_user(buf, &ds18b20_temp, sizeof(ds18b20_temp))) {return -1; // 复制失败,返回错误代码}return 0; // 成功读取并复制温度值
}int ds18b20_release(struct inode *inode, struct file *file)
{return 0;
}/*** DS18B20 温度传感器的 ioctl 函数* @param file 文件指针* @param cmd 命令* @param args 参数* @return 返回执行结果,成功返回 0,失败返回 -1*/
long ds18b20_ioctl(struct file *file, unsigned int cmd, unsigned long args) {int resolution;if (cmd == SET_RESOLUTION) {  // 判断命令是否为设置分辨率if (args >= SET_RESOLUTION_9 && args <= SET_RESOLUTION_12) {  // 判断参数是否在有效的分辨率范围内set_resolution(args);  // 调用设置分辨率的函数return 0;  // 返回成功}}else if (cmd == READ_RESOLUTION) {// 读取分辨率resolution = read_resolution();// 将分辨率的值复制给用户空间的argsif (copy_to_user((int *)args, &resolution, sizeof(resolution))) {// 复制失败,返回-1表示失败return -1;}}// 如果不匹配 SET_RESOLUTION 或者 args 不在有效范围内,不执行任何操作return -1;  // 返回失败
}struct file_operations ds18b20_fops = {.open = ds18b20_open,.read = ds18b20_read,.release = ds18b20_release,.unlocked_ioctl = ds18b20_ioctl,.owner = THIS_MODULE,
};int ds18b20_probe(struct platform_device *dev)
{int ret;printk("This is probe \n");// 分配内存给ds18b20_data结构体ds18b20 = kzalloc(sizeof(*ds18b20), GFP_KERNEL);if (ds18b20 == NULL){printk("kzalloc error\n");ret = -ENOMEM;goto error_0;}// 分配字符设备号ret = alloc_chrdev_region(&ds18b20->dev_num, 0, 1, "myds18b20");if (ret < 0){printk("alloc_chrdev_region error\n");ret = -EAGAIN;goto error_1;}// 初始化字符设备cdev_init(&ds18b20->ds18b20_cdev, &ds18b20_fops);ds18b20->ds18b20_cdev.owner = THIS_MODULE;cdev_add(&ds18b20->ds18b20_cdev, ds18b20->dev_num, 1);// 创建设备类ds18b20->ds18b20_class = class_create(THIS_MODULE, "sensors");if (IS_ERR(ds18b20->ds18b20_class)){printk("class_create error\n");ret = PTR_ERR(ds18b20->ds18b20_class);goto error_2;}// 创建设备ds18b20->ds18b20_device = device_create(ds18b20->ds18b20_class, NULL, ds18b20->dev_num, NULL, "ds18b20");if (IS_ERR(ds18b20->ds18b20_device)){printk("device_create error\n");ret = PTR_ERR(ds18b20->ds18b20_device);goto error_3;}// 获取GPIO描述符ds18b20->ds18b20_gpio = gpiod_get_optional(&dev->dev, "ds18b20", 0);if (ds18b20->ds18b20_gpio == NULL){ret = -EBUSY;goto error_4;}// 设置GPIO方向为输出gpiod_direction_output(ds18b20->ds18b20_gpio, 1);return 0;error_4:device_destroy(ds18b20->ds18b20_class, ds18b20->dev_num);error_3:class_destroy(ds18b20->ds18b20_class);error_2:cdev_del(&ds18b20->ds18b20_cdev);unregister_chrdev_region(ds18b20->dev_num, 1);error_1:kfree(ds18b20);error_0:return ret;
}const struct of_device_id ds18b20_match_table[] = {{.compatible = "ds18b20"},{},
};struct platform_driver ds18b20_driver = {.driver = {.owner = THIS_MODULE,.name = "ds18b20",.of_match_table = ds18b20_match_table,},.probe = ds18b20_probe,
};static int __init ds18b20_init(void)
{int ret;// 注册平台驱动ret = platform_driver_register(&ds18b20_driver);if (ret < 0){printk("platform_driver_register error\n");return -1;}return 0;
}static void __exit ds18b20_exit(void)
{// 释放资源gpiod_put(ds18b20->ds18b20_gpio);device_destroy(ds18b20->ds18b20_class, ds18b20->dev_num);class_destroy(ds18b20->ds18b20_class);cdev_del(&ds18b20->ds18b20_cdev);unregister_chrdev_region(ds18b20->dev_num, 1);kfree(ds18b20);platform_driver_unregister(&ds18b20_driver);
}module_init(ds18b20_init);
module_exit(ds18b20_exit);
MODULE_LICENSE("GPL");

2、makefile

KERNELDIR := /home/alientek/rk3568_linux_sdk/kernel
ARCH=arm64
CROSS_COMPILE=/opt/atk-dlrk356x-toolchain/usr/bin/aarch64-buildroot-linux-gnu-export  ARCH  CROSS_COMPILECURRENT_PATH := $(shell pwd)
obj-m := ds18b20.obuild: kernel_moduleskernel_modules:$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules
clean:$(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean

编译生成ds18b20.ko文件

五、应用程序

ds18b20App.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <stdlib.h>#define SET_RESOLUTION _IOW('A', '0', int)
#define READ_RESOLUTION _IOR('A', '1', int)/*** 根据传感器读取的原始数据计算温度值* @param value 传感器读取的原始数据*/
void ds18b20_get_temp(int value) {char sig;   // 温度正负号float temp; // 温度值// 判断温度正负号if ((value >> 11) & 0x01) {sig = '-';value = ~value + 1;value &= ~(0xf8 << 8);} else {sig = '+';}// 计算温度值temp = value * 0.0625;// 打印温度信息printf("温度为 %c%.4f\n", sig, temp);
}/*** 根据传感器分辨率值打印分辨率信息* @param value 传感器分辨率值*/
void ds18b20_get_resolution(int value) {switch (value) {case 0x1F:printf("分辨率为 9 位\n");break;case 0x3F:printf("分辨率为 10 位\n");break;case 0x5F:printf("分辨率为 11 位\n");break;case 0x7F:printf("分辨率为 12 位\n");break;default:break;}
}int main(int argc, char *argv[]) {int fd;    // 文件描述符int data;  // 读取的数据int args;  // 参数值int resolution;  // 返回的分辨率的值// 打开设备文件fd = open("/dev/ds18b20", O_RDWR);if (fd < 0) {printf("打开设备文件出错\n");return -1;}// 获取命令行参数args = atoi(argv[1]);printf("参数值为 %d\n", args);// 检查参数范围if (args < 9 || args > 12) {printf("错误!参数范围应为 9 - 12\n");return -1;}// 设置分辨率ioctl(fd, SET_RESOLUTION, args);// 读取分辨率ioctl(fd, READ_RESOLUTION, &resolution);ds18b20_get_resolution(resolution);while (1) {// 读取数据read(fd, &data, sizeof(data));// 处理并打印温度信息ds18b20_get_temp(data);}return 0;
}

编译:

/opt/atk-dlrk356x-toolchain/bin/aarch64-buildroot-linux-gnu-gcc ds18b20App.c -o ds18b20App

六、测试

先接好DS18B20模块,保证线序是对的。

加载驱动

 insmod ds18b20.ko 

测试

./ds18b20App 9

测试正常,这是单个GPIO测试,如果模拟I2C或SPI,驱动是怎么写?

如有侵权,或需要完整代码,请及时联系博主。

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

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

相关文章

为什么要做USB转多路UART项目 - 技术角度

前言 之前专门为USB转多路UART项目写了个序&#xff0c;提到了技术方案原因&#xff0c;这个文章打算展开讲一下。 一、工业物联网关 最初是因为有个工业物联网关的项目&#xff0c;需要出多路RS485接口&#xff0c;每路外接几十个三相电表PLC之类的电力电子设备。其中一款需…

【论文极速读】 可微分检索索引(Differential Search Index, DSI)

【论文极速读】 可微分检索索引&#xff08;Differential Search Index&#xff0c; DSI&#xff09; FesianXu 20240714 at WeChat Search Team 前言 最近从朋友处得知了DSI这个概念&#xff0c;所谓的可微分检索索引DSI&#xff0c;就是通过语言模型将检索过程中的索引和召回…

pixelRNN与pixelCNN

目的&#xff1a;为了找到一个最能解释得到的生成样本的模型 PixelRNN 我们需要利用概率链式法则将图像x的生成概率转变为每个像素生成概率的乘积&#xff0c;也就是每个通道生成概率的乘积。 公式&#xff1a; 公式解释&#xff1a;p(x)是每个图像x的概率&#xff1b;右侧为…

浅聊授权-spring security和oauth2

文章目录 前言自定义授权spring security授权oauth2授权概述 前言 通常说到授权&#xff0c;就会想到登录授权、token令牌、JWT等概念&#xff0c;授权。顾名思义就是服务器授予了客户端访问资源的权益&#xff0c;那么要实现授权有几种方案呢&#xff0c;三种授权方式在公司项…

c++dll库的制作和使用

01、dll库的创建使用 创建dll项目 dllexport到处 dllimport导入 分别制定dll和lib的生成目录 调用&#xff1a; 包含头文件 常规添加 最后把dll文件拷贝到程序 成功调用

使用Keepalived实现双机热备(虚拟漂移IP地址)详细介绍

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f427;Linux基础知识(初学)&#xff1a;点击&#xff01; &#x1f427;Linux高级管理防护和群集专栏&#xff1a;点击&#xff01; &#x1f510;Linux中firewalld防火墙&#xff1a;点击&#xff01; ⏰️创作…

uniapp发送Form Data格式请求

设置header的Content-Type为 application/x-www-form-urlencoded 即可 uni.request({url: , // 接口urldata: {input: 写一篇一千字的作文}, // 入参method: POST, // 参数类型header: {"Content-Type": "application/x-www-form-urlencoded"}, // 请求头…

进销存管理系统设计

进销存管理系统&#xff08;Inventory Management System&#xff0c;简称IMS&#xff09;是一种帮助企业有效管理商品的入库、出库及库存情况的信息系统。良好的进销存管理系统能够提升库存周转率、减少库存成本、提高订单处理效率&#xff0c;从而增强企业的市场竞争力。以下…

[JS]Generator

介绍 Generator函数是 ES6 提供的一种异步编程解决方案, async是该方案的语法糖 核心语法 Generator对象由生成器函数返回, 并且它符合可迭代协议和迭代器协议 生成器函数在执行时能暂停, 后面又从暂停处继续执行 <script>// 1.定义生成器函数function* testGenerato…

VMware与centos安装

目录 VM安装 安装centos VM安装 VMware Workstation Pro是VMware&#xff08;威睿公司发布的一袋虚拟机软件&#xff09;&#xff0c;它主要功能是可以给用户在单一的桌面上同时运行不同的操作系统&#xff0c;也是可以进行开发、测试、部署新的应用程序的最佳解决方案。 开始…

HarmonyOS 屏幕适配设计

1. armonyOS 屏幕适配设计 1.1. 像素单位 &#xff08;1&#xff09;px (Pixels)   px代表屏幕上的像素点&#xff0c;是手机屏幕分辨率的单位&#xff0c;即屏幕物理像素单位。 &#xff08;2&#xff09;vp (Viewport Percentage)   vp是视口百分比单位&#xff0c;基于…

程序包不存在【java: 程序包org.springframework.boot不存在】

1、问题提示&#xff1a;java: 程序包org.springframework.boot不存在 注意&#xff1a;已经下载好了程序包&#xff0c;就是提示不存在 2、解决办法

PostgreSQL 中如何处理数据的并发读写和锁等待超时?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 PostgreSQL 中如何处理数据的并发读写和锁等待超时一、并发读写的基本概念&#xff08;一&#xff09;…

公司周年庆活动应该怎么策划?

当我们谈论公司周年庆典&#xff0c;我们不仅仅是在讨论一个简单的派对。 这是一个展现公司文化、增强员工归属感、加深客户关系&#xff0c;甚至推动公司战略发展的重要时刻。 那么&#xff0c;如何策划一场既有趣又有意义的周年庆典呢&#xff1f;这里分享一点自己的私人笔…

【java】力扣 买卖股票的最佳时机II

文章目录 题目链接题目描述思路代码 题目链接 122.买卖股票的最佳时机II 题目描述 思路 这道题和121.买卖股票的最佳时机 有所不同&#xff0c;不同点在于&#xff0c;这道题的股票可以多次买卖(但是要在买之前先卖掉) 详细思路请看链接的文章【java】力扣 买卖股票的最佳时…

ERP基础知识

ERP 一、概述 ​ ERP是Event-related Potentials的简称。外加一种特定的刺激&#xff0c;作用于感觉系统或脑 的某一部位&#xff0c;在给予刺激或撤销刺激时&#xff0c;或和当某种心理因素出现时在脑区所产生的电位变化&#xff0c;成为事件相关电位&#xff0c;是一种特殊…

Sentinel-1 Level 1数据处理的详细算法定义(四)

《Sentinel-1 Level 1数据处理的详细算法定义》文档定义和描述了Sentinel-1实现的Level 1处理算法和方程,以便生成Level 1产品。这些算法适用于Sentinel-1的Stripmap、Interferometric Wide-swath (IW)、Extra-wide-swath (EW)和Wave模式。 今天介绍的内容如下: Sentinel-1 L…

【详解】Spring Cloud概述

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f525;个人专栏&#xff1a;Spring学习之路&#x1f4d5;格言&#xff1a;吾愚多不敏&#xff0c;而愿加学欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 1. 认识微服务 1.1 单体架构 1.2 集群和分布式架构 1.3 集群和分布式…

从零开始做题:什么奇奇怪怪的东西

题目 解题 mrf拓展名&#xff0c;macro recorder打开&#xff0c;鼠标键盘的记录 然后解压flag.zip即可&#xff0c;发现有一个挂载的文件&#xff0c;直接打开后 显示所有的隐藏文件 一个一个打开 然后进行拼接运行吧估计。 首先打开txt文件直接久就给出了代码&#xff1…

linux的学习(四):磁盘,进程,定时,软件包的相关命令

简介 关于磁盘管理&#xff0c;进程管理&#xff0c;定时任务&#xff0c;软件包管理的命令的使用 磁盘管理类命令 du du 目录名&#xff1a; 查看文件和目录占用的磁盘空间 参数&#xff1a; -h&#xff1a;可以看到大小的单位&#xff0c;g,mb-a&#xff1a;还可以看到文…