tianxiaoMCU
发表于 2012-5-11 17:29:53
好好学习
fanjian224
发表于 2012-5-20 21:21:25
你好,我想问问,
else while(1) //38KHz脉冲,占空比5:26
{
IR = 0;
if(TF0)break;
if(TF0)break;
IR = 1;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
if(TF0)break;
}
怎么就实现了占空比为 5:26 啊,不解?
BXAK
发表于 2012-5-20 21:27:46
本帖最后由 BXAK 于 2012-5-20 21:29 编辑
fanjian224 发表于 2012-5-20 21:21 static/image/common/back.gif
你好,我想问问,
else while(1) //38KHz脉冲,占空比5:26
{
看36、43、44楼回复
fanjian224
发表于 2012-5-20 21:33:36
BXAK 发表于 2012-5-20 21:27 static/image/common/back.gif
看36、43、44楼回复
楼主谢谢啦
苦行僧
发表于 2012-5-20 21:37:38
过些天也要弄一下红外,看看
fanjian224
发表于 2012-5-20 21:54:05
楼主,我想问问怎么才能增加红外发送距离,老师让我们做个红外,要发送距离为50米,我看了看网上,最多就是10米
楼主,你给点建议吧
BXAK
发表于 2012-5-20 22:49:27
fanjian224 发表于 2012-5-20 21:54 static/image/common/back.gif
楼主,我想问问怎么才能增加红外发送距离,老师让我们做个红外,要发送距离为50米,我看了看网上,最多就是 ...
红外不可见光,还是红外激光?
通信点对点,还是像家用遥控器那样广角度?
我们平时用的红外发射二极管是 20多mW(压降约1.4v,工作平均电流一般小于20mA),较好环境下遥控>=10米,
如果是红外不可见光广角度遥控更远距离,
要用大功率红外发射二极管,淘宝有卖0.3W、0.5W的,1元多,
50米也就是用于室外了,也就不可能像室内那样随意方向都可以遥控电视,
要选着发射角度较小的,信号才不会过于分散,保证距离远时信号强度;但发射角度太小信号过于集中遥控角度就小了,根据需要(有10、30、45、60度角的),
室外的强光环境,接收头型号、滤光、聚光也要考虑(还是一句话,根据实际需要增减,实验如果不加滤光、聚光也OK那最好),
其它的看看43、44楼回复
liycobl
发表于 2012-5-20 23:42:25
mark .
fanjian224
发表于 2012-5-23 21:53:27
BXAK 发表于 2012-2-5 22:42 static/image/common/back.gif
回复【34楼】tzsteel
-----------------------------------------------------------------------
楼主,想问问哪种红外一体接收头比较好,最好接收距离比较远的
BXAK
发表于 2012-5-23 23:00:11
fanjian224 发表于 2012-5-23 21:53 static/image/common/back.gif
楼主,想问问哪种红外一体接收头比较好,最好接收距离比较远的
接触有限,就不推荐了,你暂时用一般的一体化接收管实验,把发射部分搞好,尽量试试看能多远,
那个发射管要>=0.3W的,发射角度小些10度、20度角,直径>=5mm,淘宝有卖自己搜索
另:2~3只发射管串联发射,供电源的电容量也要够大
fanjian224
发表于 2012-5-24 13:04:43
BXAK 发表于 2012-5-23 23:00 static/image/common/back.gif
接触有限,就不推荐了,你暂时用一般的一体化接收管实验,把发射部分搞好,尽量试试看能多远,
那个发射 ...
嘻嘻,非常感谢楼主!!!
fanjian224
发表于 2012-5-30 15:55:36
楼主,麻烦问下,发射用的PNP什么型号比较合适?
BXAK
发表于 2012-5-30 16:06:35
fanjian224 发表于 2012-5-30 15:55 static/image/common/back.gif
楼主,麻烦问下,发射用的PNP什么型号比较合适?
S8550挺合适的,没有就9012之类
fanjian224
发表于 2012-5-30 19:12:14
BXAK 发表于 2012-5-30 16:06 static/image/common/back.gif
S8550挺合适的,没有就9012之类
嗯,谢谢啦
fanjian224
发表于 2012-5-31 19:50:47
楼主,我想问问,你拿这个程序做过实物没,想问问你用的红外接收管的型号是多少?
我用的红外发射管是遥控上的l,接收头不知道什么型号,是不是型号不一样接收不到啊?
ljt80158015
发表于 2012-5-31 19:54:13
收藏了,慢慢看!
ljt80158015
发表于 2012-5-31 19:54:37
收藏了,慢慢看!
ljt80158015
发表于 2012-5-31 19:54:56
收藏了,慢慢看!
ljt80158015
发表于 2012-5-31 19:55:12
收藏了,慢慢看!
ljt80158015
发表于 2012-5-31 19:55:33
收藏了,慢慢看!
ljt80158015
发表于 2012-5-31 19:56:00
收藏了,慢慢看!
BXAK
发表于 2012-5-31 20:22:20
fanjian224 发表于 2012-5-31 19:50 static/image/common/back.gif
楼主,我想问问,你拿这个程序做过实物没,想问问你用的红外接收管的型号是多少?
我用的红外发射管是遥控 ...
自然做过,也用很久了,
你发射、接收所用的单片机具体是什么型号,晶振多少
fanjian224
发表于 2012-6-2 17:51:30
BXAK 发表于 2012-5-31 20:22 static/image/common/back.gif
自然做过,也用很久了,
你发射、接收所用的单片机具体是什么型号,晶振多少 ...
楼主,现在能用了,发射用的是89C52,接收用的是90C51
fanjian224
发表于 2012-6-2 18:04:02
BXAK 发表于 2012-5-20 22:49 static/image/common/back.gif
红外不可见光,还是红外激光?
通信点对点,还是像家用遥控器那样广角度?
楼主,你好,我用的红外线不可见光点对点通信,角度10度的就行
想问问红外用的聚光镜一般用什么啊,我想用这个东西让红外平行发射,不至于太过分散。
楼主,你一般做红外时用聚光镜吗?
downtoearth
发表于 2012-6-2 18:10:47
这个现在正需要!记号!
BXAK
发表于 2012-6-2 19:18:17
fanjian224 发表于 2012-6-2 18:04 static/image/common/back.gif
楼主,你好,我用的红外线不可见光点对点通信,角度10度的就行
想问问红外用的聚光镜一般用什么啊,我想 ...
我用来遥控家里的小电器,用不上这么小得角度。
红外线发射管 + 一般的放大镜就行(注意:发射管要散光类的,放大镜的焦距要小),不过自己弄挺麻烦的,像:调节、固定……都不方便,
钱包鼓的话,建议买现成的,不过挺贵的,好像便宜的也要几十元,其实也就是我平常看到的(可见光)红外激光笔,只是把发光管换成了真正的红外线发射管(不可见光),
如果还是打算自己弄的话,可以买(可见光)红外激光笔(就2元钱)拆了用里面的放大镜
PS:
相同直径下,放大镜焦距小放大倍数大,放大镜焦距大放大倍数小。
红外不可见光可以用手机的摄像头观察。
fanjian224
发表于 2012-6-4 16:14:51
BXAK 发表于 2012-2-2 19:32 static/image/common/back.gif
回复【18楼】tzsteel
-----------------------------------------------------------------------
else wh ...
楼主,你好,这个程序的载波频率为38.461kHz
如何能让频率变为38Khz呢
fanjian224
发表于 2012-6-4 16:15:55
楼主,你好,这个程序的载波频率为38.461kHz
如何能让频率变为38Khz呢
BXAK
发表于 2012-6-4 19:14:05
fanjian224 发表于 2012-6-4 16:15 static/image/common/back.gif
楼主,你好,这个程序的载波频率为38.461kHz
如何能让频率变为38Khz呢
19楼、20楼、36楼回复有说明
fanjian224
发表于 2012-6-4 20:44:08
BXAK 发表于 2012-6-4 19:14 static/image/common/back.gif
19楼、20楼、36楼回复有说明
我还是闹不懂nop()需要多少时间,
如果是12Mhz的话,应该是1us吧,不知道我说的对不对
如果是1us的话,那就达不到38Khz啦
楼主,麻烦你给解释一下吧,谢谢啦
BXAK
发表于 2012-6-4 21:39:17
本帖最后由 BXAK 于 2012-6-4 21:41 编辑
38KHz周期:26.315789473684210526315789473684us
老51(如:AT89C52、STC89C52……)指令速度以机器周期来算:1机器周期(us) = 12个时钟 = 12/频率(MHz)
增强型高速51(如:STC 1T系列……)指令速度直接以时钟来算,时钟(us) = 1/频率(MHz)
老51很难生成26.315789473684210526315789473684us,除非用特殊频率的晶振,STC 12T系列@12MHz时只能用最接近的26us,也就是38.461KHz
高速51可以接近很接近,STC 1T系列@12MHz时可以用最接近的26.333333333333333333333333333333us,也就是37.974KHz
fanjian224
发表于 2012-6-5 10:14:35
tzsteel 发表于 2012-2-2 19:04 static/image/common/back.gif
回复【楼主位】BXAK
-----------------------------------------------------------------------
大侠,你好,我想问问你怎么用软件实现载波频率为38Khz的微调的,楼主的载波频率38.46Khz,我想实现38Khz,怎么微调啊?
BXAK
发表于 2012-6-5 10:23:14
fanjian224 发表于 2012-6-5 10:14 static/image/common/back.gif
大侠,你好,我想问问你怎么用软件实现载波频率为38Khz的微调的,楼主的载波频率38.46Khz,我想实现38Khz ...
看132楼的说明
fanjian224
发表于 2012-6-5 10:34:13
BXAK 发表于 2012-6-4 21:39 static/image/common/back.gif
38KHz周期:26.315789473684210526315789473684us
老51(如:AT89C52、STC89C52……)指令速度以机器周期来 ...
楼主,谢谢你啦
tzsteel
发表于 2012-7-5 19:07:01
请问一下楼主红外解码部份,好像只是解点按的,要解连按的话要咋弄啊?连按的话,是连着发9MS+2.25MS的码。谢谢
有缘于你
发表于 2012-7-7 19:03:44
很不错
MCUStudent
发表于 2012-7-7 20:10:41
MARK!人都说好!我也马克。
c475301174
发表于 2012-7-21 15:49:57
请问解码程序中的#define Boot_Limit (((9000+4500) +2000)/Step) //引导码周期上限
#define Boot_Lower (((9000+4500) -2000)/Step) //引导码周期下限
#define Bit1_Limit ((2250 +800)/Step) //“1”周期上限
#define Bit0_Limit ((1125 +400)/Step) //“0”周期上限
是怎么得出来的,看不明白,上限和下限是根据什么计算出来的。
c475301174
发表于 2012-7-21 18:24:33
BXAK 发表于 2012-6-5 10:23 static/image/common/back.gif
看132楼的说明
请问BXAK解码程序中引导码和bit 0发送和bit 1发送怎么有上下限啊,这点不明白Boot_Limit,Boot_Lower,Bit1_Limit, Bit0_Limit这几个是什么意思。我明白数据码中一字节数据会有时间长短不一样。但是引导码在不是9ms高电平和4.5ms 低电平吗,是怎样计算出来的
BXAK
发表于 2012-7-21 18:45:08
就是做个阀门,不过允许误差2000us有点大了,改成1000吧,
说白了,就是设置允许误差范围,
理论引导码周期9000+4500,单片机不可能每次检测到的引导码周期准准是13500ms,尤其是程序里用的是定时器中断查询下降沿,实际测出的值有些波动在所难免,
13500 -1000<时间<13500 +1000,就可以认为是引导码到了,同步置位开始尝试解码
BXAK
发表于 2012-7-21 18:46:15
c475301174 发表于 2012-7-21 18:24 static/image/common/back.gif
请问BXAK解码程序中引导码和bit 0发送和bit 1发送怎么有上下限啊,这点不明白Boot_Limit,Boot_Lower,Bi ...
就是做个阀门,不过允许误差2000us有点大了,改成1000吧,
说白了,就是设置允许误差范围,
理论引导码周期9000+4500,单片机不可能每次检测到的引导码周期准准是13500ms,尤其是程序里用的是定时器中断查询下降沿,实际测出的值有些波动在所难免,
13500 -1000<时间<13500 +1000,就可以认为是引导码到了,同步置位开始尝试解码
c475301174
发表于 2012-7-21 18:58:59
BXAK 发表于 2012-7-21 18:46 static/image/common/back.gif
就是做个阀门,不过允许误差2000us有点大了,改成1000吧,
说白了,就是设置允许误差范围,
理论引导码周 ...
谢谢BXAK的解答,我还以为是数据码中那种全0或全1而导致一字节数据时间有一个范围,现在明白了,谢谢~^~
huangpeifeng
发表于 2012-7-26 14:52:27
#include "INC\MY_SET.H"
#include "INC\IR_NEC.H" //调用NEC解码头文件
这两个文件有么?
BXAK
发表于 2012-7-26 17:06:04
huangpeifeng 发表于 2012-7-26 14:52 static/image/common/back.gif
#include "INC\MY_SET.H"
#include "INC\IR_NEC.H" //调用NEC解码头文件
都在压缩包里面
huangpeifeng
发表于 2012-7-26 20:32:54
BXAK 发表于 2012-7-26 17:06 static/image/common/back.gif
都在压缩包里面
找到了,不过收到会有时乱码,如果长按一次就在P1++;怎么改呢?程序反应有点慢
hlfqzy
发表于 2012-7-30 15:39:14
谢谢楼主,正要学习这个,还有个问题想请教下,就是你现在的那按连按处理,是达到了时间后才动作的,但是如果要改成你电视那种音量控制那种方式要怎么改动呢
dtrabbit8
发表于 2012-8-17 09:59:42
mark 一下
rookieli
发表于 2012-8-17 16:03:43
收藏之{:lol:}
aysyjgw
发表于 2012-8-17 16:05:00
支持下,楼主辛苦
chenfzg
发表于 2012-8-17 16:50:21
写的不错~~~~~~~
hubaixdl123
发表于 2012-8-20 19:51:56
本帖最后由 hubaixdl123 于 2012-8-21 19:49 编辑
用VU2联合PROTEUS进行仿真发送部分没有问题。
但是用VU2联合PROTEUS进行接收解码仿真时,出现了指针跑乱的情况,用其它版本也是一样。我将接收解码的程序从
IR_NEC.H中考到主程序后,程序可以运行,但是相应的发送部分无法同时进行,依据是发送一边的LED没有显示。
如果有可以仿真接收部分的大侠,请告知解决方法。谢谢!
jz701209李
发表于 2012-8-21 20:14:36
学习学习,谢谢
madswan
发表于 2012-8-31 10:59:13
好东西。不过没装仿真软件,打不开.DSn文件,楼主位的图太小,看不清电阻值多少,请问发射功能单片机电路中三个电阻分别是多少?
tangzhipeng12
发表于 2012-8-31 12:09:07
顶……{:victory:}
madswan
发表于 2012-9-3 10:49:01
楼主怎么还没有来
dory_m
发表于 2012-9-3 11:20:26
不错,谢谢!!!{:biggrin:}
xdco
发表于 2012-9-3 12:16:49
mark一下
克隆
发表于 2012-9-3 12:31:56
看到了,就标记下,说不定会用到!
yihui184
发表于 2012-9-4 11:48:46
xyr 发表于 2012-5-7 09:18 static/image/common/back.gif
不是软件的问题,我由原来AVR Studio 4改为ICC编译就好了,具体AVR Studio 4为什么不行我还未查清,
谢 ...
移值成功啦?移植到AVR了?
15813191501
发表于 2012-10-2 15:29:50
点h文件里面有程序也能编译,我以前连定义变量在点h文件里也会报错。
xfdr
发表于 2012-11-15 22:04:46
不错,学习一下
hncjs
发表于 2012-11-15 22:28:08
不错的
1752482885
发表于 2012-11-27 20:25:05
学学,最近正在解码红外。
mTouch
发表于 2012-11-29 17:01:36
有人在AT89C2051上测试通过吗?
mTouch
发表于 2012-11-30 21:47:29
用AT89C2051芯片,同样采用12M晶振,将代码修改为如下:
发射部分:
#include <AT892051.h>
#include "INC\MY_SET.h"
//sbitIR= P3^6; //发射引脚(接PNP三极管基极)
sbitIrOutput= P1^6;
//#defineUSER_H P2 //用户码高8位
//#defineUSER_L P0 //用户码低8位
#defineUSER_H0x03
#defineUSER_L 0xFC
//uint8c tab = { //操作码
// 0x12,0x05,0x1e,0x55,
// 0x01,0x1b,0x03,0x6b,
// 0x07,0x08,0x09,0x68,
// 0x22,0xE6,0x33,0xe2};
#define m9 (65536-9000) //9mS
#define m4_5(65536-4500) //4.5mS
#define m1_6(65536-1650) //1.65mS
#define m_56(65536-560) //0.56mS
#define m40 (65536-40000) //40mS
#define m56 (65536-56000) //56mS
#define m2_25 (65536-2250) //2.25mS
voidZZ(uint8 x); //NEC编码发送程序
voidZ0(uint8 temp); //单帧(8位数据)发送程序
voidTT0(bit BT,uint16 x); //38KHz载波发射 + 延时程序
void delay()//延时程序,大约 1s
{
int i,j;
for(i=0;i<400;i++)
{
for(j=0;j<100;j++)
{
}
}
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:主程序
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void main(void)
{
TMOD = 0x01; //T0 16位工作方式
IrOutput=1; //发射端口常态为高电平(接PNP三极管基极)
//IrOutput=0; //发射端口常态为低电平(接NPN三极管基极)
while(1)
{
ZZ(0x05);
delay();
delay();
delay();
}
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:NEC编码发送程序
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void ZZ(uint8 Value)
{
TT0(1,m9); //高电平9mS
TT0(0,m4_5); //低电平4.5mS
/*┈ 发送4帧数据┈*/
Z0(USER_H); //用户码高8位
Z0(USER_L); //用户码低8位
Z0(Value); //操作码
Z0(~Value); //操作码反码
/*┈┈ 结束码 ┈┈*/
TT0(1,m_56);
TT0(0,m40);
/*┈┈ 重复码 ┈┈*/
/*while(1)//KEY() != 0xFF)
{
TT0(1,m9);
TT0(0,m2_25);
TT0(1,m_56);
TT0(0,m40);
TT0(0,m56);
} */
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:单帧(8位数据)发送程序
入口:temp
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void Z0(uint8 temp)
{
uint8 v;
for (v=0;v<8;v++) //循环8次移位
{
TT0(1,m_56); //高电平0.65mS
if(temp&0x01) TT0(0,m1_6); //发送最低位
else TT0(0,m_56);
temp >>= 1; //右移一位
}
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:38KHz载波发射 + 延时程序
入口:(是否发射载波,延时约 x (uS))
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void TT0(bit BT,uint16 x)
{
TH0 = x>>8; //输入T0初始值
TL0 = x;
TF0=0; //清0
TR0=1; //启动定时器0
if(BT == 0) while(!TF0); //BT=0时,不发射38KHz载波只延时;BT=1发射38KHz脉冲且延时;
else while(1) //BT=1时,发射38KHz脉冲+延时;38KHz载波,(低电平)占空比5:26
{
IrOutput = 0; // PNP
// IrOutput = 1; // NPN
if(TF0)break;if(TF0)break;
_nop_(); //频率有些高,降低添加适量的空操作“_nop_();”(注:不要放在大括号两侧)
IrOutput = 1; // PNP
//IrOutput = 0; // NPN
if(TF0)break;if(TF0)break;
if(TF0)break;if(TF0)break;
if(TF0)break;if(TF0)break;
if(TF0)break;if(TF0)break;
if(TF0)break;if(TF0)break;
}
/*
else while(1) //BT=1时,发射38KHz脉冲+延时;38KHz载波(低电平)占空比约5:26
{
// IrOutput = 0; // PNP
IrOutput = 1; // NPN
if(TF0)break;if(TF0)break;
if(TF0)break;if(TF0)break;
_nop_();
//IrOutput = 1; // PNP
IrOutput = 0; // NPN
if(TF0)break;if(TF0)break;
if(TF0)break;if(TF0)break;
if(TF0)break;if(TF0)break;
if(TF0)break;if(TF0)break;
}
*/
TR0=0; //关闭定时器0
TF0=0; //标志位溢出则清0
IrOutput =1; //载波停止后,发射端口常态为高 (接PNP三极管基极)
//IrOutput =0; //载波停止后,发射端口常态为高 (接NPN三极管基极)
}
接收部分:
#include <AT892051.h>
#include "INC\MY_SET.H"
#include "INC\IR_NEC.H" //调用NEC解码头文件
sbit IrLED =P1^6; //指示1
sbit LED1 = P1^5; //指示2
sbit LED2 = P1^4; //指示3
void KZ0(); //短按处理
/***************** 主函数 ********************/
void main(void)
{
IRSignal = 1;//P1口引脚写入“1”时,其可用作输入端
IR_Init(); //红外线解码初始化
LED1 = 1;
LED2 = 1;
IR_BT= 0;
while(1)
{
//遥控检测
if ((IR_BT==2)||(IR_BT==3))
{
TR0 = 0;
KZ0(); //短按处理
IR_BT =0; //清有效标志
IRReset();
TR0 = 1;
}
if (!IRSignal)
{
IrLED =0;
}
else
{
IrLED = 1;
}
}
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:遥控短按处理
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void KZ0()
{
switch(NEC)
{
// case 0x12: P10 = !P10; break;
case 0x12:
LED1 = 0;//~LED1;
LED2 = 1;
break;
case 0x05:
LED2 = 0;//~LED2;
LED1 = 1;
break;
case 0x1E: break;
case 0x55: break;
case 0x01: break;
case 0x1B: break;
case 0x03: break;
case 0x6B: break;
case 0x07: break;
case 0x08: break;
case 0x09: break;
case 0x68: break;
case 0x22: break;
case 0xE6: break;
case 0x33: break;
case 0xE2: break;
default:break;
}
}
/********************** 定时器0中断函数************************/
void time0(void) interrupt 1
{
IR_NEC();
}
#ifndef __IR_NEC_H__
#define __IR_NEC_H__
//【用户必填项:USER_H、USER_L、Check_EN、CPU_Fosc、IR】
#defineUSER_H 0x80 //用户码高8位
#defineUSER_L 0x7F //用户码低8位
#defineCheck_EN 0 //是否要校验16位用户码:不校验填0,校验则填1
#defineCPU_Fosc 12000000 //输入主频,自适应解码(单位:Hz,范围:6MHz ~ 40MHz)
#defineCA_S 8 //长按时间设置,单位:108mS(即 108mS整数倍,10倍以上为宜)
//sbit IR = P3^6; //红外线接口(任意引脚)
sbit IRSignal = P1^7; //红外线接口(任意引脚)
#defineStep 400 //红外采样步长:400us
#defineTH_H ((65536-Step*(CPU_Fosc/300)/40000)/256)//定时器高8位基准赋值
#defineTH_L ((65536-Step*(CPU_Fosc/300)/40000)%256)//定时器低8位基准赋值
uint8 IR_BT; //解码效果返回:0无效,1有效,2短按,3长按
uint8 NEC; //解码存放:16位用户码、操作码正反码
uint8 cntCA; //长按计数
//uint16cntStep; //步数计
uint8 cntStep; //步数计
bit IRa,IRb; //电位状态保存
bit IRsync; //同步标志
uint8 BitN; //位码装载数
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:红外线解码初始化
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void IR_Init()
{
TMOD &= 0xF0; //清定时器0
TMOD |= 0x01; //定时器0:16位定时器
TL0 = TH_L; //每步时间
TH0 = TH_H;
ET0 = 1;
EA= 1;
TR0 = 1;
}
void IRReset()
{
TL0 = TH_L; //每步时间
TH0 = TH_H;
NEC = 0x00; //解码存放:16位用户码、操作码正反码
NEC = 0x00;
NEC = 0x00;
NEC = 0x00;
cntCA = 0; //长按计数
cntStep = 0; //步数计
IRa =0;
IRb = 0; //电位状态保存
IRsync =0; //同步标志
BitN =0; //位码装载数
}
/*┈┈┈┈┈┈┈┈┈┈ 基准 ┈┈┈┈┈┈┈┈┈┈┈*/
//#define Boot_Limit (((9000+4500) +2000)/Step) //引导码周期上限
//#define Boot_Lower (((9000+4500) -2000)/Step) //引导码周期下限
//#define Bit1_Limit ((2250 +800)/Step) //“1”周期上限
//#define Bit0_Limit ((1125 +400)/Step) //“0”周期上限
//允许误差2000us有点大了,改成1000
#define Boot_Limit (((9000+4500) +1000)/Step) //引导码周期上限
#define Boot_Lower (((9000+4500) -1000)/Step) //引导码周期下限
#define Bit1_Limit ((2250 +800)/Step) //“1”周期上限
#define Bit0_Limit ((1125 +400)/Step) //“0”周期上限
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:红外线NEC周期采样解码法(定时中断,下降沿查询周期时间)
全局变量:IR_BT = 0无效
1有效,待继续判断长、短按(如不需要判断长、短按,则直接使用)
2短按
3长按
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void IR_NEC()
{
TL0 = TH_L; //重赋值
TH0 = TH_H;
IRb = IRa; //上次电位状态
IRa = IRSignal; //当前电位状态
cntStep++; //步数采样
if (IR_BT==1)
{
if(cntStep>300)
{
IR_BT=2;//解码有效后,如果无长按,120ms(400us×300)后默认短按
}
}
// IRb = IRa; //上次电位状态
// IRa = IRSignal; //当前电位状态
if(IRb && !IRa) //是否下降沿(上次高,当前低)
{
if(cntStep > Boot_Limit) //超过同步时间?
{
if(IR_BT==1)
{
if(++cntCA>CA_S)
{
IR_BT=3; //解码有效后,继续按住遥控>CA_S即长按
}
}
IRsync=0; //同步位清0
}
else if (cntStep > Boot_Lower)
{
IRsync=1;
BitN=32;
}//同步位置1,装载位码数
else if (IRsync) //如果已同步
{
if(cntStep > Bit1_Limit)
{
IRsync=0;
}
else
{
NEC >>= 1;
if(cntStep > Bit0_Limit)
NEC |= 0x80; //“0”与“1”
if(--BitN == 0)
{
IRsync = 0; //同步位清0
#if (Check_EN == 1)
if((NEC==USER_H)&&(NEC==USER_L)&&(NEC==~NEC)) //校验16位用户码、操作码正反码
{
IR_BT=1;
cntCA=0;
} //解码有效,接下来判断:短按?长按?
#else
if(NEC==~NEC)
{
IR_BT=1;
cntCA=0;
} //校验操作码正反码
#endif
}
else if ((BitN & 0x07)== 0) //NEC每装满8位,移动保存一次(即 BitN%8 == 0)
{
NEC=NEC;
NEC=NEC;
NEC=NEC;
}
}
}
cntStep = 0; //步数计清0
}
}
//取消相关宏定义
#undef CPU_Fosc
#endif
其他部分,没有改动!
写入芯片之后, 无法解码出来哦!
拜托各位,看看问题出在哪里?
HeP028
发表于 2012-11-30 22:28:36
留个爪印
mTouch
发表于 2012-12-1 14:54:51
mTouch 发表于 2012-11-30 21:47 static/image/common/back.gif
用AT89C2051芯片,同样采用12M晶振,将代码修改为如下:
发射部分:
#include
移植到89C2051成功!
前面不成功的原因是下面的代码的原因:
if(NEC==~NEC)
{
TR0 =0; // 增加
IR_BT=1;
}
判断解码成功之后, 没有TR0=0的话,
下面的代码,没有执行到
if(cntStep>300)
{
IR_BT=2;//解码有效后,如果无长按,120ms(400us×300)后默认短按
}
也没有执行到
if(++cntCA>CA_S)
{
IR_BT=3; //解码有效后,继续按住遥控>CA_S即长按
}
这可能跟发射部分有关!
另外,还修改了下面的二句宏定义
#define Boot_Limit (((9000+4500) +500)/Step) //引导码周期上限
#define Boot_Lower (((9000+4500) -500)/Step) //引导码周期下限
tian_cn
发表于 2012-12-2 13:13:15
mark............
lxa0
发表于 2012-12-2 22:05:50
好文章~~~~~~~~~~~~~
mTouch
发表于 2012-12-3 14:33:58
BXAK 发表于 2012-2-3 19:15 static/image/common/back.gif
回复【22楼】tzsteel
-----------------------------------------------------------------------
如何修改为占空比为1/3 或1/10 ?
Doctor_A
发表于 2012-12-3 14:50:32
楼主 ,这个程序有很大的BUG。。。单片机仿真中错开了漏洞所在。
单片机查询方式浪费了大量的单片机时间。
程序中的38K红外产生部分实际中不能应用。
相信产生的频率比38K低得多。。根本无法编码。
利用中断的方式比较适合。
BXAK
发表于 2012-12-3 20:42:23
Doctor_A 发表于 2012-12-3 14:50 static/image/common/back.gif
楼主 ,这个程序有很大的BUG。。。单片机仿真中错开了漏洞所在。
单片机查询方式浪费了大量的单片机时间。
...
“相信产生的频率比38K低得多。。根本无法编码。”你懂汇编吗?你看过其他坛友的回复吗?说得这么绝对,从坛友的回复看,他们也成功了,而且我是实物验证成功了,想分享才弄了个仿真上传的
Doctor_A
发表于 2012-12-4 09:10:42
BXAK 发表于 2012-12-3 20:42 static/image/common/back.gif
“相信产生的频率比38K低得多。。根本无法编码。”你懂汇编吗?你看过其他坛友的回复吗?说得这么绝对, ...
这样啊。。。我也是先利用查询方式失败后改用中断才可以执行的。。只不过占空比需要两个中断辅助完成调节而已。。查询方式以26US的时间查询示波器显示编码长度延长了不少。。得此回复
hlfqzy
发表于 2012-12-4 10:55:49
楼主,你现在这个程序只支持长短按键,如果要改成连按呢?要怎么改动?望指点
LQS1200
发表于 2013-1-4 20:15:45
看看!谢谢!
dexidz
发表于 2013-1-6 07:03:32
多好的贴子!总有人都不仔细看就回复!不知道会暴露出你挺二的啊!?
bbssilverkey
发表于 2013-1-8 14:34:28
认真看了,这个代码写的很模块,复用率很高
wgui
发表于 2013-1-22 00:56:22
不错!支持!
beyondvs
发表于 2013-2-21 16:14:52
本帖最后由 beyondvs 于 2013-2-21 16:19 编辑
BXAK 发表于 2012-2-23 00:45 static/image/common/back.gif
回复【45楼】wangyz1997
-----------------------------------------------------------------------
非常感谢楼主,用你的程序调通了12T的STC89C58系列单片机红外发射模块,但是我们现在用的都是1T的STC12C5A32S2单片机,楼主发得1T程序看的不太明白,请教如下:
void TT0(bit BT,uint16 X)
{
uint8 t;
TH0 = ((uint8 *)&X); //X高8位
TL0 = ((uint8 *)&X); //X低8位
TF0=0; //清0
TR0=1; //启动定时器0
if(BT) //38KHz载波,(低电平)占空比约 9:(9+28)【12M: 1t <=> 1/12(uS),38KHz周期26.316uS <=> 316t 】
{
while(1)
{
IR_Out = 0; // 4t
for(t=9;t;t--)if(TF0)goto TN; // 2t + (4t+4t)*x
if(TF0)goto TN; // 4t
IR_Out = 1; // 4t
for(t=28;t;t--)if(TF0)goto TN; // 2t + (4t+4t)*x
if(TF0)goto TN; // 4t
}
}
else while(!TF0);
TN:TR0 =0; //关闭定时器0
IR_Out =1; //38KHz载波停止后,发射端口常态=1
}
1.楼主程序里goto TN是什么意思?倒数第三行也有个TN:TR0 =0; 不明白什么意思。
2.TH0 = ((uint8 *)&X); //X高8位
TL0 = ((uint8 *)&X); //X低8位
这个,如何理解?为何12T程序里是这样赋初值的
TH0 = x>>8; //输入定时值
TL0 = x;
麻烦楼主把1T的38KHz载波发射 + 延时程序重新注释整理共享下,非常感谢,感觉楼主这段程序写的 太精妙。
3.12T发射程序里
TT0(1,m9); //高电平9mS
TT0(0,m4_5); //低电平4.5mS
/*┈ 发送4帧数据┈*/
Z0(USER_H); //用户码高8位
Z0(USER_L); //用户码低8位
Z0(Value); //操作码
Z0(~Value); //操作码反码
/*┈┈ 结束码 ┈┈*/
TT0(1,m_56);
TT0(0,m40);
NEC协议里为何有结束码?不是9MS高电平+低电平4.5mS+用户名+用户反码+操作码+操作反码吗?
hamipeter
发表于 2013-2-21 17:37:15
不错,支持下
BXAK
发表于 2013-2-21 23:14:21
beyondvs 发表于 2013-2-21 16:14 static/image/common/back.gif
非常感谢楼主,用你的程序调通了12T的STC89C58系列单片机红外发射模块,但是我们现在用的都是1T的STC12C5 ...
1、关于 goto:http://baike.baidu.com/view/3209842.htm,看了就知道 TN 是干嘛的
2、 ((uint8 *)&X)、 ((uint8 *)&X) 通过指针方式获取X的高八位、低八位(具体看C语言的指针用法),而且这个还要注意不同编译器大小端不同,比如:
【大小端】
Keil-C51 大端寻址
SDCC-C51 小端寻址
AVRGCC 小端寻址
……
如果将一个32位的整数0x12345678存放到一个长整型变量(long)中,这个整型变量采用大端或者小端模式在内存中的存储由下表所示。
简单起见,用OP0表示一个32位数据的最高字节MSB(Most Significant Byte),用OP3表示一个32位数据最低字节LSB(Least Significant Byte)。
地址偏移 大端模式 小端模式
0x00 12(OP0) 78(OP3)
0x01 34(OP1) 56(OP2)
0x02 56(OP2) 34(OP1)
0x03 78(OP3) 12(OP0)
如:uint16 X = 0x1234,
在 Keil-C51 中, ((uint8 *)&X) 即是 0x12 、 ((uint8 *)&X) 即是 0x34;
在 SDCC-C51 中, ((uint8 *)&X) 即是 0x34 、 ((uint8 *)&X) 即是 0x12;
在 AVRGCC 中, ((uint8 *)&X) 即是 0x34 、 ((uint8 *)&X) 即是 0x12;
3、标准NEC编码没仔细看,但我平时用的各种成品NEC编码遥控器都这样,自己用示波器 或者 简易逻辑分析仪((最新)热转印自制了一个红外线遥控逻辑分析器) 捕捉一个完整的波形看看最清楚
XSEAYCY
发表于 2013-2-22 21:27:01
先下载,有时间试试。
beyondvs
发表于 2013-2-27 12:05:49
今天试了楼主的1T发射程序,可以发射,楼主真是牛人,还有一些疑问要请教楼主:我家电视机遥控器是NEC协议的,DVD遥控器是其他协议的,而空调遥控器是每按一次键,发送两次NEC协议码,如何做到能学习各种遥控器码?
allen0871
发表于 2013-2-27 12:17:56
mark, 好资料
jacktau
发表于 2013-2-27 12:30:22
好东西,顶起来,感谢共享~~~~~~~~~~~~
BXAK
发表于 2013-2-27 20:41:53
beyondvs 发表于 2013-2-27 12:05 static/image/common/back.gif
今天试了楼主的1T发射程序,可以发射,楼主真是牛人,还有一些疑问要请教楼主:我家电视机遥控器是NEC协议 ...
参考:基于STC89C52的简易学习型红外遥控器,
这个只是简易的单键固定码学习,看原理,自己修改完善吧
hncjs
发表于 2013-2-27 20:57:15
红外解码不错的
zhuzhaokun1987
发表于 2013-3-6 18:11:13
学习了~!
jack6735
发表于 2013-4-11 16:56:10
楼主,菜鸟请问如何把你的程序改成按住一个键,让小灯亮,放开就熄灭的效果??
灰灰不会飞
发表于 2013-4-12 08:47:06
mark
zhxshseu
发表于 2013-4-12 09:05:24
mark一下~~~~
dyzhenhuai
发表于 2013-4-14 15:19:37
学习,学习,再学习!!!!
propor123
发表于 2013-4-14 16:08:50
学习一下。
miller8708
发表于 2013-4-14 16:15:04
收藏了谢谢
jiang47
发表于 2013-4-14 17:34:38
标记一下。。。
hncjs
发表于 2013-4-14 19:54:05
不错的红外解码
HeP028
发表于 2013-5-2 23:25:04
留言备用!!
dlion
发表于 2013-5-3 14:43:13
用STC1T 发56KHz载波 怎么计算
zhongH
发表于 2013-5-3 14:59:53
mark
qq511153186
发表于 2013-5-3 22:43:17
自己正在做红外解码的,学习