51单片机--红外遥控

文章目录

  • 红外遥控的介绍
  • 硬件电路
  • NEC编码
  • 外部中断
  • 红外遥控实例代码

红外遥控的介绍

红外遥控是一种无线、非接触控制技术,通过使用红外线来传送控制信号。它具有抗干扰能力强、信息传输可靠、功耗低、成本低、易实现等显著优点,因此被广泛应用于各种电子设备和家用电器,也越来越多地应用于计算机和手机系统中。
在这里插入图片描述

硬件电路

红外遥控系统一般由发射和接收两个部分组成。发射部分包括红外发光二极管,它是一种特殊的发光二极管,能够发射调制后的红外光波。接收部分通常采用红外接收模块,用于接收来自遥控器发射的红外信号。当遥控器处于学习状态时,接收模块会接收外来红外信号,并将其转换成电信号。经过检波、整形和放大等处理后,这些电信号会被传送到中央处理单元(CPU)进行解码和执行相应的控制动作。

发射端
在这里插入图片描述
IN是输入信号端口,输入的信号会通过38kHz的频率在三极管中放大,到发光二极管中,二极管发出闪烁着的特制红外光线
在现实生活中有很多种类型的红外线,为了让接收方只接收这一类型的红外线,就在电路中加入了频率,让这个信号能有一定频率的闪烁;
当我们没有输入时,默认为高电平,而当我们输入信号时,就会在低电平发出有频率波动的信号
在这里插入图片描述

接收端
在这里插入图片描述
这里将接收的发光二极管内置在了电路中,电路也很容易,电源、接地、以及信号输出
在这里我们会让OUT端口接上外部中断,当产生下降沿就进入中断
在这里插入图片描述

NEC编码

NEC编码是一种红外遥控协议,常用于遥控器与设备之间的通信。它是一种常用的编码格式;将遥控发送过来的信号进行一定形式的编码,转换为对应的信息
在这里插入图片描述
NEC编码的数据格式通常由以下几部分组成:

  1. 引导码(Leader Code):持续低电平(通常为9ms)和持续高电平(通常为4.5ms),用于标识开始传输数据。

  2. 系统码(Customer Code):8位二进制代码,用于识别具体的设备或品牌。

  3. 数据码(Data Code):8位二进制代码,表示具体的指令或按键信息。在传输数据时一般持续低电平(560us)和持续高电平(560us)表示传输‘0’,持续低电平(560us)和持续高电平(1690us)表示传输‘1’;

  4. 取反码(Inverted Data Code):与数据码和系统码相反的二进制代码,用于检验数据的正确性。

  5. 结束码(Stop Bit):持续高电平(通常为0.56ms),表示数据传输结束。在这里,我们没有引用到;

  6. 重复码(Repeat Code):数据传输之后,若持续低电平(9ms)和持续高电平(2.25ms),那么将会重复这个命令信息;

在这里插入图片描述

NEC编码使用38kHz的载波频率进行传输,通过在红外光线的调制和解调实现遥控功能。在发射时,数据按照引导码、系统码、数据码和取反码的顺序发送;在接收端,通过解码器将红外信号还原为对应的系统码和数据码,从而实现遥控器与设备的交互。

外部中断

51单片机的外部中断是指通过外部信号触发单片机进行中断处理的一种机制。单片机通过外部引脚接收到特定的信号后,会立即暂停当前的任务,转而执行与该中断相关的程序。

在51单片机中,有两个外部中断源,分别为外部中断0(INT0)和外部中断1(INT1)。这两个中断源分别对应单片机的引脚P3.2和P3.3。
在这里插入图片描述

外部中断可以通过两种触发方式来进行中断处理:电平触发和边沿触发。电平触发是指当外部信号维持在某个电平上时触发中断,可以是低电平触发或高电平触发;边沿触发是指当外部信号的跳变沿(上升沿或下降沿)出现时触发中断。

中断号
在这里插入图片描述

此次操作相关寄存器以及原理
在这里插入图片描述

