51单片机+红外发射模块(38k+NEC),这代码对不对?有详细注释!

shaoxiaojing5193 2013-03-12 03:52:12
哪位大神帮小弟看一下这段代码,是网上载的,我大概修改了一下几个数值,因为我觉得原来的错的,结果红外发射模块发射不了,用原来载下来的数值执行起来也是不行,小弟这里没示波器,这份代码小弟很详细的给它添加了很多注释,只求有心的前辈帮一下小弟,帮忙看一下哪里不对。。。。 38k + NEC协议。。。。作者没有使用循环去发送 用户码 用户反码 键码 键反码,所以代码看起来比较多,其实是很少的。。。
捣鼓了我好几天了一直不知道为什么不行,啊啊啊啊啊啊 拜托前辈了!帮了小弟这个忙,什么都好说



//#include <AT89X51.h> 
#include <reg51.h>

static bit OP; //红外发射管的亮灭控制位
static unsigned int count; //延时计数器
static unsigned int endcount; //终止延时计数
static unsigned char flag; //红外发送标志
sbit P3_4=P3^4;
char iraddr1; //十六位地址的第一个字节
char iraddr2; //十六位地址的第二个字节
void SendIRdata(char p_irdata);//发送子函数
void delay();


void main(void)
{
count = 0;
flag = 0; //无载波
OP = 0; //不亮
P3_4 = 0; //在后面会发现用OP赋值的
EA = 1; //允许CPU中断
TMOD = 0x11; //设定时器0和1为16位模式1
ET0 = 1; //定时器0中断允许
TH0 = 0xFF;
TL0 = 0xE6; //设定时值0为38K 也就是每隔26us中断一次
TR0 = 1; //开始计数
iraddr1=3; //自定义的一个地址
iraddr2=252; //地址反码

do
{
delay(); //延时
SendIRdata(221); //发送数据

}while(1);
}

//定时器0中断处理
void timeint(void) interrupt 1
{
TH0=0xFF;
TL0=0xE6; //设定时值为38K 也就是每隔26us中断一次
count++;

if (flag==1) //如果是待发送的有效数据flag=1,就在此产生载波(亮灭交变)
{
OP=~OP; //产生方波其实就是调制后的高电平哈
}
else
{
OP = 0; //发送低电平
}

P3_4 = OP; //往发射模块的 IO口发送出去哈
}

void SendIRdata(char p_irdata) //发送数据子函数
{
int i;
char irdata=p_irdata;

/***************************************************************/

//发送9ms的起始码
//引导码是9ms的高电平,9000us/26us = 346
endcount = 346;
flag=1; //载波模式有效
count=0;
while(count<endcount); //等待中断,在中断中发送载波,总时间为9ms


//发送4.5ms的结果码,并是载波模式无效,也就是发送4.5ms的低电平
//结果码是 4500us/26us = 173
endcount = 173;
flag=0;
count=0;
while(count<endcount);

/***************************************************************/
//发送十六位地址的前八位,iraddr存的是地址码
irdata=iraddr1;
for(i=0;i<8;i++)
{
//一个周期里规定先以高电平开始,在以低电平结束。先发送0.56ms的38KHZ“1”的红外波(即编码中0.56ms的高电平)
endcount = 21; //560us/26us = 21
flag=1;
count=0;
while(count<endcount); //等待中断


if(irdata-(irdata/2)*2) //判断二进制数个位为1还是0
{
endcount=64; //如果是 1,修改 endcount = 64, 64*26us = 1680us
}
else
{
endcount=21;//如果是0,则低电平 21*26us = 560us;
}
flag=0; //因为发送的 0,所以调制后就是一连串连续的低电平,所以 flag=0,载波模式无效
count=0;

while(count<endcount); //等待中断发送

irdata=irdata>>1;//依次取位

}

//发送十六位地址的后八位


irdata=iraddr2; //此处已经是地址的反码
for(i=0;i<8;i++)
{
endcount = 21;
flag=1;
count=0;

while(count<endcount);

if(irdata-(irdata/2)*2)
{
endcount = 64;

}
else
{
endcount = 21;
}

flag=0;
count=0;

while(count<endcount);

irdata=irdata>>1;
}/***************************************************************/
//发送八位数据

irdata=p_irdata;

for(i=0;i<8;i++)
{
endcount = 21;
flag=1;
count=0;

while(count<endcount);

if(irdata-(irdata/2)*2)
{
endcount=64;;

}
else
{
endcount = 21;
}

flag=0;
count=0;

while(count<endcount);

irdata=irdata>>1;
}

//发送八位数据的反码
irdata=~p_irdata; //要将数据位取反

for(i=0;i<8;i++)
{
endcount = 21;
flag=1;
count=0;

while(count<endcount);

if(irdata-(irdata/2)*2)
{
endcount = 64;
}
else
{
endcount = 21;
}

flag=0;
count=0;

while(count<endcount);

irdata=irdata>>1;
}

//到这边一帧的数据已经按照 38K + NEC发送出去了
}


