红外模块详解

和红外有关的模块有很多,比如红外循迹,红外感应,红外发射,红外接收,红外对射,红外编解码等等。

今天我们要介绍的是红外编解码模块,它最常见的应用就是我们家里的电视、空调,当我们按下遥控器上的按钮时,红外信号从遥控器上的红外编解码模块发射,操作电视音量增大,空调温度降低等等。

1. 源码下载及前置阅读

本文首发 良许嵌入式网 :https://www.lxlinux.net/e/ ,欢迎关注!

本文所涉及的源码及安装包如下(由于平台限制,请点击以下链接阅读原文下载):

https://www.lxlinux.net/e/stm32/infrared-sensor-tutorial.html

如果你是嵌入式开发小白,那么建议你先读读下面几篇文章。

  • 了解不同的下载程序方法,为你的嵌入式开发提供更多选择:【STM32下载程序的五种方法:https://www.lxlinux.net/e/stm32/five-ways-to-flash-program-to-stm32.html】
  • 手把手让你掌握MDK的使用方式和技巧,助你更高效地进行开发:【一文教你使用MDK开发工具:https://www.lxlinux.net/e/stm32/mdk-development-tool-tutorial.html】
  • 从零开始轻松掌握STM32开发的必备指南:【零基础快速上手STM32开发(手把手保姆级教程):https://www.lxlinux.net/e/stm32/stm32-quick-start-for-beginner.html】

前期教程,没看过的小伙伴可以先看下。

  • 嵌入式基本功,为后续学习打下坚实的基础:【STM32串口接收不定长数据(接收中断+超时判断):https://www.lxlinux.net/e/stm32/stm32-usart-receive-data-using-rxne-time-out.html】

2. 红外编解码模块介绍

2.1 型号介绍

红外编解码模块使用特定的红外协议来确保设备之间的通信准确性和兼容性。常见的红外编解码协议包括 NEC、RC5、RC6 等。

我们今天介绍的是 NEC 红外编解码模块,型号是 YS-IRTM。

  • 红外发射头: 用于发射红外信号,波长为 940nm,频率为 38k,协议为 NEC 编码的红外信号。

  • 红外接收头:用于接收 NEC 红外信号,进而单片机进行分析解码操作。

  • 红外头扩展:该接口为红外发射头的扩展,可以连接多个红外发射头(常称红外发射模块),用于安放到不同的位置,实现多方位控制。

2.2 工作参数及引脚介绍

默认波特率是 9600。

YS-IRTMSTM32
GNDGND
RXDA2(串口2)/B10(串口3)
TXDA3(串口2)/B11(串口3)
5V5V

3. 红外编解码原理

我们今天介绍的红外编解码模块采用 NEC 编码,由引导码、用户码高位、用户码低位、数据码、数据反码五部分组成。

NEC 编码格式如下:

  1. 使用 38kHz 的载波频率。

  2. 引导码间隔为 9ms+4.5ms,用于同步发送方和接收方的时钟。

  3. 用户编码用于识别设备类型,比如识别不同的遥控器。

  4. 通过脉冲串之间的时间间隔来实现信号的调制(PWM)。

    • 逻辑「0」由 0.56ms 的 38kHz 载波和 0.565ms 的无载波间隔组成,周期1.125ms。

    • 逻辑「1」由 0.56ms 的 38kHz 载波和 1.69ms 的无载波间隔组成,周期2.25ms。

  5. 结束位由 0.56ms 的 38kHz 载波组成。

学习完原理,就进行我们的实践吧。

4. 通信示意图

实现目标是我们有一个三色 LED 灯,三个灯各自有特定的信号,遥控器/手机发送红外信号,红外编解码模块收到数据,若含绿灯信号,绿灯亮;再次发送绿灯信号,绿灯灭,黄灯和红灯设定和效果一样。

5. 编程准备

我们知道,NEC 红外信号编码由 1 个 16 位用户码(分为高、低 8 位)、1 个 8 位数据码和 1 个 8 位数据码的反码组成。格式如下:

「用户码高位、用户码低位、数据码、数据反码」

我们在做解码操作时,只需要将遥控器对准红外接收头,按下需要解码的按键,即可通过串口调试助手查看到解码的结果,结果输出为「用户码高位+用户码低位+命令码」三位。

