基本介绍

什么是红外线?

人的眼睛能看到的可见光按波长从长到短排列,依次为红、橙、黄、绿、青、蓝、紫。其中红光的波长范围为0.62~0.76μm;紫光的波长范围为0.38~0.46μm。比紫光波长还短的光叫紫外线,比红光波长还长的光叫红外线.红外线遥控就是利用波长为0.76~1.5μm之间的近红外线来传送控制信号的。

红外线系统的组成

红外线系统一般由红外发射装置和红外接收设备两大部分组成。红外发射装置又可由键盘电路、红外编码芯片、电源和红外发射电路组成。红外接收设备可由红外接收电路、红外解码芯片、电源和应用电路组成。通常为了使信号更好的被发射端发送出去,经常会将二进制数据信号调制成为脉冲信号,通过红外发射管发射。常用的有通过脉冲宽度来实现信号调制的脉宽调制(PWM)和通过脉冲串之间的时间间隔来实现信号调制的脉时调制(PPM)两种方法。

发射管和接收管

发送
是一只特殊的发光二极管;由于其内部材料不同于普通发光二极管,因而在其两端施加一定电压时,它便发出的是红外线而不是可见光。目前大量的使用的红外发光二极管发出的红外线波长为940nm左右,外形与普通φ5发光二极管相同。

 接收
红外遥控接收器的主要作用是将遥控发射器发来的红外光信好转换成电信号,再放大、限幅、检波、整形,形成遥控指令脉冲,输出至遥控微处理器。

接收原理图:

红外遥控发射(载波频率)

通常红外遥控为了提高抗干扰性能和降低电源消耗,红外遥控器常用载波的方式传送二进制编码,常用的载波频率为38kHz,这是由发射端所使用的455kHz晶振来决定的。

红外遥控键值

遥控器上不同的按键有着不一样的键值,按下相对应的键,红外二极管就会发送对应的信号,接收装置接收到信号后会对信号进行信号解调后会得到相应按键的键值,再根据不同的键值执行相应的操作。

NEC协议

发送

就像串口通信一样,红外通信也有其自己的通信协议,我们一般遵循NEC协议。
NEC规定红外二极管每次发送的信号的数据格式如下:

发送的数据主要由引导码、用户码1、用户码2、数据码、数据反码组成。引导码相当于暗号,当接收装置接收到正确的引导码后就开始读取数据,俩组用户码是为了区别其他的红外发射器发射的信号,数据码中的内容就对应着相应的键值,数据反码是为了在接收信号后检验信号的正确性。(引导码是“9ms高电平+4.5ms低电平”)

这样我们虽然清楚了信号的发送形式,但是怎么表达数据发送中的高低位(“0"和"1”)呢?这又涉及到NEC的位定义了,规定:“0.56ms高电平+0.565ms低电平”代表“1”;“0.56ms高电平+1.69ms低电平”代表“0”,就是说“0”与“1”的不同就是他们低电平所持续的时间不同。(PS:发送数据时从最低位开始发送)。

接收:

  NEC协议中定义的高电平为发送端发送38K载波信号,接收端接收到载波信号输出低电平;定义的低电平为发送端发送38K载波信号,接收端无信号输入,输出高电平。接收端和发送端正好相反。以下以接收端为准进行讨论。

所以单片机接收到的数据格式与发送时的恰恰相反,就是说接收时的引导码是“9ms低电平+4.5ms高电平”;“0”是“0.56ms低电平+0.565ms高电平”;“1”是“0.56ms低电平+1.69ms高电平”。这一点我们要格外注意,因为后续我们在解码程序中是以接收到的数据为准的!!!

这里是接收头完成一次完整数据接收的时序说明。

我们来看一下各个键按下之后的情况吧!拿第一个键举例子,首先启动码,然后地址码00000000,反码11111111;命令码10100010(0x45,第一个键的键码),反码01011101 。

程序分析

这是解码代码的基本思路,当空闲时,状态为0,之后准备接收信号状态为1,接收数据或者重复;如果是接收数据的开始型号,我们就置状态为2,如果是重复信号的话,继续回到状态0。

由于我们数据的接收以第一个下降沿开始,所以这里采用外部中断的方式,来进行数据的待机,且不用进行太多寄存器的配置工作。使用定时器0来进行电平的持续时间采集。

状态0:(空闲状态)

 if(IR_State==0)               //状态0,空闲状态{Timer0_SetCounter(0); //定时计数器清0Timer0_Run(1);         //定时器启动IR_State=1;             //置状态为1}

