zigbee 万能遥控器 裸机发送和协议栈发送
HX1010
http://www.sbprojects.com/knowledge/ir/index.php
遥控编码
http://www.sbprojects.com/knowledge/ir/rc5.php
http://www.sbprojects.com/knowledge/ir/nec.php
发送方:波形图上的高电平对应发相同时间长度的38KHZ方波;波形图上的低电平对应停止发送对应时间长度的方波(即保持低或高电平即可)
比如在发送方发送引导码时,先发送9ms的38KHZ防波,然后停止发送4.5ms。接着发送数据。
发送数据0时,先发送0.56ms的38KHZ方波,然后停止发送0.56ms.接着发送下一位。发送数据1时,先发送0.56ms的38KHZ方波,然后停止发送1.68ms.接着发送下一位。全部数据发送完成之后,就停止发送。
接收方:IRM3638,平时没接收到38KHZ方波时,输出高电平;接收到38KHZ方波时,持续输出低电平,直到方波消失。
比如在接收到波形图上的高电平时(即接收发送者发送的方波时),持续输出低电平,直到法波消失。
http://www.100y.com.tw/pdf_file/FM-6038LM-5A.pdf
http://www.docin.com/p-43857433.html
裸机发送:
#include <ioCC2530.h>
#define IROUT P1_1 //红外发射脚
#define RLED P1_0 //红外接收
#define uchar unsigned char
#define uint unsigned int/*****************************************
//定义全局变量
*****************************************///接收模式
unsigned int irtime;//红外用全局变量
unsigned char irok;//=1,表示一组连续的红外代码已经成功接收完毕
unsigned char irpro_ok;//=1,表示红外代码已经解析完毕
unsigned char IRCode[4]; //处理后的红外码,分别是 客户码,客户码,数据码,数据码反码
unsigned short __xdata IRSourceData[160]; //33个高低电平的时间数据unsigned char __xdata IRSourceData2[14]=
{0x65,0x4b,0x00,0x00,0x02,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0xa0,0xba
};//haier kogntiao kaiji 29static char ifg=0;//每次按下遥控器时,会触发多次红外中断,只需在第一次红外中断时开启定时器,ifg=0表示初次红外中断//发射模式
uint counter = 0;
uchar LEDFlag = 0;
uchar ucIs38KHZ=0;
uint uiCurrentCount=0;
uint uiTotalCount=0;void Delay(uint n)
{uint i;for(i = 0;i<n;i++);for(i = 0;i<n;i++);for(i = 0;i<n;i++);for(i = 0;i<n;i++);for(i = 0;i<n;i++);
}extern void SendIRdata2(char cData);
//接收模式的函数
void Ircordpro(void)//红外码值处理函数
{ unsigned char i, j, k;unsigned int cord,value;k=1;for(i=0;i<4;i++) //处理4个字节{for(j=1;j<=8;j++) //处理1个字节8位{cord=IRSourceData[k];if(cord>67*2)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差value=value|0x80;else value=value;if(j<8)value=value>>1;k++;}IRCode[i]=value;value=0; } irpro_ok=1;}//红外接收中断处理
#pragma vector = P1INT_VECTOR__interrupt void P1_ISR(void){if(P1IFG & 0x01) //红外中断{//需要在前面清理中断标志P1IFG &= 0; P1IF=0;static unsigned int iIndex=0; //每次按下遥控器时,会触发多次红外中断,只需在第一次红外中断时开启定时器,ifg=0表示初次红外中断if(ifg==0){T4CTL |= 0x10; //启动定时器T4ifg=1;irtime=0;iIndex=0;//重新开始for(int i=0;i<160;i++)//初始化数组为0IRSourceData[i]=0;return ;//第一个下降沿测得的irtime不要,因为=0}//if(irtime<605*2&&irtime>=317*2)//引导码 TC9012的头码,9ms+4.5ms// i=0;IRSourceData[iIndex]=irtime;irtime=0;iIndex++; } if(P1IFG & 0x04) //按键中断{Delay(5);if(P1IFG & 0x04) { //需要在前面清理中断标志P1IFG &= 0; //清中断标志P1IF=0;Delay(5);SendIRdata2(68);P1_4=0;//表示发送完毕,进行下一个接收}}}//接收定时器,产生38KHZ方波
#pragma vector = T4_VECTOR
__interrupt void T4_ISR(void)
{if(TIMIF &= 0x18) //Timer4溢出? {irtime++;//判断对方的一组连续的代码是否发送完毕//如果长时间(>6000)未接收到相邻的一个下降沿,判定此组红外代码完毕//此时就停掉定时器,并且//置ifg标志为0,为下一组代码做初始化的准备//置irok标志为1,表示此组红外代码已经接收完毕,后续处理使用此标志if(irtime>6000){T4CTL &= ~0x10; // 停止定时器T4ifg=0;irok=1;}//需要在最后清理中断标志TIMIF &= ~0x18; //清除Timer4溢出中断标记IRCON &= ~0x10; //清除Timer4中断标记}}//初始化红外接收
//p1.0是红外接收脚,需配置为中断,下降沿触发。核心板的第14脚。也是LED1.
void InitReceiveIR(void)
{EA=0;P1INP |= 0x01; //上拉 P1IEN |= 0X01; //P10设置为中断方式PICTL |= 0X02; //下降沿触发IEN2 |= 0x10; // P1 使能中断;P1IFG |= 0x00; //初始化中断标志位//EA = 1;
}//初始化定时器4
void InitT4(void)
{EA=0;T4CTL = 0x07; //不分頻,Up-Down Mode(0x00->T1CC0->0x00)T4CC0 = 0x30; //设定初值TIMIF &= ~0x18; //清除Timer4溢出中断标记 T4CTL |= 0x08; //设定Timer4溢出中断使能IRCON &= ~0x10; //清除Timer4中断标记IEN1 |= 0x10; //设定Timer中断使能//EA = 1;
}//接收模式的函数//发送模式的函数void StartAndSendIRData(uint TotalCoun,uchar Is38KHZ)
{
#if 1ucIs38KHZ=Is38KHZ;uiCurrentCount=0;do{}while(uiCurrentCount<TotalCoun);ucIs38KHZ=0;//发送完成之后停止发射载波
#endif
}void SendIRdata(char cData)
{if(IRSourceData[0]==0)return;//开启定时器T4T4CTL |= 0x10; int i,j;unsigned short irdata=0;//发送引导码irdata=IRSourceData[0];//先发送0.56ms的38KHZ红外波(即编码中0.56ms的高电平)StartAndSendIRData(irdata/2,1);//停止发送红外信号(即编码中的低电平)StartAndSendIRData(irdata/2,0); //1为宽的低电平//StartAndSendIRData(irdata,0);//0为窄的低电平irdata=IRSourceData[1];//先发送0.56ms的38KHZ红外波(即编码中0.56ms的高电平)StartAndSendIRData(irdata/2,1);//停止发送红外信号(即编码中的低电平)StartAndSendIRData(irdata/2,0); //1为宽的低电平//StartAndSendIRData(irdata,0);//0为窄的低电平//发送数据码j=2;while(IRSourceData[j]!=0){irdata=IRSourceData[j];if(irdata>120){StartAndSendIRData(irdata/2,1); StartAndSendIRData(irdata/2,0); }else {StartAndSendIRData(irdata/4,1); StartAndSendIRData(irdata*3/4,0);}j++;}// 再发送一位,以便使得接收端产生一个中断,确定上一位的持续时间irdata=0x1;for(i=0;i<1;i++){//先发送0.56ms的38KHZ红外波(即编码中0.56ms的高电平)StartAndSendIRData(22,1);//停止发送红外信号(即编码中的高电平)if(irdata & 1)StartAndSendIRData(65,0); //1为宽的低电平elseStartAndSendIRData(22,0);//0为窄的低电平irdata=irdata>>1;}//发送完毕时关闭定时器T4T4CTL &= ~0x10;
}void SendIRdata2(char cData)
{int i;unsigned char irdata;T3CTL |= 0x10; #if 0//发送9ms的38KHZ起始码StartAndSendIRData(346,1);//停止发送4.5ms,属于起始码StartAndSendIRData(173,0);
#endif //发送9ms的38KHZ起始码StartAndSendIRData(346*48/100,1);//停止发送4.5ms,属于起始码StartAndSendIRData(173*48/100,0);//发送9ms的38KHZ起始码StartAndSendIRData(346*60/98,1);//停止发送4.5ms,属于起始码StartAndSendIRData(173*60/98,0);for(int j=0;j<14;j++){irdata=IRSourceData2[j];for(i=0;i<8;i++){//先发送0.56ms的38KHZ红外波(即编码中0.56ms的高电平)StartAndSendIRData(22,1);//停止发送红外信号(即编码中的低电平)if(irdata & 1)StartAndSendIRData(65,0); //1为宽的低电平elseStartAndSendIRData(22,0);//0为窄的低电平irdata=irdata>>1;}}// 再发送一位,以便使得接收端产生一个中断,确定上一位的持续时间irdata=0x1;for(i=0;i<1;i++){//先发送0.56ms的38KHZ红外波(即编码中0.56ms的高电平)StartAndSendIRData(22,1);//停止发送红外信号(即编码中的高电平)if(irdata & 1)StartAndSendIRData(65,0); //1为宽的低电平elseStartAndSendIRData(22,0);//0为窄的低电平irdata=irdata>>1;}T3CTL &= ~0x10;}//发送定时器,产生38KHZ方波
#pragma vector = T3_VECTOR
__interrupt void T3_ISR(void)
{if(TIMIF &= 0x01) //Timer4溢出? {uiCurrentCount++;if(ucIs38KHZ==1)IROUT = !IROUT;//载波发射elseIROUT =0;//不发射,保持0或者1均可//需要在最后清理中断标志TIMIF &= ~0x01; //清除Timer4溢出中断标记,cpu自动也会清除}IRCON &= ~0x08; //清除Timer4中断标记,,cpu自动也会清除}//初始化红外发送
//p1.1是红外发送脚,需配置为输出。核心板的第13脚。也是LED2.
void InitSendIR(void)
{P1SEL &= ~0x02; //设定P1_1为通用I/OP1DIR |= 0x02; IROUT = 1;
}//初始化定时器3,用于产生发送方波,38KhZ
void InitT3(void)
{EA=0;T3CTL = 0x07; //不分頻,Up-Down Mode(0x00->T1CC0->0x00)T3CC0 = 0x30; //设定初值TIMIF &= ~0x01; //清除Timer4溢出中断标记 T3CTL |= 0x08; //设定Timer4溢出中断使能IRCON &= ~0x08; //清除Timer4中断标记IEN1 |= 0x08; //设定Timer中断使能//EA = 1;
}//发送模式的函数//设置发送键P1_2即中断
void InitKey(void)
{//P1SEL &= ~0x04; //设定P1_2为通用I/O//P1DIR &= ~0x04; //P1INP &= ~0x04;EA=0;P1INP |= 0x04; //上拉 P1IEN |= 0X04; //P12设置为中断方式PICTL |= 0X02; //下降沿触发IEN2 |= 0x10; // P1 使能中断;P1IFG |= 0x04; //初始化中断标志位
}//设置学习成功指示灯P1_4即S2为通用,输出
void InitLED(void)
{P1SEL &= ~0x10; //设定P1_4为通用I/OP1DIR |= 0x10; P1INP &= ~0x10;P1_4=0;}main()
{ InitLED();InitT4();InitReceiveIR(); InitKey();InitT3();InitSendIR();EA = 1;while(1)//主循环{
#if 1if(irok) //如果接收好了进行红外处理{//Ircordpro();irok=0;P1_4=1;//表示接受完毕。可以发送}if(irpro_ok) //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等{// Ir_work();}#endif }}
协议栈 接收
2013-5-29 18:01:45
使用两个外部中断,上升沿和下降沿触发,可以识别所有红外协议
/**
bysong 2013-3-11 8:19:28
process receiving the ir signal
*/#include "OSAL.h"
#include "ZGlobals.h"
#include "AF.h"
#include "aps_groups.h"
#include "ZDApp.h"
#include "OnBoard.h"/* HAL */
#include "hal_lcd.h"
#include "hal_led.h"
#include "hal_key.h"
#include "sapi.h"
#include "smt_ir_rec.h"//#include "zcl_general.h"//中断数目
#define MAX_IRDATA_NUM 230
#define MAX_IRHEAD_NUM 10
#define MAX_IRTAIL_NUM 10#define MAX_IR_BYTE_NUM ((MAX_IRHEAD_NUM+MAX_IRTAIL_NUM+MAX_IRDATA_NUM)*2)static uint16 *m_pu16IRSourceData=NULL; //MAX_DATALEN个高低电平的时间数据//static uint16 __xdata m_pu16IRSourceData3[MAX_IRDATA_NUM]; //MAX_DATALEN个高低电平的时间数据
//static uint16 __xdata m_szu16IRSourceDataR[MAX_DATALEN]; //MAX_DATALEN个高低电平的时间数据
static uint16 m_u16SourceDataTotalNum;//实际接收到的有效位个数,包括data,head和tail
static uint32 m_u32IRtime;//红外用全局变量
static bool m_bIRok=0;//红外位数据已经接收到
static uint8 m_u8Ifg=0;//每次按下遥控器时,会触发多次红外中断,只需在第一次红外中断时开启定时器,m_u8Ifg=0表示本次中断是初次红外中断//初始化红外接收
//由于p1.0-led1-irin已经作为led显示使用,协议栈中很多地方都使用led1作为指示使用,所以选用了p1.3-botton2,
//此时需要隔断红外芯片的1脚,直接连到p1.3,即p16的37脚,
//由于红外1脚在有载波信号时输出0,所以p1.3最好要上拉,
void smt_ir_rec_InitReceiveIR(void)
{if ( m_pu16IRSourceData== NULL)m_pu16IRSourceData=(uint16 *)osal_mem_alloc(MAX_IR_BYTE_NUM);if ( m_pu16IRSourceData== NULL)SystemReset();osal_memset(m_pu16IRSourceData,0,MAX_IR_BYTE_NUM);//return;EA=0;
#if 1// 使用p1.3,button2P1INP |= 1<<3; //上拉 P1IEN |= 1<<3; //P13中断使能PICTL |= (1<<1); //下降沿触发
#endif#if 1// 使用p1.7P1INP |= 1<<7; //上拉 P1IEN |= 1<<7; //P17中断使能PICTL &= ~(1<<2); //上升沿触发
#endifP1IFG |= 0x00; //初始化中断标志位IEN2 |= 1<<4; // P1 使能中断;EA = 1; }void smt_ir_rec_StopReceiveIR(void)
{// 使用p1.3,button2//P1INP |= 0x01; //上拉 if(m_pu16IRSourceData!=NULL){osal_mem_free(m_pu16IRSourceData);m_pu16IRSourceData=NULL;}//return;//P1IEN &= ~0x08; P1IEN &= ~(1<<3); P1IEN &= ~(1<<7); IEN2 &= ~(1<<4); // EA = 0;
}//红外接收中断处理
/*
#pragma vector = P1INT_VECTOR__interrupt void smt_ir_rec_P1_ISR(void)
#pragma vector = P1INT_VECTOR__interrupt void smt_ir_rec_P1_ISR(void)
*/
#if 1HAL_ISR_FUNCTION( smt_ir_rec_P1_ISR, P1INT_VECTOR ){static uint16 u16_Index=0;if(P1IFG & 0x08) //红外中断,p1.3,下降沿中断中记录的是上次高电平电平持续的时间{P1IFG = 0;P1IF=0;//if(P1IFG==0) //红外中断{ //每次按下遥控器时,会触发多次红外中断,只需在第一次红外中断时开启定时器,m_u8Ifg=0表示初次红外中断if(m_u8Ifg==0){smt_ir_rec_InitT4();//启动定时器T4。如果直接使用T4CTL |= 0x10去启动,有时候会启动失败m_u8Ifg=1;m_u32IRtime=0;u16_Index=0;//重新开始m_u16SourceDataTotalNum=0;osal_memset( m_pu16IRSourceData, 0, MAX_IR_BYTE_NUM );// osal_memset( m_szu16IRSourceDataR, 0, sizeof(m_szu16IRSourceDataR) );return ;//第一个下降沿测得的irtime不要,因为=0}if( m_u16SourceDataTotalNum < MAX_IR_BYTE_NUM/2){m_pu16IRSourceData[u16_Index++]=m_u32IRtime;//t4中断次数存储起来m_u16SourceDataTotalNum=u16_Index;m_u32IRtime=0;//清零,为下一次中断准备}} } #if 1if(P1IFG & 0x80) //红外中断,p1.7,上升沿中断中记录的是上次低电平持续的时间{P1IF = 0;P1IFG = 0;//if(P1IFG==0) //红外中断{ if( m_u16SourceDataTotalNum < MAX_IR_BYTE_NUM/2){m_pu16IRSourceData[u16_Index++]=m_u32IRtime;//t4中断次数存储起来m_u16SourceDataTotalNum=u16_Index;m_u32IRtime=0;//清零,为下一次中断准备}}}P1IF = 0;P1IFG = 0;/*if(P1IFG!=0){P1IF = 0;P1IFG = 0;}*/
#endif}#endif/*
定时器t4在hal_timer.c中已经定义了中断处理函数,所以先要在hal_timer.c中注释掉,如下HAL_ISR_FUNCTION( halTimer4Isr, T4_VECTOR )
{halProcessTimer4 ();
}否则中断发生时会进入hal_timer.c中的中断处理函数中执行
*//*#pragma vector = T4_VECTOR
__interrupt void smt_ir_rec_T4_ISR(void)#pragma vector = T4_VECTOR
__interrupt void smt_ir_rec_T4_ISR(void)
*/
#if 1
HAL_ISR_FUNCTION( smt_ir_rec_T4_ISR, T4_VECTOR )
{// if(TIMIF &= 0x18) //Timer4溢出? {m_u32IRtime++; //判断对方的一组连续的代码是否发送完毕 //如果长时间(>16000)未接收到相邻的一个下降沿,判定此组红外代码完毕 //此时就停掉定时器,并且 //置ifg标志为0,为下一组代码做初始化的准备 //置irok标志为1,表示此组红外代码已经接收完毕,后续处理使用此标志 if(m_u32IRtime>16000){T4CTL &= ~0x10; // 停止定时器T4m_u8Ifg=0;if(m_pu16IRSourceData[0]<6|| m_pu16IRSourceData[1]<6|| m_pu16IRSourceData[2]<6 || m_pu16IRSourceData[3]<6 || m_pu16IRSourceData[4]<6 || m_pu16IRSourceData[5]<6 || m_pu16IRSourceData[6]<6 || m_pu16IRSourceData[7]<6 )//在自己发射时,虽然禁止了接受,但也会检测到全是0的ir码,需排除此种情况m_bIRok=0;elsem_bIRok=1;}//TIMIF &= ~0x18; //清除Timer4溢出中断标记IRCON &= ~0x10; //清除Timer4中断标记}
}
#endif//初始化定时器4
void smt_ir_rec_InitT4(void)
{T4CTL = 0x07; //不分頻,Up-Down Mode(0x00->T1CC0->0x00)T4CC0 = 210; //设定初值TIMIF &= ~0x18; //清除Timer4溢出中断标记 T4CTL |= 0x08; //设定Timer4溢出中断使能IRCON &= ~0x10; //清除Timer4中断标记IEN1 |= 0x10; //设定Timer中断使能EA = 1;T4CTL |= 0x10; //启动定时器T4
}//m_u16SourceDataTotalNum是中断个数,每个占用2个字节
//为了节约资源,传输时,前面10个中断数每个占2个字节,后面10个每个中断数每个占2个字节,中间每个占1个字节
uint16 smt_ir_rec_GetIRSourceData(uint8 * pu8IRSourceData)
{//return 20;if(m_bIRok==1){m_bIRok=0;uint16 byteNum =0;byteNum= Uint162Ir(m_pu16IRSourceData,m_u16SourceDataTotalNum<<1,pu8IRSourceData);osal_memset( m_pu16IRSourceData, 0, MAX_IR_BYTE_NUM );// byteNum=200;return byteNum;}elsereturn 0;
}/*** 返回转化为1字节的数目的字节总数目
*/
uint16 Uint162Ir(uint16 *pSrc,uint16 srcByteCnt,uint8 *pDst)
{uint16 ret=0;if(srcByteCnt<=0)return 0;if(srcByteCnt>(MAX_IRHEAD_NUM+MAX_IRHEAD_NUM+MAX_IRDATA_NUM)*2 )return 0;if(srcByteCnt <= (MAX_IRHEAD_NUM+MAX_IRHEAD_NUM)*2){osal_memcpy(pDst,pSrc,srcByteCnt);ret=srcByteCnt;}else if(srcByteCnt > (MAX_IRHEAD_NUM+MAX_IRHEAD_NUM)*2){uint16 dataByteCnt=( srcByteCnt- ((MAX_IRHEAD_NUM+MAX_IRHEAD_NUM) *2 ) );osal_memcpy(pDst,pSrc,MAX_IRHEAD_NUM*2);osal_memcpy(&pDst[MAX_IRHEAD_NUM*2+dataByteCnt/2],&pSrc[MAX_IRHEAD_NUM+dataByteCnt/2],MAX_IRTAIL_NUM*2);
//process data
//2字节数据--》1字节数据for(uint16 i=0;i<dataByteCnt/2;i++){//pDst是单字节类型//pSrc是双字节类型pDst[MAX_IRHEAD_NUM*2+i]=pSrc[MAX_IRHEAD_NUM+i];}ret=(dataByteCnt>>1) + ((MAX_IRHEAD_NUM+MAX_IRHEAD_NUM)<<1);}return ret;
}/*** 返回转化为2字节的数目的字节总数目*/
uint16 Ir2Uint16(uint8 *pSrc,uint16 srcByteCnt,uint16 *pDst)
{uint16 ret=0;if(srcByteCnt <= (MAX_IRHEAD_NUM+MAX_IRHEAD_NUM)*2){osal_memcpy(pDst,pSrc,srcByteCnt);ret=srcByteCnt;}else if(srcByteCnt > (MAX_IRHEAD_NUM+MAX_IRHEAD_NUM)*2){uint16 dataNum=srcByteCnt-(MAX_IRHEAD_NUM+MAX_IRHEAD_NUM)*2;//cout<<"srcByteCnt "<<srcByteCnt<<endl;//cout<<"dataNum "<<dataNum<<endl;osal_memcpy(pDst,pSrc,MAX_IRHEAD_NUM*2);osal_memcpy(&pDst[MAX_IRHEAD_NUM+dataNum],&pSrc[MAX_IRHEAD_NUM*2+dataNum],MAX_IRTAIL_NUM*2);
//process data
//1字节数据--》2字节数据for(uint16 i=0;i<dataNum;i++){//pSrc 是单字节类型//pDst是双字节类型pDst[MAX_IRHEAD_NUM+i]=pSrc[MAX_IRHEAD_NUM*2+i];}ret=(dataNum+MAX_IRHEAD_NUM+MAX_IRHEAD_NUM)*2;}return ret;
}
/*
本文件内函数调用顺序smt_ir_rec_InitReceiveIR();
即直接在外部函数中调用此函数就可以接收红外信号了
定时器在接收到红外中断信号的时候启动smt_ir_rec_GetIRCmd();
*/
转载于:https://www.cnblogs.com/-song/archive/2013/02/06/3331829.html
zigbee 万能遥控器 裸机发送和协议栈发送相关推荐
- java串口发送16进制_串口发送数据——字符串发送与十六进制发送的区别
在计算机中,数据是以二进制的形式存储的,例如十进制 1(10)在计算机中用 0000 0001(2)来表示.我们在用串口发送数据的时候首先将待数据转换为对应的ASCII码,然后再将这些ASCII码按照 ...
- python中带附件发送电子邮件_python发送带附件邮件
Python SMTP发送邮件 SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式. py ...
- 串口发送通信---UART发送---STM32F4实现
串口发送程序配置过程(HAL库) 初始化串口相关参数,使能串口 HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart) 该函数的参数是串口 ...
- Spring Boot整合websocket实现群聊,点对点聊天,图片发送,音频发送
参考:基于https://blog.csdn.net/qq_38455201/article/details/80374712 基础上进行添加图片发送和音频发送功能 单点图片发送: 单点音频发送: ...
- 【计算机网络】数据链路层 : 后退 N 帧协议 GBN ( 滑动窗口 | 发送窗口长度 | “发送方“ 累计确认、超时机制 | “接收方“ 按序接收、确认帧发送机制 | 计算示例 )★
文章目录 一. 滑动窗口协议引入 二. 后退 N 帧协议 ( GBN ) 滑动窗口 三. 后退 N 帧协议 ( GBN ) 运行过程 四. 后退 N 帧协议 ( GBN ) 发送方数据分类 五. 后退 ...
- 环信服务器发送消息ext,发送消息
发送消息 聊天相关 API,可以发送文本消息,发送图片消息,发送语音消息,发送视频消息,发送透传消息和发送扩展消息. 发送文件类型消息要先把文件上传到环信服务器,参考文档:文件上传下载 REST接口发 ...
- php发送电子邮件,PHP发送电子邮件
本文使用 PHPMailer 进行邮件发信. PHPMailer 的开源地址:https://github.com/PHPMailer/PHPMailer/ 下载 PHPMailer 后解压.本文是解 ...
- 消息的同步发送,异步发送以及消息发送的可靠性
最近写的一个通信框架中有两种最基本的消息发送方式:同步发送和异步发送. 同步方式: 消息的发送方发A送一条消息到接收端B,B收到消息之后需要对消息进行处理,然后发送ACK确认消息回A,A收到B的ACK ...
- php redis 短信频率,发送短信: 使用Redis限制每天的发送频率和发送时间
ratelimiting.lua --[[实现访问频率的脚本.参数:KEY[1] 用来标识同一个用户的idARGV[1] 过期时间ARGV[2] 过期时间内可以访问的次数返回值: 如果没有超过指定的频 ...
最新文章
- Linux在任务栏上找不到最小化窗口的解决方法
- kubernetes (k8s)的二进制部署单节点(etcd和flannel网络)
- lisp正负调换_坐标提取lisp程序
- 数据库表设计索引外键设计_关于索引的设计决策 数据库管理系统
- linux操作系统 抢占式,Linux操作系统内核抢占补丁的基本原理(2)
- app做好后如何上线_传统企业如何做好线上线下全网营销?不知道的建议看完这篇干货...
- mysql swarm_【Docker】 Swarm简单介绍
- tamtam-nuget-imageserver
- Tomcat乱码解决方法
- 计算机硬件工程师主要干什么,计算机硬件工程师主要学习什么内容
- 寄存器、锁存器和触发器的区别与联系
- MYQQ复活版 20220801
- 链接计算机 输入网络密码,联想电脑怎么连接无线网输入密码时怎么输入
- 当下的力量实践手册读书笔记(1.29)
- 使用MobaXterm tunneling访问集群(服务器)jupyter notebook
- 【商业源码】生日大放送-Newlife商业源码分享
- STM32F207ZG GPIO口学习
- Abaqus安装CAE报错Regview解决方法
- 窗口透明化 AlphaBlend
- hdu 2222 AC 自动机 模版(数组实现)