在做编码发送时发送「地址+操作位+数据位1+数据位2+数据位3」即可。

所以在正式开始前,我们需要知道我们的遥控器/手机会发出怎样的红外信号。

5.1 硬件准备与连接

准备所需要的硬件如下:

  • 红外编解码模块:YS-IRTM
  • 遥控器:红外遥控器
  • 串口:USB 转 TTL

我红外遥控器用的是正点原子的,不一定要用同款,甚至有的手机也可以当作红外遥控器用。

5.2 红外接收,查看编码

先将红外编解码模块与 USB 转 TTL 模块连接,插到电脑,用串口看看遥控器会发出怎样的编码。

接线如下:

YS-IRTMUSB 转 TTL
VCC5V
RXDTX
TXDRX
GNDGND

接好效果如下:

打开串口助手,选择你的串口号,波特率选择 9600;勾选显示接收时间,将换行输出,看的更清楚;勾选十六进制显示。

然后就可以按遥控器查看编码啦,以下是我的遥控器 1~9 的编码。我们选择 1 的 00 FF 16 为绿灯码,2 的 00 FF 19 为黄灯码,3 的 00 FF 10D 为红灯码。

5.3 红外发射

红外的发射指令格式如下:

地址操作位数据位1数据位2数据位3
A1(FA)XXXXXXXX
  • 地址:A1为默认地址(可改),FA 为通用地址 (不可改)。

  • 操作位:该位的数据用于代表当前的工作状态。

    • F1:红外发射状态
    • F2:进入修改串口通信地址状态
    • F3:进入修改波特率状态
  • 数据位:不同的操作位(工作状态)有不同的数据内容,具体可看下表。

操作位数据位1数据位2数据位3说明
F1用户码高位用户码低位命令码
F21-FF0000数据位1代表需要修改的地址值
F31-4000001 - 4800bps
02 - 9600bps
03 - 19200bps
04 - 57600bps

比如:

目的编码
发射 NEC 信号编码为 1C 2F 33A1 F1 1C 2F 33
修改串口通信地址为 0xA5A1 F2 A5 00 00
修改波特率为9600bps(对应序号2)A1 F3 02 00 00

我们发射信号后会收到如下结果:

编码意义
F1发射成功
F2串口地址修改成功
F3波特率设置成功
无返回指令接收错误、操作不成功、重启才有效

串口效果如下:

A1是串口通信默认地址,修改串口通信地址为A5后,再发送「A1 F1 00 FF 16」就收不到了,要发送「A5 F1 00 FF 16」才可以得到发射成功的「F1」。

6. 红外对射实验

我们来试试红外对射,两个红外编解码模块发送、接收。

本实验使用的硬件如下:

  • 两个红外编解码模块:YS-IRTM
  • 两个串口:USB 转 TTL

两对接线如下:

YS-IRTMUSB 转 TTL
5V5V
RXDTXD
TXDRXD
GNDGND

接好效果如下:

电脑打开两个串口调试助手,发送编码效果如下,红框和绿框各是一次发送结果。

红外对射的交互方式虽然简单,但是有很多应用场景。例如利用红外对射进行无线控制和交互,实现遥控车辆、飞行器、电子游戏等的操作和反馈。

7. 编程实战

7.1 硬件接线

本教程使用的硬件如下:

  • 单片机:STM32F103C8T6
  • 红外编解码模块:YS-IRTM
  • 遥控器:红外遥控器
  • 小灯:三色 LED 灯模块
  • 串口:USB 转 TTL
  • 烧录器:ST-LINK V2

接线如下:

YS-IRTMLEDSTM32USB 转 TTL
5V5V
RXDA2
TXDA3
GNDG
RA5
YA6
GA7
GNDG
A10TX
A9RX
GGND

烧录的时候接线如下表,如果不会烧录的话可以看我之前的文章【STM32下载程序的五种方法:https://www.lxlinux.net/e/stm32/five-ways-to-flash-program-to-stm32.html】。

ST-Link V2STM32
SWCLKSWCLK
SWDIOSWDIO
GNDGND
3.3V3V3

接好如下图:

7.2 串口接收数据

串口接收数据在【STM32串口接收不定长数据(接收中断+超时判断):https://www.lxlinux.net/e/stm32/stm32-usart-receive-data-using-rxne-time-out.html】有详细介绍,没看过的小伙伴可以看看。