使用外部中断前,需要进行相应的初始化操作。

初始化

void Interrupt0_Init()
{
	IT0=1;//外部中断0选择边沿触发
	IE0=1;//外部中断0请求标志
	EX0=1;//外部中断0请求允许位
	EA=1;//总中断允许
	PX0=1;//中断优先级控制
}

红外遥控实例代码

接下来,我们要实现的是在屏幕上显示地址,命令码,数字增减,通过遥控的控制,让命令码随之改变,数字达到增减;
在这里插入图片描述
在这里插入图片描述

我们将通过定时器和外部中断0来进行操控,写出NEC编码;
利用不同的状态表示到达不同的编码阶段;
在这里插入图片描述

Timer0.h

#ifndef __TIMER0_H__
#define __TIMER0_H__

void Timer0Init();
void Timer0_SetCounter(unsigned int Value);
unsigned int Timer0_GetCounter();
void Timer0_Run(unsigned char Flag);
#endif

Timer0.c

#include <REGX52.H>

/**
  * @brief 定时器0初始化
	* @param 无
	* @reval 无
  */
void Timer0Init(void)		//1毫秒@11.0592MHz
{
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |=0x01;
	TL0 = 0;		//设置定时初值
	TH0 = 0;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 0;		//定时器0不计时
	
}

//定时器0设置计数器值,范围0-65535
void Timer0_SetCounter(unsigned int Value)
{
	TH0=Value/256;
	TL0=Value%256;
}


//定时器0获取计数器值
unsigned int Timer0_GetCounter()
{
	return (TH0<<8)|TL0;
}

//定时器0启动停止控制
void Timer0_Run(unsigned char Flag)
{
	TR0=Flag;
}


将定时器初始化为0,让定时器实现计时器的功能;

Interrupt.h

#ifndef __INTERRUPT_H__
#define __INTERRUPT_H__

void Interrupt0_Init();

#endif

Interrupt.c

#include <REGX52.H>

//外部中断0初始化
void Interrupt0_Init()
{
	IT0=1;
	IE0=1;
	EX0=1;
	EA=1;
	PX0=1;
}

按键对应命令码:
在这里插入图片描述

IR.h

#ifndef __IR_H__
#define __IR_H__


#define IR_POWER		0x45
#define IR_MODE			0x46
#define IR_MUTE			0x47
#define IR_START_STOP	0x44
#define IR_PREVIOUS		0x40
#define IR_NEXT			0x43
#define IR_EQ			0x07
#define IR_VOL_MINUS	0x15
#define IR_VOL_ADD		0x09
#define IR_0			0x16
#define IR_RPT			0x19
#define IR_USD			0x0D
#define IR_1			0x0C
#define IR_2			0x18
#define IR_3			0x5E
#define IR_4			0x08
#define IR_5			0x1C
#define IR_6			0x5A
#define IR_7			0x42
#define IR_8			0x52
#define IR_9			0x4A




void IR_Init();
unsigned char IR_GetDataFlag();
unsigned char IR_GetRepeatFlag();
unsigned char IR_GetAddress();
unsigned char IR_GetCommand();

#endif

IR.c

#include <REGX52.H>
#include"Timer0.h"
#include"Interrupt.h"

unsigned int IR_Time;
unsigned char IR_State;

unsigned char IR_Data[4];
unsigned char IR_pData;

unsigned char IR_DataFlag;
unsigned char IR_RepeatFlag;
unsigned char IR_Address;
unsigned char IR_Command;

//红外遥控初始化
void IR_Init()
{
	Timer0Init();
	Interrupt0_Init();
}


//红外遥控获取收到数据帧标志位
unsigned char IR_GetDataFlag()
{
	if(IR_DataFlag)
	{
		IR_DataFlag=0;
		return 1;
	}
	return 0;
}

//红外遥控获取收到连发标志位
unsigned char IR_GetRepeatFlag()
{
	if(IR_DataFlag)
	{
		IR_RepeatFlag=0;
		return 1;
	}
	return 0;
}