状态1:(等待状态,用于等待引导码,利用外部中断和定时器,得出两次下降沿的间隔时间,判断是Start,或者Repeat)。

 else if(IR_State==1)      //状态1,等待Start信号或Repeat信号{IR_Time=Timer0_GetCounter();   //获取上一次中断到此次中断的时间Timer0_SetCounter(0);  //定时计数器清0//如果计时为13.5ms,则接收到了Start信号(判定值在12MHz晶振下为13500,在11.0592MHz晶振下为12442)if(IR_Time>12442-500 && IR_Time<12442+500){IR_State=2;          //置状态为2}//如果计时为11.25ms,则接收到了Repeat信号(判定值在12MHz晶振下为11250,在11.0592MHz晶振下为10368)else if(IR_Time>10368-500 && IR_Time<10368+500){IR_RepeatFlag=1;   //置收到连发帧标志位为1Timer0_Run(0);     //定时器停止IR_State=0;         //置状态为0}else                    //接收出错{IR_State=1;         //置状态为1}}

状态2:(数据接收状态,也是利用外部中断和定时器,判断每一位数据接收到的是0还是1,当接受完32位时,结束状态)

 else if(IR_State==2)      //状态2,接收数据{IR_Time=Timer0_GetCounter(); //获取上一次中断到此次中断的时间Timer0_SetCounter(0);  //定时计数器清0//如果计时为1120us,则接收到了数据0(判定值在12MHz晶振下为1120,在11.0592MHz晶振下为1032)if(IR_Time>1032-500 && IR_Time<1032+500){IR_Data[IR_pData/8]&=~(0x01<<(IR_pData%8));    //数据对应位清0IR_pData++;          //数据位置指针自增}//如果计时为2250us,则接收到了数据1(判定值在12MHz晶振下为2250,在11.0592MHz晶振下为2074)else if(IR_Time>2074-500 && IR_Time<2074+500){IR_Data[IR_pData/8]|=(0x01<<(IR_pData%8));  //数据对应位置1IR_pData++;          //数据位置指针自增}else                 //接收出错{IR_pData=0;         //数据位置指针清0IR_State=1;          //置状态为1}if(IR_pData>=32)        //如果接收到了32位数据{IR_pData=0;          //数据位置指针清0if((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}}

完整例程如下:

main.c

#include <REGX52.H>
#include "Delay.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();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)       //如果遥控器VOL-按键按下{Num--;                      //Num自减}if(Command==IR_VOL_ADD)           //如果遥控器VOL+按键按下{Num++;                       //Num自增}LCD_ShowNum(2,12,Num,3);        //显示Num}}
}

Delay.c


void Delay(unsigned int xms)
{unsigned char i, j;while(xms--){i = 2;j = 239;do{while (--j);} while (--i);}
}

Deay.h

#ifndef __DELAY_H__
#define __DELAY_H__void Delay(unsigned int xms);#endif

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

Init0.c

#include <REGX52.H>/*** @brief  外部中断0初始化* @param  无* @retval 无*/
void Int0_Init(void)
{IT0=1;IE0=0;EX0=1;EA=1;PX0=1;
}/*外部中断0中断函数模板
void Int0_Routine(void) interrupt 0
{}
*/

Init0.h

#ifndef __INT0_H__
#define __INT0_H__void Int0_Init(void);#endif

Timer.c

#include <REGX52.H>/*** @brief  定时器0初始化* @param  无* @retval 无*/
void Timer0_Init(void)
{TMOD &= 0xF0;     //设置定时器模式TMOD |= 0x01;     //设置定时器模式TL0 = 0;      //设置定时初值TH0 = 0;       //设置定时初值TF0 = 0;       //清除TF0标志TR0 = 0;      //定时器0不计时
}/*** @brief  定时器0设置计数器值* @param  Value,要设置的计数器值,范围:0~65535* @retval 无*/
void Timer0_SetCounter(unsigned int Value)
{TH0=Value/256;TL0=Value%256;
}/*** @brief  定时器0获取计数器值* @param  无* @retval 计数器值,范围:0~65535*/
unsigned int Timer0_GetCounter(void)
{return (TH0<<8)|TL0;
}/*** @brief  定时器0启动停止控制* @param  Flag 启动停止标志,1为启动,0为停止* @retval 无*/
void Timer0_Run(unsigned char Flag)
{TR0=Flag;
}

Timer.h

#ifndef __TIMER0_H__
#define __TIMER0_H__void Timer0_Init(void);
void Timer0_SetCounter(unsigned int Value);
unsigned int Timer0_GetCounter(void);
void Timer0_Run(unsigned char Flag);#endif

