历史上的今天
今天是:2024年08月27日(星期二)
2021年08月27日 | 51单片机-代码文件和测试
2021-08-27 来源:eefocus
创建好“infrared.c”和“infrared.h”文件。
1.infrared.c的代码
#include #include unsigned char irflag = 0; //红外接收标志,收到一帧正确数据后置1 unsigned char ircode[4]; //红外代码接收缓冲区 /* 初始化红外接收功能 */ void InitInfrared() { IR_INPUT = 1; //确保红外接收引脚被释放 TMOD &= 0x0F; //清零T1的控制位 TMOD |= 0x10; //配置T1为模式1 TR1 = 0; //停止T1计数 ET1 = 0; //禁止T1中断 IT1 = 1; //设置INT1为负边沿触发 EX1 = 1; //使能INT1中断 } /* 获取当前高电平的持续时间 */ unsigned int GetHighTime() { TH1 = 0; //清零T1计数初值 TL1 = 0; TR1 = 1; //启动T1计数 while (IR_INPUT) //红外输入引脚为1时循环检测等待,变为0时则结束本循环 { if (TH1 >= 0x40) { //当T1计数值大于0x4000,即高电平持续时间超过约18ms时, break; //强制退出循环,是为了避免信号异常时,程序假死在这里。 } } TR1 = 0; //停止T1计数 return (TH1*256 + TL1); //T1计数值合成为16bit整型数,并返回该数 } /* 获取当前低电平的持续时间 */ unsigned int GetLowTime() { TH1 = 0; //清零T1计数初值 TL1 = 0; TR1 = 1; //启动T1计数 while (!IR_INPUT) //红外输入引脚为0时循环检测等待,变为1时则结束本循环 { if (TH1 >= 0x40) { //当T1计数值大于0x4000,即低电平持续时间超过约18ms时, break; //强制退出循环,是为了避免信号异常时,程序假死在这里。 } } TR1 = 0; //停止T1计数 return (TH1*256 + TL1); //T1计数值合成为16bit整型数,并返回该数 } /* INT1中断服务函数,执行红外接收及解码 */ void EXINT1_ISR() interrupt 2 { unsigned char i,j; unsigned char byt; unsigned int time; //接收并判定引导码的9ms低电平 time = GetLowTime(); if ((time<7833) || (time>8755)) //时间判定范围为8.5~9.5ms, { //超过此范围则说明为误码,直接退出 IE1 = 0; //退出前清零INT1中断标志 return; } //接收并判定引导码的4.5ms高电平 time = GetHighTime(); if ((time<3686) || (time>4608)) //时间判定范围为4.0~5.0ms, { //超过此范围则说明为误码,直接退出 IE1 = 0; return; } //接收并判定后续的4字节数据 for (i=0; i<4; i++) //循环接收4个字节 { for (j=0; j<8; j++) //循环接收判定每字节的8个bit { //接收判定每bit的560us低电平 time = GetLowTime(); if ((time<313) || (time>718)) //时间判定范围为340~780us, { //超过此范围则说明为误码,直接退出 IE1 = 0; return; } //接收每bit高电平时间,判定该bit的值 time = GetHighTime(); if ((time>313) && (time<718)) //时间判定范围为340~780us, { //在此范围内说明该bit值为0 byt >>= 1; //因低位在先,所以数据右移,高位为0 } else if ((time>1345) && (time<1751)) //时间判定范围为1460~1900us, { //在此范围内说明该bit值为1 byt >>= 1; //因低位在先,所以数据右移, byt |= 0x80; //高位置1 } else //不在上述范围内则说明为误码,直接退出 { IE1 = 0; return; } } ircode[i] = byt; //接收完一个字节后保存到缓冲区 } irflag = 1; //接收完毕后设置标志 IE1 = 0; //退出前清零INT1中断标志 } 2.infrared.h的代码 因为主函数中只需要使用“InitInfrared();”函数来初始化,而“unsigned int GetHighTime()”和“unsigned int GetLowTime()”都是只在“void EXINT1_ISR() interrupt 2”中使用,所以头文件不用声明这三部分的函数。 #ifndef __INFRARED_H__ #define __INFRARED_H__ sbit IR_INPUT = P3^3; //红外接收引脚 extern unsigned char irflag; //红外接收标志,收到一帧正确数据后置1 extern unsigned char ircode[4]; //红外代码接收缓冲区 void InitInfrared(); //初始化红外接收功能 #endif 3.main.c测试代码 我们在宋老师的例程lesson16_1中通过按红外遥控器上的按键得知,第一行的三个按键会使ircode[2]分别变为0x45、0x46、0x47显示在数码管上,那么我们只需要判断ircode[2]的数据就可以知道按下的是哪个按键然后去执行相关任务就可以了。 我们用小灯测试红外遥控器的按键是否有效,有效则会切换小灯的亮灭。 #include #include #include void main() { LED_Init();//初始化LED硬件模块 EA = 1; InitInfrared(); while (1) { if (irflag) { irflag = 0; //以下是遥控器第一行按键 if(ircode[2]==0x45)LED9=!LED9; if(ircode[2]==0x46)LED8=!LED8; if(ircode[2]==0x47)LED7=!LED7; //以下是遥控器第二行按键 if(ircode[2]==0x44)LED4=!LED4; if(ircode[2]==0x40)LED3=!LED3; if(ircode[2]==0x43)LED2=!LED2; } } }
上一篇:51单片机-红外遥控
下一篇:51单片机-温度传感器代码解析Ⅰ
史海拾趣
|
第一节: 心情和时钟 说实话我能够使用的单片机不多,我总是以为无论什么单片机都能开发出好的产品。 前些年用51,总是向各位大大学习,无休止的索取,在网上狂览一通。心里感激的同时也想奉献一些,可是我会什么?后来使用avr(公司要求)还是 ...… 查看全部问答> |
|
安全监控系统常见的故障现象在一个监控系统进入调试阶段、试运行阶段以及交付使用后,有可能出现这样那样的故障现象,如:不能正常运行、系统达不到设计要求的技术指标、整体性能和质量不理想,亦即一些软毛病。这些问题对于一个安防系统工程项目来 ...… 查看全部问答> |
|
原来在windows mobile 6.0上开发了个应用程序,现在想移植到wince6.0 的PND上(找别人买的,好象没有提供SDK),不知该如何做,我用VS2005,只能选择mobile 6.0的开发环境。我想在在这个pnd上开发程序,并能在其模拟器运行与调试… 查看全部问答> |
|
爱晶电子 基于ENC28J60的PIC以太网开发板(PIC实验板/PIC开发板) ¥450 http://item.taobao.com/auction/item_detail-db2-cdaacf2253921bc4ab5b5d41b991e651.jhtml 小新电子 PIC18F97J60 以太网开发板 一 口 价: 298.00元 http:/ ...… 查看全部问答> |
|
最近做一个项目,把两个现有设备并凑到一起。两个设备CPU需要通信,所有接口都有其他用途,只剩下一个Jtag,有没有办法使用Jtag进行通信?系统是基于Linux的,想不重写驱动就可以通信,不知有没有可能,本人对Jtag没什么了解,望达人指教。… 查看全部问答> |
|
【VxWorks5.x -->VxWorks6.x 移植问题】 大家好,谁有没有做过 PPC的BSP 从 5.X ---> 6.X 的移植啊? 我所知道的是,从6.x对5.X的支持是兼容的,那么我就先把 5.X 的BSP文件夹 如 ppc_myself_XXX 放到 h/config/ 下,然后新建立 BSP 工程,进行编译,可是编译的时候,发现ERROR超多啊 ...… 查看全部问答> |
|
103系列的好用的USB iap现在挪到105下不好用了。 对这个USB很不了解。 现在哪里能找到基于USB-OTG的USB iap例程? 哪位能分享一下例程不胜感激… 查看全部问答> |