//红外遥控获取收到的地址数据
unsigned char IR_GetAddress()
{
	return IR_Address;
}

//红外遥控获取收到的命令数
unsigned char IR_GetCommand()
{
	return IR_Command;
}

//外部中断0函数
void Int0_Routine() interrupt 0
{
	if(IR_State==0)  //状态0,空闲状态
	{
		Timer0_SetCounter(0); //计数器清0
		Timer0_Run(1); //定时器启动
		IR_State=1; //变为状态1
	}
	else if(IR_State==1) //状态1,等待Start信号或Repeat信号
	{
		IR_Time=Timer0_GetCounter(); //获取开始的时间或重复的时间
		Timer0_SetCounter(0); //计时器清0
		if(IR_Time>12442-500&&IR_Time<12442+500)//表示是开始信号,进入下一阶段
		{
			IR_State=2;
		}
		else if(IR_Time>10368-500&&IR_Time<10368+500)//是重复信号,回到最初的起点
		{
			IR_RepeatFlag=1; //连发帧标志位置1
			Timer0_Run(0); //定时器停止
			IR_State=0;  //状态置0
		}
		else
		{
			IR_State=1;
		}
	}
	else if(IR_State==2) //状态2,接收数据
	{
		IR_Time=Timer0_GetCounter();//获取接收数据的时间段
		Timer0_SetCounter(0);
		if(IR_Time>1032-500&&IR_Time<1032+500)//数据接到为0
		{
			IR_Data[IR_pData/8]&=~(0x01<<(IR_pData%8));
			IR_pData++;
		}
		else if(IR_Time>2074-500&&IR_Time<2074+500)//数据接收到为1
		{
			IR_Data[IR_pData/8]|=(0x01<<(IR_pData%8));//除8是将32位下标分为4个元素,模8将32位下标从0~7有序循环
			IR_pData++;
		}
		else //接收错误
		{
			IR_pData=0;
			IR_State=1;
		}
		if(IR_pData>=32) //如果收到了32位
		{
			IR_pData=0; //下标清0
			if((IR_Data[0]==~IR_Data[1])&&(IR_Data[2]==~IR_Data[3])) //数据验证
			{
				IR_Address=IR_Data[0]; //存储数据
				IR_Command=IR_Data[2];
				IR_DataFlag=1; //数据帧标志位置1
			}
			Timer0_Run(0); //定时器停止
			IR_State=0; //状态置0
			
		}
	}
}

LCD1602.c

#include <REGX52.H>

//引脚配置:
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_EN=P2^7;
#define LCD_DataPort P0

//函数定义:
/**
  * @brief  LCD1602延时函数,12MHz调用可延时1ms
  * @param  无
  * @retval 无
  */
void LCD_Delay()
{
	unsigned char i, j;

	i = 2;
	j = 239;
	do
	{
		while (--j);
	} while (--i);
}

/**
  * @brief  LCD1602写命令
  * @param  Command 要写入的命令
  * @retval 无
  */
void LCD_WriteCommand(unsigned char Command)
{
	LCD_RS=0;
	LCD_RW=0;
	LCD_DataPort=Command;
	LCD_EN=1;
	LCD_Delay();
	LCD_EN=0;
	LCD_Delay();
}

/**
  * @brief  LCD1602写数据
  * @param  Data 要写入的数据
  * @retval 无
  */
void LCD_WriteData(unsigned char Data)
{
	LCD_RS=1;
	LCD_RW=0;
	LCD_DataPort=Data;
	LCD_EN=1;
	LCD_Delay();
	LCD_EN=0;
	LCD_Delay();
}

/**
  * @brief  LCD1602设置光标位置
  * @param  Line 行位置,范围:1~2
  * @param  Column 列位置,范围:1~16
  * @retval 无
  */
void LCD_SetCursor(unsigned char Line,unsigned char Column)
{
	if(Line==1)
	{
		LCD_WriteCommand(0x80|(Column-1));
	}
	else if(Line==2)
	{
		LCD_WriteCommand(0x80|(Column-1+0x40));
	}
}

