51红外解码调试笔记

发布者:beta12最新更新时间:2015-02-05 来源: 51hei关键字:红外解码  调试笔记 手机看文章 扫描二维码
随时随地手机看文章
    前阵子帮他们做实习小车的买东西,看着便宜就顺便买了个红外的遥控器和1838的红外接收头子。这两天闲着没事,看了很多资料才终于完成了红外解码,的确是久了没玩51,好多东西生疏了导致调试过程几经挫折,经过这次复习了好多51的东西,受益匪浅。
    查阅资料得知常见红外编码为PPM制式。红外发射端以脉宽0.565ms、间隔0.56ms的脉冲信号表示二进制“0”,以脉宽0.565ms,间隔1.65ms的脉冲信号为“1”。如下图.
上述“0”、“1”组成的32位二进制码经过38KHz的载波进行二次调制以提高发射效率、降低电源功耗。
32位二进制码组中,前16位为用户识别码,能区别不同电气设备防止不同机种遥控码相互干扰。后16位为8位操作码极其反码。遥控器在按下后周期性的发出一种32位二进制码,周期108ms。这108ms由一个起始码(9ms),一个结果码(4.5ms),低8位地址码、高8位地址码、8位数据码极其8位数据反码组成。
 
接受时使用1838通用红外接头

红外接头将38K载波信号过滤掉,得到与发射代码反向接受码。
上述是我自己整理的资料。后经示波器验证大致是这样的,便开始编写程序。

红外解码的关键就是识别“0”和“1”。以下是具体代码,通过51单片机接受红外信号,解码后将8位操作码通过串口以十六进制发送给电脑(比较粗糙,还没来得及完善,仅供参考)[page]

 
#include//单片机型号STC89C52
 
#define uchar unsigned char
#define uint unsigned int
 
sbit IR=P3^2;//位定义,使用P3^2口外部中断0
 
uint lowtime,hightime;
uchar a[4],m,flag;
 
bit decode();//解码程序
void sci();//串口初始化
 
void main()
{
// delay_ms(100);
TR0=0;
TH0=0;
TL0=0;
sci();
EA=1;
IT0=1;//设置外部中断0为下降沿触发方式
EX0=1;//开外部中断0
while(1)
{
if(flag==1) //验证前导码正确后才开始解码并向串口发送数据
{
decode();
for(m=0;m<1;m++)//向串口发射a[2],及8位操作码
{
SBUF=a[2];
while(!TI);
TI=0;
}
while(1);
}
}
}
 
void ext0() interrupt 0
{
EX0=0;//进外部中断0后立即关闭中断0,防止二次中断
TR0=1;//开定时器0
while(IR==0);//一直计数,直到IR由0跳变到1
TR0=0;//关闭定时器0
lowtime=256*TH0+TL0;//lowtime储存引导码低电平持续时间
TH0=0;
TL0=0;//清空定时器0寄存器值,以备下一次计数
TR0=1;
while(IR==1);//等待IR由1跳表到0
TR0=0;//关闭定时器0
hightime=256*TH0+TL0;//hightime存储结果码高电平持续时间
if((lowtime>7800)&&(lowtime<8800)&&(hightime>3600)&&(hightime<4700))
//9000us/1.085=8294,判断区间8800-7800
//4500us/1.085=4100,判断区间3600-4700
//此值为11.0592MHz晶振时的值。  
flag=1;//符合判断条件则将flag标志置1,否则认为是干扰信号不予解码
}
 
bit decode()
{
uchar temp;
uchar i,j;
for(i=0;i<4;i++)
{
for(j=0;j<7;j++)
{
temp>>=1;
TH0=0;
TL0=0;
TR0=1;
while(IR==0);
TR0=0;
lowtime=256*TH0+TL0;
TH0=0;
TL0=0;
TR0=1;
while(IR==1);
TR0=0;
hightime=256*TH0+TL0;
if((lowtime<370)||(lowtime>640))//低电平时间长度不合理
return 0;
if((hightime>420)&&(hightime<620))//高电平持续时间560us左右即位“0”
temp&=0x7f;
if((hightime>1300)&&(hightime<1800))//高电平持续时间1680us左右即位“1”
temp|=0x80;
}
a[i]=temp;
}
}
 
void sci()
{
SM0=0;
SM1=1;
REN=1;
TMOD=0x21;//此处注意设置定时器0的方式为工作方式1
TH1=0xfd;
TL1=0xfd;
TR1=1;
ES=1;
}

串口显示出的十六进制的编码(每次单片机断电的时候都会向电脑发送00,不知道为什么...)
 
 
这只是初步的程序,调试过程中状况百出。显示串口显示问题,SBUFS是8位寄存器,只能存储8位二进制数据,故32位二进制需要发送四次,每次到串口为1位十六进制数据。还有定时器0的模式,之前一直没有设置,结果郁闷了一晚上。
 
另外,关于红外的用途的话,有人说这东西接受距离不远,也就几米(有资料说在输出段并上1uf电容可将接收距离增加至十多米,待验证),最致命的是它是红外线,必须要将发射端对准接收端才能接收到信号,这就是它比不上蓝牙、NRF24L01等无线通信最主要的原因。不过,NRF24L01之麻烦,以我的智商估计没有半个月是做不出来的。
关键字:红外解码  调试笔记 引用地址:51红外解码调试笔记

上一篇:单片机外围电路中涉及的问题
下一篇:51单片机之printf

推荐阅读最新更新时间:2024-03-16 13:53

W801单片机学习笔记——调试器的配置与使用(适用于W801和W806)
1.前言 在以往的Cortex-M内核单片机的开发中,最离不开的一个东西就是调试器,什么J-Link,ST-Link,DAP-Link等等,没了他们调试程序感觉浑身难受,效率直线下降。调试器就好比是战士的枪,W801单片机的开发当中怎么能够没有。与W801单片机配套的调试器叫做ICE,该调试器官方卖得很贵,不过大佬们已经攻克了下来,笔者用的ICE正是大佬们设计的ICE 记得给这位UP点赞打赏哦。 做好之后是这样的: 2.调试器设置 首先,打开工程的属性,并找到Debug页,如下图: 按照红色框中设置,并点击Settings... ,点击后如下图所示: 点击黄色框右下方的Update即可检查ICE是否与W801正
[单片机]
W801单片机学习<font color='red'>笔记</font>——<font color='red'>调试</font>器的配置与使用(适用于W801和W806)
uPD6121 avr红外解码程序
#include iom16v.h #include macros.h #define uint unsigned int #define uchar unsigned char #define ulong unsigned long /*------------------------------显示-----------------------------------*/ #define LED _DATA PORTB const uchar tab ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x7
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved