迅维网

标题: 自制STC80C51红外遥控电路板 [打印本页]

作者: 蟒山    时间: 2013-11-8 20:35
标题: 自制STC80C51红外遥控电路板
/*
此程序为红外遥控,按遥控器上的按键后在数据管上显示相应的地址码和指令码

*/

#include "reg52.h"
#define uchar unsigned char
sbit hwx=P3^3;                      //中断1端口P3.3
uchar irtime,irdata[32],ircord[4];  //irtime:收集IR1838数据引脚低电平脉冲宽度的计数变量,根据此变量数值大小判断是0还是1
                                                                        //irdata数组:地址码和指令码每位的存储数组,地址码16位,指令码8位,指令码反码8位,共32位,引导码丢弃没用
                                                                        //ircord数组:将地址码和指令码做转后存储为字节的数组,以便查询num数组里面的值,在数码管上显示码值的十六进制
uchar code num[]={                                        //数码管显示所有数组
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
bit irok;                                                 //将位数转为字节数后的标志位

void delay(unsigned int k)                //执行一次为50ms左右
{
        uchar i;
        unsigned int j;
        i=250;
        while(i)
        {
                j=k;
                while(j)j--;
                i--;
        }
}
void tim0init()                          //定时器0初始化函数
{
        TMOD=0x02;
        ET0=1;
        EA=1;
}
void ex1init()                        //中断1初始化函数
{
        IT1=1;
        EX1=1;
}
void tim0ir() interrupt 1                        //定时器0中断函数
{
        irtime++;                                           //irtime为低电平宽度变量,每加1,时间将增加256微秒
}
void ex1ir() interrupt 2                  //中断1中断函数
{
        static uchar i;                                //i变量为局部静态变量,第二次进入函数时,其值不会被置0,而是接着上一次调用函数后的值运行
        static bit startflag;                //startflag变量:判断是引导码后,其值置1,表示接收码数据开始.接收32个位后,被置0,停止接收
        uchar tmp;
        tmp=10;
        while(tmp) tmp--;                   //延时函数,消除干扰
        if(hwx)                                           //再次判断是干扰还是数据,hwx为0表示数据,为1表示是干扰产生的中断
        {
                return;
        }                  
        TH0=TL0=0;
        TR0=1;                                         //每位中断产生时,计数清零
        if(startflag)
        {
                irdata=irtime;         
                irtime=0;
                i++;
                if(i==32)                         //当计满32位后,将相关变量清0,准备接收第二次按键
                {
                       
                        EX1=0;                        //关闭中断,延时400ms,消除有用数据后的干扰数据
                        TR0=0;
                        startflag=0;
                        irok=1;                         //接收完时,将irok置1,表示可以进行位到字节的转换
                        delay(200);                  //延时25为50ms左右,延时200既为400ms
                        EX1=1;                         //延时消除干扰后,打开中断,准备接收第二次按键
                        return;
                }
        }
        if((irtime>=47)&&(irtime<56))        //如果irtime在47和56之间,确定为引导码,准备接收数据
        {
                i=0;
                irtime=0;
                startflag=1;                   //startflag置1后,下一次的中断既为接收址码开始
        }

}
void irpro()
{
        uchar i,j,k,value;
        value=k=0;                          //此处需注意加赋值语句,不然第二次调用函数时,两个变量的初值有时不会是0
        for(i=0;i<4;i++)          //共四个字节需要转
        {
                for(j=0;j<8;j++)   //每字节八位
                {
                        value=value>>1;
                         if(irdata[k]>5) value=value|0x80;
                        k++;
                }
           ircord=value;                 //将位转为字节后的数据存入ircord数组
           value=0;
        }
        irok=0;           //转换结束标志
}
void irdisplay()                //数码管显示函数
{
       
        P1=0;
        P2=num[ircord[0]/16];         //以16进制显示
        delay(1);

        P1=1;
        P2=num[ircord[0]%16];
        delay(1);

        P1=3;
        P2=num[ircord[2]/16];
        delay(1);

        P1=4;
        P2=num[ircord[2]%16];
        delay(1);
}
void main(void)
{
        tim0init();
        ex1init();
        while(1)
        {
                if(irok)
                {
                        irpro();          //位数转换为字节
                }
                irdisplay();        //显示码值
               
       
        }
       
}



作者: chengjunkou    时间: 2013-11-8 21:15
闲得没事做得人,还不如再设计点火药什么什么得,哪样才有实用性
作者: Love恋爱Summ    时间: 2013-11-8 22:35
学习了
作者: Rainwong    时间: 2013-11-8 22:42
原来遥控器这么麻烦啊!
作者: 胜利笔记本维修    时间: 2013-11-8 22:48
牛人  不错 不错
作者: jiajinfei    时间: 2013-11-8 23:12
看那些指令看的眼花缭乱,好像天书一样,没看懂,只看懂楼主编了个程序,制作了一个电路板,装好测试,波形正常,说明制作成功,不知我理解对否
作者: zxszmca    时间: 2013-11-8 23:59
现在手头有点紧,修本本赚点盘缠先,暂时没时间研究这么高深的东西,楼主厉害!!
作者: 蟒山    时间: 2013-11-9 20:57
我是两年前学的,到现在隔了两年没搞了,这段时间也在学维修笔记本。找算有机会自己开个店

补充内容 (2013-11-11 22:19):
可以呀,多多交流
作者: 蟒山    时间: 2013-11-9 20:59
发表于 2013-11-8 21:15:26 |只看该作者
闲得没事做得人,还不如再设计点火药什么什么得,哪样才有实用性
=============================
你说对的,当时的确很闲 。单片机很费时间的。
作者: YXCLG    时间: 2013-11-10 18:26
楼主牛B
作者: ywc403483752    时间: 2013-11-10 18:43
楼主太牛逼了
作者: erwin    时间: 2013-11-10 18:44
输出部分没有
作者: 神秘之心灵    时间: 2013-11-10 19:27
太有才了,但没什么价值

作者: 蟒山    时间: 2013-11-10 20:52

输出部分没有
================
明眼人,这个代码一看就没输出,我也是贴上代码后才发觉贴了另一个程序的代码,不好意思
作者: 蟒山    时间: 2013-11-10 20:54
贴上属于本身的代码
/*
此程序为红外遥控开关,可使用一般的家电遥控器进行控制,无须专门配置遥控器。按任一遥控器上的某一按键2~3秒即可将此键设置为开关键,
设置后每次按键,继电器执行相应的开关动作,对电灯进行控制。中途可改变遥控器或选用另外按键来进行开关,只须按另外键2~3秒设置即可。
在使用不同的晶振时,延时不一样,此代码使用的是8M晶振。
*/

#include "reg52.h"
#define uchar unsigned char
#define uint unsigned int
sbit hwx=P3^3;                      //中断1端口P3.3
sbit jdqkg=P3^6;                                                 //继电器控制端
uchar irdata[33],ircord[4],oldcord[4]={1,1,1,1};                  //irdata数组:地址码和指令码每位的存储数组,地址码16位,
                                                                                                  //指令码8位,指令码反码8位,共32位,引导码丢弃没用
                                                                                                //ircord数组:将地址码和指令码做转后存储为字节的数组,以便查询num数组里面的值
                                                                                                //oldcord数组:存入指定设置遥控器的地址码和遥控器上某一开关数据值
bit irok,reok;                                                 //irok将位数转为字节数后的标志位 ,reok是否有重复码产生而进行开关键重新设置标志位

void ex1ir() interrupt 2                  //中断1中断函数
{
        uchar i;
        uint tmp;
        PCON=0;                                                //有中断产生,中止节能模式,进入正常模式
        EX1=0;
        tmp=17;
        while(tmp) tmp--;                   //延时200微秒,消除干扰.使用8M晶振初值100延时1200微秒,初值17即可延时200微秒 。
                                                                // 此处只是相对uint数据类型,uchar类型计算出的延时初值会不一样。需在软件里面模拟测试
        if(hwx)                                           //判断是干扰还是数据,hwx为0表示数据,为1表示是干扰产生的中断
        {       
                EX1=1;
                return;
        }
        i=33;
        while(i)
        {       
                irdata[33-i]=0;
                while(!hwx)                  //低电平数据直接丢去,此处暂未加防干扰死循环
                {
                        ;
                }
               
                while(hwx)
                {
                        irdata[33-i]++;                               
                        tmp=5;
                        while(tmp) tmp--;                //加入延时初值5,否则数组值会被计满。延时60微秒 。更换晶振,此处做相应修改
                        if(irdata[33-i]==255) break;                //如果数组计满255,说明有干扰,退出死循环
                }
                i--;

        }
        while(!hwx);                   //丢弃有用数据之后的低电平
        i=0;
        while(hwx)                          //毛弃有用数据之后的高电平
        {
                tmp=50;
                while(tmp) tmp--;
                if(i>250) break;         //        防止死循环
                i++;
        }
        i=0;
        while(!hwx)                  //延时后看是否重复码产生
        {
                i++;
                tmp=9050;           //延时108.4毫秒初值9050  更换晶振,此处做相应修改
                while(tmp) tmp--;
                if(i>250) i=250;        //如果长时间按键不松,将变量值始终定为250,防止变量溢出
        }

        if((5<i)&&(i<50))
        {
                reok=1;                        //reok为是否有重复按键产生,当按键时间大于2~3秒后,程序会对所按的键设置为开关灯键
        }
        irok=1;
        EX1=1;

}


void irpro()
{
        uchar i,j,k,value;
        value=k=1;                          //此处需注意加赋值语句,不然第二次调用函数时,两个变量的初值有时不会是0,k=1数组从第二个开始,第一个为引导码,不用
        for(i=0;i<4;i++)          //共四个字节需要转
        {
                for(j=0;j<8;j++)   //每字节八位
                {
                        value=value>>1;
                         if(irdata[k]>10) value=value|0x80;        //更换晶振,此处比较值做相应修改       
                        k++;
                }
           ircord[i]=value;                 //将位转为字节后的数据存入ircord数组
           value=0;
        }
        if(reok)                                 //reok为1表示有重复码产生,要进行遥控器开关键设置
        {
                reok=0;
                for(i=0;i<4;i++)
                {
                        oldcord[i]=ircord[i]; //将新按键或遥控器值对oldcord进行更新,使新设置开关键生效
                }
        }
}

void main(void)
{
        EA=1;
        EX1=1;
        IT1=1;
        while(1)
        {
                if(irok)                //是否进行位数到字节的转换
                {
                        irok=0;
                        irpro();          
                }
                if(ircord[0]==oldcord[0])                        //地址码判断是否是同一遥控器的按键
                {
                        if(ircord[2]==oldcord[2])           //0、1元素为地址码,2元素为数据码,3元素为数据码反码        。此处判断是否是开关键被按下
                        {
                                ircord[2]=0;
                                jdqkg=~jdqkg;                         //取反,控制开和关
                        }
                }
                PCON=PCON|0x01;
        }
}
作者: 蟒山    时间: 2013-11-10 20:59
没想到贴子加精了,还送了好多下载分,早知道这样也可以送下载分,我就不拿RMB充值了。以后多发点,我还有好多原创的电路板和代码呢
作者: zimingjun520    时间: 2013-11-11 11:28
看得出楼主花了很大的心思修这板,花了更大的心思发帖,值得鼓励!表扬!
作者: chinayusanling    时间: 2013-11-11 12:19
单片机。。C   要很大毅力啊
作者: 蟒山    时间: 2013-11-11 12:58
主要还是要有兴趣。我是全凭兴趣才坚持了一年多,能做出板子出来写代码
作者: 安安国际    时间: 2013-11-11 17:05
       我彻底坐了次飞机了。一点不懂编程。请教下LZ。你懂单片机编程。还会制作电路板。按理应该去做硬件研发啊。为什么会上笔记本维修的论坛啊。难道你也是修笔记本的。那这也太强了吧。
作者: 蟒山    时间: 2013-11-11 17:54
看着专业,其实很业余。以前是兴趣,真去了做了研发后,不到一个星期就没干了,兴趣和职业完全不是一回事。现在做的工业也与电子完全无关,想学维修,主要是想转行开个店子。目前还是纠结中…………
作者: 蟒山    时间: 2013-11-11 17:54
感觉能修笔记本的很牛B
作者: erwin    时间: 2013-11-11 21:36
线路很精致,元件也整齐.
一个不明:二极管是防反向电源还是保护继电器?

作者: 蟒山    时间: 2013-11-11 22:07
发表于 2013-11-11 21:36:39 |只看该作者
线路很精致,元件也整齐.$ ~7 E; X% q9 q2 b0 L9 @9 j
一个不明:二极管是防反向电源还是保护继电器?; p,
==============================

防止继电器反向电流击穿三极管。
作者: 蟒山    时间: 2013-11-11 22:20

嗯,是这个意思
作者: 小刘师傅    时间: 2013-11-12 11:54
搞的是什么东西啊
作者: ︶ ̄微笑╮转身    时间: 2013-11-12 11:57
看不懂全是代码
作者: sk可人    时间: 2013-11-12 14:31
修单片机也很赚钱啊
作者: 蟒山    时间: 2013-11-12 14:54
sk可人 发表于 2013-11-12 14:31
修单片机也很赚钱啊

呵呵,请指点
作者: 新芯箱硬88    时间: 2013-11-13 10:39
我了个去   这也搞啊   你的时间可是真多啊!
作者: zhang98828    时间: 2013-11-13 11:03
蟒山 发表于 2013-11-9 20:57
我是两年前学的,到现在隔了两年没搞了,这段时间也在学维修笔记本。找算有机会自己开个店

补充内容 (2013 ...

大家交个朋友互相研究探讨本人QQ472552173
作者: 蟒山    时间: 2013-11-13 11:05
zhang98828 发表于 2013-11-13 11:03
大家交个朋友互相研究探讨本人QQ472552173

好的,加了
作者: 蟒山    时间: 2013-11-13 11:08
新芯箱硬88 发表于 2013-11-13 10:39
我了个去   这也搞啊   你的时间可是真多啊!

以前有时间的时候护的,现在没时间了,都两年没搞了
作者: qingyuyumeng    时间: 2013-11-13 14:44
毕业5年了  之前还高些玩玩 现在都没时间搞这个了  从专业出来了   我是没救了  加油了 哥们
作者: letstone    时间: 2013-11-13 15:33
LZ高手,以前想过用PIC16F630写,但红外载波这块做不好。
作者: 蟒山    时间: 2013-11-14 11:28
letstone 发表于 2013-11-13 15:33
LZ高手,以前想过用PIC16F630写,但红外载波这块做不好。

我只是接收,没做发射
作者: coal    时间: 2013-11-15 13:41
牛人啊,不管闲不闲,但是有技术就行
作者: WANGOUXUNWEI    时间: 2013-11-17 13:04
有才,佩服了
作者: S1念    时间: 2013-11-17 15:59
这些对我来说就是乱码
作者: 张强生    时间: 2013-11-19 11:44
哥!我很膜拜你啊!!牛不是吹的!
作者: wanqiang    时间: 2013-11-21 11:10
浪费时间啊?
作者: 唐某    时间: 2013-11-22 12:25
晕啊,佩服
作者: whty2010    时间: 2013-11-25 11:57
建议缩小体积,可以直接用STC15F104系列8脚的单片机或者STC新出的3-5v宽电压的单片机,供电可以直接用手机充电器的电路板改造直接供电,有能力的话最好用手机电池升压供电,用干电池消耗太大。
作者: 蟒山    时间: 2013-11-25 12:43
whty2010 发表于 2013-11-25 11:57
建议缩小体积,可以直接用STC15F104系列8脚的单片机或者STC新出的3-5v宽电压的单片机,供电可以直接用手机充 ...

非常好的建议,看来是个单片机高手
作者: huyx08    时间: 2013-11-29 10:56
值得鼓励!表扬!
作者: dskfie    时间: 2014-6-23 11:41
C语言,没学过单片机,能告诉我是怎么写到单片机里的吗!!!
作者: suminglunhui    时间: 2014-9-20 12:32
楼主太强大了,干嘛要来学电脑呀,浪费人才呀
作者: huaszo    时间: 2014-10-16 17:15
好好学习踏踏实实
作者: leeway123    时间: 2014-10-21 13:23
LZ牛人啊。坚持一年就有这成绩厉害
作者: 123迅维网    时间: 2014-11-14 12:36
看了这个遥控器制作好像有点麻烦
作者: benlynf    时间: 2015-2-1 23:13
请问一下 接受分析的是什么软件
作者: 低调哥    时间: 2015-3-26 16:13
好深奥  看不太懂
作者: nuoyanhi    时间: 2015-3-26 23:32
楼主的爱好好强大




欢迎光临 迅维网 (https://www.chinafix.com/) Powered by Discuz! X3.4