/**
  * @brief  LCD1602初始化函数
  * @param  无
  * @retval 无
  */
void LCD_Init()
{
	LCD_WriteCommand(0x38);//八位数据接口,两行显示,5*7点阵
	LCD_WriteCommand(0x0c);//显示开,光标关,闪烁关
	LCD_WriteCommand(0x06);//数据读写操作后,光标自动加一,画面不动
	LCD_WriteCommand(0x01);//光标复位,清屏
}

/**
  * @brief  在LCD1602指定位置上显示一个字符
  * @param  Line 行位置,范围:1~2
  * @param  Column 列位置,范围:1~16
  * @param  Char 要显示的字符
  * @retval 无
  */
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char)
{
	LCD_SetCursor(Line,Column);
	LCD_WriteData(Char);
}

/**
  * @brief  在LCD1602指定位置开始显示所给字符串
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  String 要显示的字符串
  * @retval 无
  */
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=0;String[i]!='\0';i++)
	{
		LCD_WriteData(String[i]);
	}
}

/**
  * @brief  返回值=X的Y次方
  */
int LCD_Pow(int X,int Y)
{
	unsigned char i;
	int Result=1;
	for(i=0;i<Y;i++)
	{
		Result*=X;
	}
	return Result;
}

/**
  * @brief  在LCD1602指定位置开始显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~65535
  * @param  Length 要显示数字的长度,范围:1~5
  * @retval 无
  */
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');
	}
}

/**
  * @brief  在LCD1602指定位置开始以有符号十进制显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:-32768~32767
  * @param  Length 要显示数字的长度,范围:1~5
  * @retval 无
  */
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length)
{
	unsigned char i;
	unsigned int Number1;
	LCD_SetCursor(Line,Column);
	if(Number>=0)
	{
		LCD_WriteData('+');
		Number1=Number;
	}
	else
	{
		LCD_WriteData('-');
		Number1=-Number;
	}
	for(i=Length;i>0;i--)
	{
		LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');
	}
}

/**
  * @brief  在LCD1602指定位置开始以十六进制显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~0xFFFF
  * @param  Length 要显示数字的长度,范围:1~4
  * @retval 无
  */
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i,SingleNumber;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		SingleNumber=Number/LCD_Pow(16,i-1)%16;
		if(SingleNumber<10)
		{
			LCD_WriteData(SingleNumber+'0');
		}
		else
		{
			LCD_WriteData(SingleNumber-10+'A');
		}
	}
}

/**
  * @brief  在LCD1602指定位置开始以二进制显示所给数字
  * @param  Line 起始行位置,范围:1~2
  * @param  Column 起始列位置,范围:1~16
  * @param  Number 要显示的数字,范围:0~1111 1111 1111 1111
  * @param  Length 要显示数字的长度,范围:1~16
  * @retval 无
  */
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length)
{
	unsigned char i;
	LCD_SetCursor(Line,Column);
	for(i=Length;i>0;i--)
	{
		LCD_WriteData(Number/LCD_Pow(2,i-1)%2+'0');
	}
}

LCD1602.h

#ifndef __LCD1602_H__
#define __LCD1602_H__

//用户调用函数:
void LCD_Init();
void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char);
void LCD_ShowString(unsigned char Line,unsigned char Column,char *String);
void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length);
void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);
void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);

#endif

main.c

#include <REGX52.H>

#include"LCD1602.h"
#include"IR.h"

unsigned char Num;
unsigned char Address;
unsigned char Command;

