国内最好用免费建站系统网站制作生成器

当前位置: 首页 > news >正文

国内最好用免费建站系统,网站制作生成器,wordpress收不到邮箱验证,WordPress文字按钮变色文章目录 红外遥控的介绍硬件电路NEC编码外部中断红外遥控实例代码 红外遥控的介绍 红外遥控是一种无线、非接触控制技术#xff0c;通过使用红外线来传送控制信号。它具有抗干扰能力强、信息传输可靠、功耗低、成本低、易实现等显著优点#xff0c;因此被广泛应用于各种电子… 文章目录 红外遥控的介绍硬件电路NEC编码外部中断红外遥控实例代码 红外遥控的介绍 红外遥控是一种无线、非接触控制技术通过使用红外线来传送控制信号。它具有抗干扰能力强、信息传输可靠、功耗低、成本低、易实现等显著优点因此被广泛应用于各种电子设备和家用电器也越来越多地应用于计算机和手机系统中。
硬件电路 红外遥控系统一般由发射和接收两个部分组成。发射部分包括红外发光二极管它是一种特殊的发光二极管能够发射调制后的红外光波。接收部分通常采用红外接收模块用于接收来自遥控器发射的红外信号。当遥控器处于学习状态时接收模块会接收外来红外信号并将其转换成电信号。经过检波、整形和放大等处理后这些电信号会被传送到中央处理单元CPU进行解码和执行相应的控制动作。 发射端 IN是输入信号端口输入的信号会通过38kHz的频率在三极管中放大到发光二极管中二极管发出闪烁着的特制红外光线 在现实生活中有很多种类型的红外线为了让接收方只接收这一类型的红外线就在电路中加入了频率让这个信号能有一定频率的闪烁 当我们没有输入时默认为高电平而当我们输入信号时就会在低电平发出有频率波动的信号
接收端 这里将接收的发光二极管内置在了电路中电路也很容易电源、接地、以及信号输出 在这里我们会让OUT端口接上外部中断当产生下降沿就进入中断
NEC编码 NEC编码是一种红外遥控协议常用于遥控器与设备之间的通信。它是一种常用的编码格式将遥控发送过来的信号进行一定形式的编码转换为对应的信息 NEC编码的数据格式通常由以下几部分组成 引导码Leader Code持续低电平通常为9ms和持续高电平通常为4.5ms用于标识开始传输数据。 系统码Customer Code8位二进制代码用于识别具体的设备或品牌。 数据码Data Code8位二进制代码表示具体的指令或按键信息。在传输数据时一般持续低电平560us和持续高电平560us表示传输‘0’持续低电平560us和持续高电平1690us表示传输‘1’ 取反码Inverted Data Code与数据码和系统码相反的二进制代码用于检验数据的正确性。 结束码Stop Bit持续高电平通常为0.56ms表示数据传输结束。在这里我们没有引用到 重复码Repeat Code数据传输之后若持续低电平9ms和持续高电平2.25ms那么将会重复这个命令信息 NEC编码使用38kHz的载波频率进行传输通过在红外光线的调制和解调实现遥控功能。在发射时数据按照引导码、系统码、数据码和取反码的顺序发送在接收端通过解码器将红外信号还原为对应的系统码和数据码从而实现遥控器与设备的交互。 外部中断 51单片机的外部中断是指通过外部信号触发单片机进行中断处理的一种机制。单片机通过外部引脚接收到特定的信号后会立即暂停当前的任务转而执行与该中断相关的程序。 在51单片机中有两个外部中断源分别为外部中断0INT0和外部中断1INT1。这两个中断源分别对应单片机的引脚P3.2和P3.3。
外部中断可以通过两种触发方式来进行中断处理电平触发和边沿触发。电平触发是指当外部信号维持在某个电平上时触发中断可以是低电平触发或高电平触发边沿触发是指当外部信号的跳变沿上升沿或下降沿出现时触发中断。 中断号
此次操作相关寄存器以及原理
使用外部中断前需要进行相应的初始化操作。 初始化 void Interrupt0_Init() {IT01;//外部中断0选择边沿触发IE01;//外部中断0请求标志EX01;//外部中断0请求允许位EA1;//总中断允许PX01;//中断优先级控制 }红外遥控实例代码 接下来我们要实现的是在屏幕上显示地址命令码数字增减通过遥控的控制让命令码随之改变数字达到增减
我们将通过定时器和外部中断0来进行操控写出NEC编码 利用不同的状态表示到达不同的编码阶段
Timer0.h #ifndef TIMER0_H #define TIMER0_Hvoid Timer0Init(); void Timer0_SetCounter(unsigned int Value); unsigned int Timer0_GetCounter(); void Timer0_Run(unsigned char Flag); #endifTimer0.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) {TH0Value/256;TL0Value%256; }//定时器0获取计数器值 unsigned int Timer0_GetCounter() {return (TH08)|TL0; }//定时器0启动停止控制 void Timer0_Run(unsigned char Flag) {TR0Flag; } 将定时器初始化为0让定时器实现计时器的功能 Interrupt.h #ifndef INTERRUPT_H #define INTERRUPT_Hvoid Interrupt0_Init();#endifInterrupt.c #include REGX52.H//外部中断0初始化 void Interrupt0_Init() {IT01;IE01;EX01;EA1;PX01; } 按键对应命令码
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(); unsigned char IR_GetDataFlag(); unsigned char IR_GetRepeatFlag(); unsigned char IR_GetAddress(); unsigned char IR_GetCommand();#endifIR.c #include REGX52.H #includeTimer0.h #includeInterrupt.hunsigned 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_DataFlag0;return 1;}return 0; }//红外遥控获取收到连发标志位 unsigned char IR_GetRepeatFlag() {if(IR_DataFlag){IR_RepeatFlag0;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_State0) //状态0空闲状态{Timer0_SetCounter(0); //计数器清0Timer0_Run(1); //定时器启动IR_State1; //变为状态1}else if(IR_State1) //状态1等待Start信号或Repeat信号{IR_TimeTimer0_GetCounter(); //获取开始的时间或重复的时间Timer0_SetCounter(0); //计时器清0if(IR_Time12442-500IR_Time12442500)//表示是开始信号进入下一阶段{IR_State2;}else if(IR_Time10368-500IR_Time10368500)//是重复信号回到最初的起点{IR_RepeatFlag1; //连发帧标志位置1Timer0_Run(0); //定时器停止IR_State0; //状态置0}else{IR_State1;}}else if(IR_State2) //状态2接收数据{IR_TimeTimer0_GetCounter();//获取接收数据的时间段Timer0_SetCounter(0);if(IR_Time1032-500IR_Time1032500)//数据接到为0{IR_Data[IR_pData/8]~(0x01(IR_pData%8));IR_pData;}else if(IR_Time2074-500IR_Time2074500)//数据接收到为1{IR_Data[IR_pData/8]|(0x01(IR_pData%8));//除8是将32位下标分为4个元素模8将32位下标从0~7有序循环IR_pData;}else //接收错误{IR_pData0;IR_State1;}if(IR_pData32) //如果收到了32位{IR_pData0; //下标清0if((IR_Data[0]~IR_Data[1])(IR_Data[2]~IR_Data[3])) //数据验证{IR_AddressIR_Data[0]; //存储数据IR_CommandIR_Data[2];IR_DataFlag1; //数据帧标志位置1}Timer0_Run(0); //定时器停止IR_State0; //状态置0}} }LCD1602.c #include REGX52.H//引脚配置 sbit LCD_RSP2^6; sbit LCD_RWP2^5; sbit LCD_ENP2^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_RS0;LCD_RW0;LCD_DataPortCommand;LCD_EN1;LCD_Delay();LCD_EN0;LCD_Delay(); }/** brief LCD1602写数据* param Data 要写入的数据* retval 无/ void LCD_WriteData(unsigned char Data) {LCD_RS1;LCD_RW0;LCD_DataPortData;LCD_EN1;LCD_Delay();LCD_EN0;LCD_Delay(); }/** brief LCD1602设置光标位置* param Line 行位置范围1~2* param Column 列位置范围1~16* retval 无/ void LCD_SetCursor(unsigned char Line,unsigned char Column) {if(Line1){LCD_WriteCommand(0x80|(Column-1));}else if(Line2){LCD_WriteCommand(0x80|(Column-10x40));} }/** brief LCD1602初始化函数* param 无* retval 无*/ void LCD_Init() {LCD_WriteCommand(0x38);//八位数据接口两行显示57点阵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(i0;String[i]!\0;i){LCD_WriteData(String[i]);} }/** brief 返回值X的Y次方*/ int LCD_Pow(int X,int Y) {unsigned char i;int Result1;for(i0;iY;i){ResultX;}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(iLength;i0;i–){LCD_WriteData(Number/LCD_Pow(10,i-1)%100);} }/** 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(Number0){LCD_WriteData();Number1Number;}else{LCD_WriteData(-);Number1-Number;}for(iLength;i0;i–){LCD_WriteData(Number1/LCD_Pow(10,i-1)%100);} }/** 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(iLength;i0;i–){SingleNumberNumber/LCD_Pow(16,i-1)%16;if(SingleNumber10){LCD_WriteData(SingleNumber0);}else{LCD_WriteData(SingleNumber-10A);}} }/** 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(iLength;i0;i–){LCD_WriteData(Number/LCD_Pow(2,i-1)%20);} } 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#includeLCD1602.h #includeIR.hunsigned 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()) //数据帧或者重复帧{AddressIR_GetAddress(); //获取遥控器地址吗CommandIR_GetCommand(); //获取遥控器命令吗LCD_ShowHexNum(2,1,Address,2);LCD_ShowHexNum(2,7,Command,2);if(CommandIR_VOL_MINUS){Num–;}if(CommandIR_VOL_ADD){Num;}LCD_ShowNum(2,12,Num,3);}} }通过判断标志位是否为1来表示是否有遥控信息传输