UART_HandleTypeDef ys_uart_handle;uint8_t ys_uart_rx_buf[YS_RX_BUF_SIZE];
uint8_t ys_uart_tx_buf[YS_TX_BUF_SIZE];
uint16_t ys_uart_rx_len = 0;void ys_init(uint32_t baudrate)
{ys_uart_handle.Instance          = YS_INTERFACE;                 /* BT */ys_uart_handle.Init.BaudRate     = baudrate;                     /* 波特率 */ys_uart_handle.Init.WordLength   = UART_WORDLENGTH_8B;           /* 数据位 */ys_uart_handle.Init.StopBits     = UART_STOPBITS_1;              /* 停止位 */ys_uart_handle.Init.Parity       = UART_PARITY_NONE;             /* 校验位 */ys_uart_handle.Init.Mode         = UART_MODE_TX_RX;              /* 收发模式 */ys_uart_handle.Init.HwFlowCtl    = UART_HWCONTROL_NONE;          /* 无硬件流控 */ys_uart_handle.Init.OverSampling = UART_OVERSAMPLING_16;         /* 过采样 */HAL_UART_Init(&ys_uart_handle);                                  /* 使能BT */
}void ys_rx_clear(void)
{memset(ys_uart_rx_buf, 0, sizeof(ys_uart_rx_buf));              //清空接收缓冲区ys_uart_rx_len = 0;                                             //接收计数器清零
}void YS_IRQHandler(void)
{uint8_t receive_data = 0;   if(__HAL_UART_GET_FLAG(&ys_uart_handle, UART_FLAG_RXNE) != RESET){      //获取接收RXNE标志位是否被置位if(ys_uart_rx_len >= sizeof(ys_uart_rx_buf))                        //如果接收的字符数大于接收缓冲区大小,ys_uart_rx_len = 0;                                             //则将接收计数器清零HAL_UART_Receive(&ys_uart_handle, &receive_data, 1, 1000);          //接收一个字符ys_uart_rx_buf[ys_uart_rx_len++] = receive_data;                    //将接收到的字符保存在接收缓冲区}if (__HAL_UART_GET_FLAG(&ys_uart_handle, UART_FLAG_IDLE) != RESET)      //获取接收空闲中断标志位是否被置位{int i = 0;printf("receive: \r\n");for(i = 0; i < ys_uart_rx_len; i++ )printf("%02X ", ys_uart_rx_buf[i]);                             //将接收到的数据打印出来printf("\r\n");control_led();ys_rx_clear();__HAL_UART_CLEAR_IDLEFLAG(&ys_uart_handle);                         //清除UART总线空闲中断}
}

7.3 LED初始化

LED 灯的代码简简单单,只要进行一下三个灯的初始化就行。

void led_init(void)
{GPIO_InitTypeDef gpio_init_struct;LED1_GPIO_CLK_ENABLE();                                 /* LED1时钟使能 */LED2_GPIO_CLK_ENABLE();                                 /* LED2时钟使能 */LED3_GPIO_CLK_ENABLE();                                 /* LED3时钟使能 */gpio_init_struct.Pin = LED1_GPIO_PIN;                   /* LED1引脚 */gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;            /* 推挽输出 */gpio_init_struct.Pull = GPIO_PULLUP;                    /* 上拉 */gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;          /* 高速 */HAL_GPIO_Init(LED1_GPIO_PORT, &gpio_init_struct);       /* 初始化LED1引脚 */gpio_init_struct.Pin = LED2_GPIO_PIN;                   /* LED2引脚 */HAL_GPIO_Init(LED2_GPIO_PORT, &gpio_init_struct);       /* 初始化LED2引脚 */gpio_init_struct.Pin = LED3_GPIO_PIN;                   /* LED3引脚 */HAL_GPIO_Init(LED3_GPIO_PORT, &gpio_init_struct);       /* 初始化LED3引脚 */LED1(0);                                                /* 关闭 LED1 */LED2(0);                                                /* 关闭 LED2 */LED3(0);                                                /* 关闭 LED3 */
}

LED 的 .h文件:

#ifndef _LED_H
#define _LED_H
#include "sys.h"/******************************************************************************************/
/* 引脚 定义 */#define LED1_GPIO_PORT                  GPIOA
#define LED1_GPIO_PIN                   GPIO_PIN_7
#define LED1_GPIO_CLK_ENABLE()          do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)             /* PA口时钟使能 */#define LED2_GPIO_PORT                  GPIOA
#define LED2_GPIO_PIN                   GPIO_PIN_6
#define LED2_GPIO_CLK_ENABLE()          do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)             /* PA口时钟使能 */#define LED3_GPIO_PORT                  GPIOA
#define LED3_GPIO_PIN                   GPIO_PIN_5
#define LED3_GPIO_CLK_ENABLE()          do{ __HAL_RCC_GPIOA_CLK_ENABLE(); }while(0)             /* PB口时钟使能 *//******************************************************************************************/
/* LED端口定义 */
#define LED1(x)   do{ x ? \HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_SET) : \HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_RESET); \}while(0)#define LED2(x)   do{ x ? \HAL_GPIO_WritePin(LED2_GPIO_PORT, LED2_GPIO_PIN, GPIO_PIN_SET) : \HAL_GPIO_WritePin(LED2_GPIO_PORT, LED2_GPIO_PIN, GPIO_PIN_RESET); \}while(0)#define LED3(x)   do{ x ? \HAL_GPIO_WritePin(LED3_GPIO_PORT, LED3_GPIO_PIN, GPIO_PIN_SET) : \HAL_GPIO_WritePin(LED3_GPIO_PORT, LED3_GPIO_PIN, GPIO_PIN_RESET); \}while(0)/* LED取反定义 */
#define LED1_TOGGLE()   do{ HAL_GPIO_TogglePin(LED1_GPIO_PORT, LED1_GPIO_PIN); }while(0)        /* 翻转LED1 */
#define LED2_TOGGLE()   do{ HAL_GPIO_TogglePin(LED2_GPIO_PORT, LED2_GPIO_PIN); }while(0)        /* 翻转LED2 */
#define LED3_TOGGLE()   do{ HAL_GPIO_TogglePin(LED3_GPIO_PORT, LED3_GPIO_PIN); }while(0)        /* 翻转LED3 *//******************************************************************************************/
/* 外部接口函数*/
void led_init(void);                                                                            /* LED初始化 */#endif

7.4 LED控制

我的遥控器前两位都一样,只需要判断第三位是不是为绿/黄/红灯码即可。若前两位都不正确,那就不是我的遥控器发出的红外信号,不用再往下判断了。

void control_led(void)
{if(ys_uart_rx_buf[0] == 0x00 && ys_uart_rx_buf[1] == 0xFF)      //地址码正确{switch(ys_uart_rx_buf[2])                                     //判断数据码{case 0x16:                                                  //绿灯码LED1_TOGGLE();                                            //翻转LED1break;case 0x19:                                                  //黄灯码LED2_TOGGLE();                                            //翻转LED2break;case 0x0D:                                                  //红灯码LED3_TOGGLE();                                            //翻转LED3break;}}
}

7.5 主函数

主函数如下:

int main(void)
{HAL_Init();                                 /* 初始化HAL库 */sys_stm32_clock_init(RCC_PLL_MUL9);         /* 设置时钟,72M */delay_init(72);                             /* 初始化延时函数 */usart_init(115200);                         /* 串口1波特率设为115200 */ys_init(9600);                              /* 串口2波特率设为9600 */led_init();printf("红外控制灯……\r\n");while(1){delay_ms(1000);}
}

7.6 运行过程

烧录后,打开串口,按下遥控器1、2、3,效果如下。

红外编解码模块(串口2)波特率是9600,串口调试助手接收的是单片机(串口1)的数据,波特率115200,大家不要弄混啦。

我们的三个小灯也打开了。(我的小绿灯不是很亮,用旧了,嘻嘻)

8. 总结

祝贺大家成功点灯!当然,除了控制灯的开关,红外编解码模块还可以应用于更广泛的场景,如家庭娱乐、医疗保健、工业自动化等等。随着技术的不断进步,红外技术将持续演进,并在更多领域发挥作用。希望本文能够为你提供了一个初步的了解,并激发你进一步深入研究和应用红外技术的兴趣。感谢各位看官,love and peace!

另外,想进大厂的同学,一定要好好学算法,这是面试必备的。这里准备了一份 BAT 大佬总结的 LeetCode 刷题宝典,很多人靠它们进了大厂。

刷题 | LeetCode算法刷题神器,看完 BAT 随你挑!

有收获?希望老铁们来个三连击,给更多的人看到这篇文章

推荐阅读:

  • 程序员必备编程资料大全
  • 程序员必备软件资源

欢迎关注我的博客:良许嵌入式教程网,满满都是干货!

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

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

相关文章

Java语法学习线程基础

Java语法学习线程基础 大纲 概念创建线程线程终止常用方法用户线程和守护线程线程的七大状态线程的同步互斥锁线程死锁释放锁 具体案例 1.概念 2. 创建线程 第一种&#xff1a; class Cat extends Thread {int time 0;Overridepublic void run() {while (true) {System.o…

HttpRunner自动化测试工具之获取响应数据extract提取值到变量

获取响应数据 extract: 提取 注&#xff1a;extract 应与request保持同一层级 1、响应行&#xff0c;响应头&#xff1b;通过 extract 提取响应的数据并存储到变量中&#xff0c;如下图&#xff1a; 注&#xff1a;变量名的前面要有 - # 获取响应数据: 响应行&#xff08;…

通过Nacos权重配置,实现微服务金丝雀发布效果(不停机部署)

在微服务项目迭代的过程中&#xff0c;不可避免需要上线&#xff1b;上线对应着部署&#xff0c;或者升级部署&#xff1b;部署对应着修改,修改则意味着风险。 传统的部署都需要先停止旧系统&#xff0c;然后部署新系统&#xff0c;之后需要对新系统进行全面的功能测试&#xf…

NAS系统折腾记 – Emby搭建家庭多媒体服务器

Emby简介 Emby是一款优秀的媒体服务器软件&#xff0c;致力于为用户提供丰富的多媒体体验。通过Emby&#xff0c;您可以方便地在家庭内的各种设备上观看您喜爱的电影、电视剧和其他视频内容。而且&#xff0c;Emby还具备强大的媒体管理功能&#xff0c;让您的影视资源井然有序…

设置Nginx进程最大可打开文件数

打开nginx.conf主配置文件。您需要配合worker_rlimit_nofile属性。如下&#xff1a; user root root; worker_processes 4; worker_rlimit_nofile 65535;#error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info;#pid logs/nginx.pid; …

26条prompt规则应用于大模型

1、引入动机 llm大模型在回答一些问题上表现出了惊人的能力&#xff0c;例如数学逻辑推理&#xff0c;代码生成&#xff0c;问题答复等。提词工程是和大预言模型交流的一门艺术。 大模型的返回结合和用户的指令和输入直接相关prompts是用户和大模型沟通的一种编码方式 一般地…

逆向基础-破解密码

1.通过study PE查看.exe程序的位数 打开 x32dbg 从暂停到运行程序 原理&#xff1a;软件算出的密码与用户输入的密码作比较 破解流程&#xff1a;查信息 --> 找内存关键数据 --> 测试

物流平台架构设计与实践

随着电商行业的迅猛发展&#xff0c;物流行业也得到了极大的发展。从最初的传统物流到现在的智慧物流&#xff0c;物流技术和模式也在不断的更新与升级。物流平台作为连接电商和物流的重要媒介&#xff0c;其架构设计和实践显得尤为重要。 一、物流平台架构设计 1. 前端架构设…

寒假 day1

1、请简述栈区和堆区的区别? 2、有一个整形数组:int arr[](数组的值由外部输入决定)&#xff0c;一个整型变量: x(也 由外部输入决定)。要求: 1)删除数组中与x的值相等的元素 2)不得创建新的数组 3)最多只允许使用单层循环 4)无需考虑超出新数组长度后面的元素&#xff0c;所以…

【FFmpeg】ffplay 命令行参数 ① ( 设置播放分辨率 | 禁用 音频 / 视频 / 字幕 选项 )

文章目录 一、ffplay 命令行参数 - 设置播放分辨率1、强制设置通用播放分辨率 -x -y 参数2、命令行示例 - 正常播放视频3、命令行示例 - 强制设置播放分辨率4、设置 YUV 播放分辨率 -video_size 和 像素设置 -pixel_format5、全屏播放 -fs 参数 二、ffplay 命令行参数 - 禁用 音…

vue-cli项目运行流程介绍

一、前言 ​ 本文介绍 vue-cli搭建的项目运行流程&#xff0c;基于已经搭建好的基础项目。关于 vue-cli 构建项目的详细流程&#xff0c;可参考博文&#xff1a;使用vue脚手架构建项目 二、main.js 项目运行 会加载入口文件 main.js /* html文件中&#xff0c;通过script …

深入学习《大学计算机》系列之第1章 1.6节——你真的了解计算机存储器吗

一.欢迎来到我的酒馆 第1章 1.6节&#xff0c;你真的了解计算机存储器吗。 目录 一.欢迎来到我的酒馆二.计算机存储器2.1 计算机存储器简介2.2 计算机存储器发展史2.3 计算机存储器发展史总结 三.计算机存储器分类3.1 主存储器3.2 内存3.3 缓存3.4 寄存器3.5 二级存储器3.6 存…

09. BI - 数据可视化,如何进行基本图形绘制

本文为 「茶桁的 AI 秘籍 - BI 篇 第 09 篇」 文章目录 EDA 作用可视化视图Python 进行可视化subplot Hi&#xff0c;你好。我是茶桁。 今天想给大家讲的是关于数据的可视化。在工作中很多时候我们不光要计算结果&#xff0c;还要把结果呈现出来&#xff0c;最好是一种图形化的…

微服务中间件 RabbitMq学习

1、为什么需要Mq 例如在用户注册业务中&#xff0c;用户注册成功后 需要发注册邮件和注册短信&#xff0c;传统的做法有两种 1.串行的方式&#xff1b;2.并行的方式 &#xff1b; 假设三个业务节点分别使用50ms&#xff0c;串行方式使用时间150ms&#xff0c;并行使用时间10…

【实战】阿里智能编码助手通义灵码

文章目录 前言技术积累通义灵码是什么&#xff1f;Copilot是什么&#xff1f;通义灵码主要功能通义灵码有哪些优势&#xff1f;通义灵码支持语言/工具通义灵码接入方式通义灵码帮助中心 实战演示安装插件行/函数级实时续写自然语言生成代码代码优化单元测试生成代码注释生成解释…

streampark+flink一键整库或多表同步mysql到doris实战

streamparkflink一键整库或多表同步mysql到doris实战&#xff0c;此应用一旦推广起来&#xff0c;那么数据实时异构时&#xff0c;不仅可以减少对数据库的查询压力&#xff0c;还可以减少数据同步时的至少50%的成本&#xff0c;还可以减少30%的存储成本&#xff1b; streampar…

代码随想录算法训练营第38天 | 动态规划理论基础 + 509.斐波那契数 + 70.爬楼梯 + 746.使用最小花费爬楼梯

今日任务 理论基础 509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯 动态规划理论基础 理论基础&#xff1a;代码随想录 动态规划&#xff0c;英文&#xff1a;Dynamic Programming&#xff0c;简称DP&#xff0c;如果某一问题有很多重叠子问题&#xff0c;使用动态规划…

Linux---进程间通信 | 管道 | PIPE | MKFIFO | 共享内存 | 消息队列

管道 管道是UNIX中最古老的进程间通信的形式&#xff0c;我们把从一个进程连接到另一个进程的数据流称为一个管道。 一个文件&#xff0c;可以被多个进程打开吗&#xff1f;可以&#xff0c;那如果一个进程打开文件&#xff0c;往文件里面写数据&#xff0c;另一个进程打开文…

GLIP:零样本学习 + 目标检测 + 视觉语言大模型

GLIP 核心思想GLIP 对比 BLIP、BLIP-2、CLIP 主要问题: 如何构建一个能够在不同任务和领域中以零样本或少样本方式无缝迁移的预训练模型&#xff1f;统一的短语定位损失语言意识的深度融合预训练数据类型的结合语义丰富数据的扩展零样本和少样本迁移学习 效果 论文&#xff1a;…

【Leetcode】第 383 场周赛

文章目录 100214. 边界上的蚂蚁题目思路代码结果 100204. 将单词恢复初始状态所需的最短时间 I题目思路代码结果 100189. 找出网格的区域平均强度题目思路代码结果 100203. 将单词恢复初始状态所需的最短时间 II题目思路代码结果 100214. 边界上的蚂蚁 题目 题目链接 给你一个…