完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
下面是红外解码的程序,其中有几处不懂,求大神解释。。。。
/******************************************************************************* * * 普中科技 -------------------------------------------------------------------------------- * 实 验 名 : 红外线试验 * 实验说明 : 数码管显示红外线发送过来的键值。 * 连接方式 : 见连接图 * 注 意 : *******************************************************************************/ #include //--定义使用的IO--// #define GPIO_DIG P0 ***it LSA = P2^2; ***it LSB = P2^3; ***it LSC = P2^4; ***it IRIN = P3^2; //--定义全局变量--// unsigned char code DIG_CODE[17]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码 unsigned char DisplayData[8]; //用来存放要显示的8位数的值 unsigned char IrValue[6]; //用来存放读取到的红外值 unsigned char time; //--声明全局函数--// void DigDisplay(); //动态显示函数 void IrInit(); void DelayMs(unsigned int ); /******************************************************************************* * 函数名 : main * 函数功能 : 主函数 * 输入 : 无 * 输出 : 无 *******************************************************************************/ void main() { // unsigned char i; IrInit(); while(1) { IrValue[4]=IrValue[2]>>4; //高位 ???什么意思?它的值是多少?? IrValue[5]=IrValue[2]&0x0f; //低位??? DisplayData[0] = 0x00; DisplayData[1] = DIG_CODE[IrValue[4]]; DisplayData[2] = DIG_CODE[IrValue[5]]; DisplayData[3] = 0x76; //01110110 DisplayData[4] = 0x00; DisplayData[5] = DIG_CODE[IrValue[4]]; DisplayData[6] = DIG_CODE[IrValue[5]]; DisplayData[7] = 0x76; DigDisplay(); } } /******************************************************************************* * 函数名 : DelayMs() * 函数功能 : 延时 * 输入 : x * 输出 : 无 *******************************************************************************/ void DelayMs(unsigned int x) //0.14ms误差 0us { unsigned char i; while(x--) { for (i = 0; i<13; i++) {} } } /******************************************************************************* * 函数名 : IrInit() * 函数功能 : 初始化红外线接收 * 输入 : 无 * 输出 : 无 *******************************************************************************/ void IrInit() { IT0=1;//下降沿触发 EX0=1;//打开中断0允许 EA=1; //打开总中断 IRIN=1;//初始化端口 } /******************************************************************************* * 函数名 : ReadIr() * 函数功能 : 读取红外数值的中断函数 * 输入 : 无 * 输出 : 无 *******************************************************************************/ void ReadIr() interrupt 0 { unsigned char j,k; unsigned int err; Time=0; DelayMs(70); if(IRIN==0) //确认是否真的接收到正确的信号 { err=1000; //1000*10us=10ms,超过说明接收到错误的信号 /*当两个条件都为真是循环,如果有一个条件为假的时候跳出循环,免得程序出错的时 侯,程序死在这里*/ while((IRIN==0)&&(err>0)) //等待前面9ms的低电平过去 { DelayMs(1); err--; } if(IRIN==1) //如果正确等到9ms低电平 { err=500; while((IRIN==1)&&(err>0)) //等待4.5ms的起始高电平过去 { DelayMs(1); err--; } for(k=0;k<4;k++) //共有4组数据 { for(j=0;j<8;j++) //接收一组数据 { err=60; while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去 { DelayMs(1); err--; } err=500; while((IRIN==1)&&(err>0)) //计算高电平的时间长度。 { DelayMs(1);//0.14ms Time++; err--; if(Time>30) //这是什么意思?? { EX0=1; return; //这个怎么返回??是中断结束?? } } IrValue[k]>>=1; //k表示第几组数据//这个数组都没有赋初值,又怎么知道它的元素是多少,怎么移位???? if(Time>=8) //如果高电平出现大于565us,那么是1 { IrValue[k]|=0x80; //数组元素是多少都不知道,怎么进行运算???? } Time=0; //用完时间要重新赋值 } } } if(IrValue[2]!=~IrValue[3]) { return; } } } /******************************************************************************* * 函 数 名 : DigDisplay * 函数功能 : 使用数码管显示 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void DigDisplay() { unsigned char i; unsigned int j; for(i=0;i<8;i++) { switch(i) //位选,选择点亮的数码管, { case(0): LSA=0;LSB=0;LSC=0; break;//显示第0位 case(1): LSA=1;LSB=0;LSC=0; break;//显示第1位 case(2): LSA=0;LSB=1;LSC=0; break;//显示第2位 case(3): LSA=1;LSB=1;LSC=0; break;//显示第3位 case(4): LSA=0;LSB=0;LSC=1; break;//显示第4位 case(5): LSA=1;LSB=0;LSC=1; break;//显示第5位 case(6): LSA=0;LSB=1;LSC=1; break;//显示第6位 case(7): LSA=1;LSB=1;LSC=1; break;//显示第7位 } GPIO_DIG=DisplayData;//发送段码 j=10; //扫描间隔时间设定 while(j--); GPIO_DIG=0x00;//消隐 } }
|
|
相关推荐
19个回答
|
|
while((IRIN==1)&&(err>0)) //计算高电平的时间长度。
{ DelayMs(1);//0.14ms Time++; err--; if(Time>30) //这是什么意思?? DelayMs(1);每循环一次,time加一,这里判断Time有没超过30次,即时间有没超过30*0.14ms { EX0=1; return; //这个怎么返回??是中断结束??退出一个循环,这里是while((IRIN==1)&&(err>0)) } } IrValue[k]>>=1; //k表示第几组数据//这个数组都没有赋初值,又怎么知道它的元素是多少,怎么移位???? 不用赋初值,因为要用的是通过移位后得到的值 if(Time>=8) //如果高电平出现大于565us,那么是1 { IrValue[k]|=0x80; //数组元素是多少都不知道,怎么进行运算????通过移位后进行或运算( | ),0x80 就是2进制 1000 000 , 或了之后第八位为1,其他7位保留来的数值 不能保证完全正确,只是自己的一些理解,希望能帮助你 } |
|
1 条评论
|
|
while((IRIN==1)&&(err>0)) //计算高电平的时间长度。 { DelayMs(1);//0.14ms Time++; err--; if(Time>30) //这是什么意思?? DelayMs(1);每循环一次,time加一,这里判断Time有没超过30次,即时间有没超过30*0.14ms { EX0=1;//为什么要写这个??? return; //这个怎么返回??是中断结束??退出一个循环,这里是while((IRIN==1)&&(err>0)) } } IrValue[k]>>=1; //k表示第几组数据//这个数组都没有赋初值,又怎么知道它的元素是多少,怎么移位???? 不用赋初值,因为要用的是通过移位后得到的值//那它移位后是多少?? if(Time>=8) //如果高电平出现大于565us,那么是1 { IrValue[k]|=0x80; //数组元素是多少都不知道,怎么进行运算????通过移位后进行或运算( | ),0x80 就是2进制 1000 000 , 或了之后第八位为1,其他7位保留来的数值 不能保证完全正确,只是自己的一些理解,希望能帮助你 } |
|
|
|
while((IRIN==1)&&(err>0)) //计算高电平的时间长度。 { DelayMs(1);//0.14ms Time++; err--; if(Time>30) //这是什么意思?? DelayMs(1);每循环一次,time加一,这里判断Time有没超过30次,即时间有没超过30*0.14ms { EX0=1;//为什么要写这个??? return; //这个怎么返回??是中断结束??退出一个循环,这里是while((IRIN==1)&&(err>0)) } } IrValue[k]>>=1; //k表示第几组数据//这个数组都没有赋初值,又怎么知道它的元素是多少,怎么移位???? 不用赋初值,因为要用的是通过移位后得到的值//那它移位后是多少?? if(Time>=8) //如果高电平出现大于565us,那么是1 { IrValue[k]|=0x80; //数组元素是多少都不知道,怎么进行运算????通过移位后进行或运算( | ),0x80 就是2进制 1000 000 , 或了之后第八位为1,其他7位保留来的数值 不能保证完全正确,只是自己的一些理解,希望能帮助你 } |
|
|
|
见识了
|
|
|
|
长见识了 ,不错,支持了
|
|
|
|
{:1:}{:1:}
|
|
|
|
数组没有赋初值,初始化为0,移位后还是0. 2楼兄弟已经解释很明白了
|
|
|
|
对这样的程序不看好,居然在中断里面延迟这么长时间,要是us级的延迟还说得过去
|
|
|
|
请问一下,一般都有什么样的红外管
|
|
|
|
|
|
|
|
挺不错的,真好
|
|
|
|
问题解决了吗啊
|
|
|
|
|
|
|
|
|
|
|
|
void main() { // unsigned char i; IrInit(); //红外线初始化。 while(1) { IrValue[4]=IrValue[2]>>4; //高位 //这两行就类似于十进制数据个位十位的分解。 IrValue[5]=IrValue[2]&0x0f; //低位 DisplayData[0] = 0x00; //下面就和用数码管显示一个两位数一样。 DisplayData[1] = DIG_CODE[IrValue[4]];//IrValue[]数组中的元素是二进制,作为DIG_CODE[]数组的下标时会自动转换成十进制。 DisplayData[2] = DIG_CODE[IrValue[5]]; DisplayData[3] = 0x76; //01110110 DisplayData[4] = 0x00; DisplayData[5] = DIG_CODE[IrValue[4]]; DisplayData[6] = DIG_CODE[IrValue[5]]; DisplayData[7] = 0x76; DigDisplay(); } } 纯属个人理解,如有不对之处,请多多指教。 |
|
|
|
|
|
|
|
看看看看看看看看看看看看看看看看看看
|
|
|
|
懂了不少,在学红外这块
|
|
|
|
请问一下,为什么下降沿进入中断后要延时9.8ms?延时完了9.8ms后,红外线数据前的9ms低电平不是过去了吗?而且因为是9.8ms过去了,这个时候应该进行到4.5ms的高电平了吧?那么第一个if(IRIN==0)应该是不成立了啊?然后就是为什么是1000*10us=10ms?DelayMS(1);不是应该是1*0.14ms=0.14ms=140us在加上执行err--;和while语句的时间乘1000吗?楼主,这里怎么理解,小弟初学单片机不是太懂 |
|
1 条评论
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
求助一下关于51系列单片机的Timer0的计时问题,TH0、TL0+1的时间是怎么算的?
195 浏览 0 评论
【RA-Eco-RA4E2-64PIN-V1.0开发板试用】开箱+Keil环境搭建+点灯+点亮OLED
172 浏览 0 评论
【敏矽微ME32G070开发板免费体验】使用coremark测试敏矽微ME32G070 跑分
453 浏览 0 评论
【敏矽微ME32G070开发板免费体验】开箱+点灯+点亮OLED
697 浏览 2 评论
602 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11977 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-20 15:47 , Processed in 1.354737 second(s), Total 129, Slave 104 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号