IR.c

#include <REGX52.H>
#include "Timer0.h"
#include "Int0.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;/*** @brief  红外遥控初始化* @param  无* @retval 无*/
void IR_Init(void)
{Timer0_Init();Int0_Init();
}/*** @brief  红外遥控获取收到数据帧标志位* @param  无* @retval 是否收到数据帧,1为收到,0为未收到*/
unsigned char IR_GetDataFlag(void)
{if(IR_DataFlag){IR_DataFlag=0;return 1;}return 0;
}/*** @brief  红外遥控获取收到连发帧标志位* @param  无* @retval 是否收到连发帧,1为收到,0为未收到*/
unsigned char IR_GetRepeatFlag(void)
{if(IR_RepeatFlag){IR_RepeatFlag=0;return 1;}return 0;
}/*** @brief  红外遥控获取收到的地址数据* @param  无* @retval 收到的地址数据*/
unsigned char IR_GetAddress(void)
{return IR_Address;
}/*** @brief  红外遥控获取收到的命令数据* @param  无* @retval 收到的命令数据*/
unsigned char IR_GetCommand(void)
{return IR_Command;
}//外部中断0中断函数,下降沿触发执行
void Int0_Routine(void) interrupt 0
{if(IR_State==0)              //状态0,空闲状态{Timer0_SetCounter(0); //定时计数器清0Timer0_Run(1);         //定时器启动IR_State=1;             //置状态为1}else if(IR_State==1)      //状态1,等待Start信号或Repeat信号{IR_Time=Timer0_GetCounter();   //获取上一次中断到此次中断的时间Timer0_SetCounter(0);  //定时计数器清0//如果计时为13.5ms,则接收到了Start信号(判定值在12MHz晶振下为13500,在11.0592MHz晶振下为12442)if(IR_Time>12442-500 && IR_Time<12442+500){IR_State=2;          //置状态为2}//如果计时为11.25ms,则接收到了Repeat信号(判定值在12MHz晶振下为11250,在11.0592MHz晶振下为10368)else if(IR_Time>10368-500 && IR_Time<10368+500){IR_RepeatFlag=1;   //置收到连发帧标志位为1Timer0_Run(0);     //定时器停止IR_State=0;         //置状态为0}else                    //接收出错{IR_State=1;         //置状态为1}}else if(IR_State==2)     //状态2,接收数据{IR_Time=Timer0_GetCounter(); //获取上一次中断到此次中断的时间Timer0_SetCounter(0);  //定时计数器清0//如果计时为1120us,则接收到了数据0(判定值在12MHz晶振下为1120,在11.0592MHz晶振下为1032)if(IR_Time>1032-500 && IR_Time<1032+500){IR_Data[IR_pData/8]&=~(0x01<<(IR_pData%8));    //数据对应位清0IR_pData++;          //数据位置指针自增}//如果计时为2250us,则接收到了数据1(判定值在12MHz晶振下为2250,在11.0592MHz晶振下为2074)else if(IR_Time>2074-500 && IR_Time<2074+500){IR_Data[IR_pData/8]|=(0x01<<(IR_pData%8));  //数据对应位置1IR_pData++;          //数据位置指针自增}else                 //接收出错{IR_pData=0;         //数据位置指针清0IR_State=1;          //置状态为1}if(IR_pData>=32)        //如果接收到了32位数据{IR_pData=0;          //数据位置指针清0if((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}}
}

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            0x4Avoid IR_Init(void);
unsigned char IR_GetDataFlag(void);
unsigned char IR_GetRepeatFlag(void);
unsigned char IR_GetAddress(void);
unsigned char IR_GetCommand(void);#endif