void delay()
{
int i,j;

for(i=0;i<400;i++)
{
for(j=0;j<100;j++)
{
}
}
}


...全文
1028 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
am540 2014-10-21
  • 打赏
  • 举报
回复
while(count<endcount); 有问题 没有count++
shaoxiaojing5193 2013-03-12
  • 打赏
  • 举报
回复
引用 1 楼 duojinian 的回复:
1.注意硬件电路需要匹配合适的晶体,如果是外部晶体的话。 2.内部晶体需要注意匹配发送速率。
硬件方面很简单阿,我是用 51的核心板,然后网上买的红外发射模块,有 GND,GCC,OUT 三个引脚,直接就接51的IO口了,所以硬件方面应该不会有问题吧。。。至于38k,NEC,都是用51的定时器实现的。。。还请前辈花点心思帮忙看下代码啊,这问题实在是困扰小弟多日了。。。。
DISINHUI 2013-03-12
  • 打赏
  • 举报
回复
1.注意硬件电路需要匹配合适的晶体,如果是外部晶体的话。 2.内部晶体需要注意匹配发送速率。
这是DS小龙哥编写的(STC)51单片机开发手册,适合51单片机入门初学者,大学生等当做工具书使用。实验的平台采用的是普中科技单片机平台,文章中的知识点详细代码清晰,注释清楚,可以复制粘贴,配套代码详细。目前写了4个大章节,后续会持续更新,更新后重新下载即可。 每个例子的完整的工程源码在PDF里有百度云盘的下载链接。失效了可以私信发送。 目前PDF里包含的目录如下: 51单片机开发手册 1 一、 单片机开发入门知识介绍 1 1.1 51单片机介绍 1 1.2 市场上的主流单片机种类 1 1.3 FPGA与单片机区别 2 1.4 DSP和单片机区别 3 二、搭建开发环境 4 2.1 STC单片机命名介绍 4 2.2 安装keil软件 4 2.3 新建工程 5 2.4 下载程序 8 2.5 使用辅助工具计算延时时间 12 2.6 STC90C51系列单片机引脚图 13 三、 基础入门学习 14 3.1 LED灯模块 14 3.2 蜂鸣器模块 17 3.5 独立按键 18 3.6 矩阵键盘 22 3.7 独立数码管(静态数码管) 26 3.8 动态数码管 29 3.9 LED 16*16点阵 33 3.10 采用38译码器驱动8位数码管 48 四、单片机提高篇 53 4.1 定时器 53 4.2 中断 60 4.3 串口通信 71 4.4 NEC红外线遥控器解码 80 4.5 DS18B20温度传感器 87 4.6 EEPROM存储芯片(AT24C02) 96 4.7 DS1302 实时时钟芯片 107 4.8 PCF8591(ADC/DAC)转换芯片 119 4.9 (HC-SR04)超声波测距模块 130 4.10 使用计数器测量NE555脉冲频率 134 4.11 LCD1602显示屏 139 四、 单片机项目篇 146 5.1 16x16点阵滚动显示 146

27,375

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