void main()
{
	LCD_Init();
	LCD_ShowString(1,1,"ADDR  CMD  NUM");
	LCD_ShowString(2,1,"00    00   000");

	IR_Init(); //NEC编码初始化
	while(1)
	{
		if(IR_GetDataFlag()||IR_GetRepeatFlag()) //数据帧或者重复帧
		{
			Address=IR_GetAddress(); //获取遥控器地址吗
			Command=IR_GetCommand(); //获取遥控器命令吗
			
			LCD_ShowHexNum(2,1,Address,2);
			LCD_ShowHexNum(2,7,Command,2);
			
			if(Command==IR_VOL_MINUS)
			{
				Num--;
			}
			if(Command==IR_VOL_ADD)
			{
				Num++;
			}
			LCD_ShowNum(2,12,Num,3);
			
		}
	}
}

通过判断标志位是否为1来表示是否有遥控信息传输

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

IDEA Debug小技巧 添加减少所查看变量、查看不同线程

问题 IDEA的Debug肯定都用过。它下面显示的变量&#xff0c;有什么门道&#xff1f;可以增加变量、查看线程吗&#xff1f; 答案是&#xff1a;可以。 演示代码 代码如下&#xff1a; package cn.itcast.attempt.threadAttempt.attempt2;public class Test {public static …

27岁到来之际,我在阿里实现了年薪30W+的小目标

毕业快 5 年了&#xff0c;每当和人聊起自己的职场飞升之路&#xff0c;都不由得感激当初果断逃离舒适圈的自己。出身一所非 211、985 院校&#xff0c;毕业后入职了一家小型互联网公司&#xff0c;当着普普通通的初级测试工程师&#xff0c;工作期间虽然也时常遇到挑战&#x…

HTTP之Session、Cookie 与 Application

目录 简介cookiecookie生命周期 sessionsession生命周期 HTTP cookies示例application 简介 cookie、seesion、application三个都会缓存我们用户状态的数据&#xff0c;使得我们在浏览器访问网站时可以更快速的获取到信息。 主要原因在于HTTP协议是无状态的&#xff0c;我们每…

计算机视觉(四)神经网络与典型的机器学习步骤

文章目录 神经网络生物神经元人工神经元激活函数导数 人工神经网络“层”的通俗理解 前馈神经网络Delta学习规则前馈神经网络的目标函数梯度下降输出层权重改变量 误差方向传播算法误差传播迭代公式简单的BP算例随机梯度下降&#xff08;SGD&#xff09;Mini-batch Gradient De…

搭建工程化项目

搭建工程化项目 首先创建一个 study 空文件夹&#xff0c;并且把它拖到 VS Code 里面。 在 VS Code 中打开终端&#xff0c;快捷键 ctrl ~ 在命令行中输入 npm init&#xff0c;在接下来所有选项中全部按 “回车” 采用默认即可。 初始化完毕后&#xff0c;在项目根目录下会出…

TypeScript 【type】关键字的进阶使用方式

导语&#xff1a; 在前面章节中&#xff0c;我们了解到 TS 中 type 这个关键字&#xff0c;常常被用作于&#xff0c;定义 类型别名&#xff0c;用来简化或复用复杂联合类型的时候使用。同时也了解到 为对象定义约束接口类型 的时候所使用的是 Interfaces。 其实对于前面&#…

C# Blazor 学习笔记(4):blazor代码分离

文章目录 前言代码分离 前言 Blazor可以支持在razor文件里面添加cs代码&#xff0c;但是代码一旦复杂了之后就会变得特别的麻烦。但是VS提供了代码分组的功能。 分离前 分离后 代码分离 我们直接右键razor组件是不能直接添加cs代码部分的 注意新建类的类名是xxx.razor…

软考中级信息安全工程师2023下半年报名时间及报名入口官网

软考中级信息安全工程师2023下半年考试时间&#xff1a; 2023年下半年软考中级信息安全工程师的考试时间为11月4日、5日。考试时间在全国各地一致&#xff0c;建议考生提前备考。共分两科&#xff0c;第一科基础知识考试具体时间为9:00-11:30&#xff1b;第二科应用技术考试具…

transformers里的AutoTokenizer之返回值token_type_ids(二)

在很多案例中&#xff0c;AutoTokenizer会返回token_type_ids这个结果&#xff1a; token_type_ids的解释&#xff1a; 对于两个句子对来说&#xff0c;上一句都标识为0&#xff0c;下一句都标识为1。

Hadoop优化

1.Datanode管理多块数据盘 1.理解 其实就是扩展Datanode空间,之前一个盘,现在加一个盘或者多个盘, 2.优点: 1.提高容错(避免硬盘损坏全部数据丢失)2.实现数据分离模式存储(框架本体与数据分离,集群出现问题数据可进行单独恢复,这样也是提高容错) 3.配置&#xff08;临时挂…

[PyTorch][chapter 45][RNN_2]

目录&#xff1a; RNN 问题 RNN 时序链问题 RNN 词组预测的例子 RNN简洁实现 一 RNN 问题 RNN 主要有两个问题&#xff0c;梯度弥散和梯度爆炸 1.1 损失函数 梯度 其中&#xff1a; 则 1.1 梯度爆炸&#xff08;Gradient Exploding&#xff09; 上面矩阵进行连乘后…

uniapp使用getStorage对属性赋值无效

1正常set(get)storage都是可以正常使用的 2.但对属性进行赋值的时候&#xff0c;却发现this.name并没有发生变化 3. 在里面打印this发现&#xff0c;在set*getStorage中并不能拿到this. 4.优化代码 这样就可以给this.name成功赋值

重学C++系列之STL库

一、什么是STL库 STL是“Standard Template Library”的缩写&#xff0c;中文翻译为“标准模板库”。CSTL是一套功能强大的C模板类&#xff0c;提供了通用的模板类和函数&#xff0c;这些模板类和函数可以实现多种流行和常用的算法和数据结构&#xff0c;如字符串操作、链表、队…

如何为新一代可持续应用设计电机编码器

从定速电机转向提供位置和电流反馈的变速电机&#xff0c;不仅可以实现工艺改进&#xff0c;还能节省大量能源。本文介绍了电机编码器&#xff08;位置和速度&#xff09;、器件类型和技术以及应用案例。此外还解答了一些关键问题&#xff0c;例如对特定系统最重要的编码器性能…

Prometheus 的应用服务发现及黑河部署等

目录 promtool检查语法 部署Prometheus Server 检查语法是否规范 部署node-exporter 部署Consul 直接请求API进行服务注册 使用register命令注册服务&#xff08;建议使用&#xff09; 单个和多个注册&#xff0c;多个后面多加了s 在Prometheus上做consul的服务发现 部署…

ChatGPT漫谈(三)

AIGC(AI Generated Content)指的是使用人工智能技术生成的内容,包括文字、图像、视频等多种形式。通过机器学习、深度学习等技术,AI系统可以学习和模仿人类的创作风格和思维模式,自动生成大量高质量的内容。AIGC被视为继用户生成内容(UGC)和专业生成内容(PGC)之后的下…

【无标题】JSP--Java的服务器页面

jsp是什么&#xff1f; jsp的全称是Java server pages,翻译过来就是java的服务器页面。 jsp有什么作用&#xff1f; jsp的主要作用是代替Servlet程序回传html页面的数据&#xff0c;因为Servlet程序回传html页面数据是一件非常繁琐的事情&#xff0c;开发成本和维护成本都非常高…

StarRocks Friends 广州站精彩回顾

上周六&#xff0c;StarRocks & Friends 活动在羊城广州成功举行&#xff0c;社区的小伙伴齐聚一堂&#xff0c;共同探讨了 StarRocks 在业界的应用实践和湖仓一体等热门话题。 本文总结了技术交流活动的关键内容和视频资料&#xff0c;感谢社区每一位小伙伴的支持和参与&…

《TCP IP网络编程》第十四章

第 14 章 多播与广播 14.1 多播 多播&#xff08;Multicast&#xff09;方式的数据传输是基于 UDP 完成的。因此 &#xff0c;与 UDP 服务器端/客户端的实现方式非常接近。区别在于&#xff0c;UDP 数据传输以单一目标进行&#xff0c;而多播数据同时传递到加入&#xff08;注…