51单片机 (十八)红外遥控相关推荐

  1. 51单片机tea5767收音机 红外遥控 自动搜台 存台 DIY

    转自:https://www.cnblogs.com/ningci/p/5464679.html 日向宁次 博客园 首页 新闻 新随笔 联系 管理 订阅 随笔- 55  文章- 0  评论- 1  5 ...

  2. 23、基于51单片机温控风扇红外遥控智能温度控制系统设计

    毕设帮助.开题指导.技术解答(有偿)见文末. 目录 摘要 一.硬件方案 二.设计功能 三.实物图 四.原理图 五.PCB图 六.Proteus仿真 七.程序源码 八.资料包括 摘要 本设计为一种温控风 ...

  3. 51单片机学习:红外遥控实验

    实验名称:红外遥控实验 接线说明:     实验现象:下载程序后,数码管上显示数码管上显示红外解码遥控器键值 注意事项:红外接收头凸起处要与PCB板接口凸起丝印处对应                  ...

  4. arduino学习笔记十八--红外遥控检测

    介绍 远程遥控技术又称为遥控技术,是指实现对被控目标的遥远控制,在工业控制.航空航天.家电领域应用广泛.红外遥控是一种无线.非接触控制技术,具有抗干扰能力强,信息传输可靠,功耗低,成本低,易实现等显著 ...

  5. 基于51单片机的智能红外遥控防雨晾衣架 雨滴光强检测系统proteus仿真原理图PCB

    功能: 0.本系统采用STC89C52作为单片机 1.LCD1602液晶实时显示当前雨滴/光强/温湿度/晾衣架状态 2.支持手动/自动两种模式 3.自动模式下,当雨滴<5/光强<80同时满 ...

  6. 1.基于51单片机的蓝牙手机遥控小车

    第一节  基于51单片机控制的蓝牙遥控小车 51控制的蓝牙遥控小车是楼主大一刚开始接触单片机时DIY的项目,时间大概是2016年的6月,现在已经是19年的5月底,借毕业前有闲时间写一下之前自己做过得种 ...

  7. 红外报警c语言,基于51单片机的人体红外报警器程序设计

    //51单片机简人体红外报警器设计,手动按键控制实现紧急报警.布防.撤防.关闭报警)// #include #define uchar unsigned char #define uint  unsi ...

  8. 基于51单片机的人体红外探测防盗报警

    资料编号:128  下面是相关功能视频演示: 128-基于51单片机的人体红外探测防盗报警(仿真+源码+全套资料) 功能说明: 1.按下紧急报警按键,紧急报警灯闪烁,蜂鸣器报警 2.按下布防按键,布防 ...

  9. 【正点原子STM32连载】 第三十八章 红外遥控实验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1

    1)实验平台:正点原子MiniPro H750开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=677017430560 3)全套实验源码+手册+视频 ...

  10. 基于51单片机的人体红外探测防盗报警(仿真+源码+全套资料)

     资料编号:128 功能说明: 1.按下紧急报警按键,紧急报警灯闪烁,蜂鸣器报警 2.按下布防按键,布防指示灯开始闪烁,闪烁大约30秒,保持亮的状态,进入布防模式 3.按下取消报警/布防按键,取消布防 ...

最新文章

  1. 【硅谷牛仔】Instagram CEO--凯文·希斯特罗姆--从销售到科技独角兽公司CEO
  2. 利用流水线改进代码中的if处理流程
  3. python读文件操作-python文件操作-读写删除复制总结
  4. 【从蛋壳到满天飞】JS 数据结构解析和算法实现-哈希表
  5. 复制、移动和删除:cp, rm, mv
  6. android 过滤cmcc,Android 无法通过cmcc wap2.0 test解决
  7. 【Android布局】在程序中设置android:gravity 和 android:layout_Gravity属性
  8. supersocke接收不到数据_基于SuperSocket的北斗终端数据接收服务的设计与实现
  9. 中fuse_保险丝座中保险丝的材质,结构,接线方式以及区别的介绍
  10. 创建ros的程序包--3
  11. .两个windowsform之间的值传递
  12. POJ 3111 K Best 贪心 二分
  13. 指针 多维数组 数组指针 指针数组
  14. 公司电脑加域之后用不了USB但是可以用鼠标键盘得解决方法
  15. 关于 Axure 动态面板
  16. 主板4线风扇原理分析
  17. Spark3.0新特性-AQE
  18. 将个人文件夹挂载到服务器上,通过 WebDAV 将服务器全部或某个文件夹挂载到电脑上当网络硬盘 | 很文博客...
  19. 第十二周练兵区——编程题——不计入总分
  20. Word文件如何查看字数

热门文章

  1. 云服务器导购:cpu、内存、硬盘、带宽都具体有什么用?
  2. php 模拟阿里妈妈登入,请问php通过curl如何模拟登陆阿里妈妈呢?
  3. 《毛毛虫组》第一次作业:团队亮相
  4. 看牛人如何20分钟被动加114个微信好友!
  5. Xamarin:使用C#移植Android操作系统
  6. 做车载测试3年,我的思考与总结
  7. c# 生成、识别二维码
  8. linux系统下配置阿里DDNS(IPv6)
  9. C#调用Lua 3、创建Lua解析器管理器
  10. php 的时间戳时区,[php]php时间戳当中关于时区的问题