找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1825|回复: 4
打印 上一主题 下一主题
收起左侧

遥控器的故事

[复制链接]
跳转到指定楼层
楼主
ID:886808 发表于 2021-3-14 13:19 来自手机 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
对我们的51单片机而言,遥控多是通过红外实现,可是你想过几十年前单片机没普及时的情形吗?
当年我在林场工作,全场只有一部电话可以打外线长途,在场部。其余的分机打不了,我当时为了方便,设计制作了电话遥控器。在家里用分机拨我预先设定好的空位内线电话号,我的分机就自动接上外线可以打长途了。原理也很简单,就是做个全桥整流电路,经滤波后直接带动有多路触点向一继电器,把我的分机接在外线上,同时断开主机。只要通话,继电器自锁;电话挂机后继电装自动释放。这个方法我一直用到我家自己安装了长途电话为止。(当然也是我占了管理程控电话交换机的光,只是为了方便,少跑一趟不近的路。)
那年孩子上中学,为了方便我在学校附近租了间小房。天很冷,晚上看电视都趴在炕上。当时电视器基本没有遥控的,电视节目也只有一个地方台。怕冷,全家谁都不愿意出被窝关闭电视机。
我用阻容元件制作了一个定时器,假定1小时。上炕前启动,1小时后关机。开始挺好,可有一天电视节目没看完时间到关机了,惹爱人一顿唠叨。我重新设计,改成电视信号控制的。有电视信号就不关机,电视机没有信号延时一段时间关闭电视机。
可没多久问题又来了。一天,电视剧看完了,开始播放晚间新闻,电视机还哇哇响,又惹来爱人埋怨。
再改,这次我制作了光控的。没有遥控器,就直接用手电筒。按一下开机,再按一下关机。用了一段时间。
后来电视台增多了,不止一个台了。我又改成短按换台,长按关机的方式。
时我把我的做法写成文章投稿给《无线电》杂志。由于我前两次发表文章都特别简洁,稿费很少,这次有意写详细点。可稿子投出去很长时间不见发表。大约几个月后我在杂志上看到了类似文章发表了。
后来杂志又有了成品电视机红外遥控器套件出售,但价格不菲,当时安装下来要200多元,还得懂各种型号电视机线路原理,风险也高。
我的许多朋友要我给他们改装电视机遥控器,我先后为几十人安装。现在的人很难理解电视机没有遥控器的时代是怎样过来的。
几年前,我准备为老父90大寿制一台51单片机控制的简易小车机器人,用流行的寻迹小车改制。选用双驱动轮加导向的方式,因为可以原地360度转向。我的设想是,小车出发,语音播报活动开始。小车前进放下一只装有书写笔的杆,写出九十两个汉字。之后播放生日快乐,我的好父亲等歌曲,最后吹灭蜡烛。
我当时用的是红外遥控配合51单片机完成各项任务。当时除写字部分外其它功能都可用程序或遥控器完成。写字功能我没有用步进电机,只在轮子上安装了码盘计数,判断行走距离和转弯角度。实际试验时误差较大,每次都难一致。后来女儿看我天天在电脑上修改再试验,就跟我说:别弄了,那天是个隆重场合,万一你的设备出点故障就不好了。我听老父讲子个故事,说一次乾隆给位老者送了幅字,写了九十大寿,这位老者九十后就死了。
所以我从止罢休半途而废,我的眼睛就是当年盯电脑屏幕辛坏的。
照片是小车主板和能片断录放mp3的设备。主板的数码管可显示解码后的红外遥控各键码。
两张家人照是老父九十大寿全体及老父我的子女和孙辈。后我大病一场,5年大父也走了,今年是他两岁年。老父若在97了。
附51机红外线资料
//#################################################################################################
//文件:51单片机的红外遥控解码程序
//属性:使用外部中断0连接遥控头,接收红外遥控键值送P2口显示,12MHz外部晶振
//作者:新思科电子 2011-06
//资源:P3.2=接收头输入,P2=8LED
//#################################################################################################
#include"reg52.h"

#define uint unsigned int
#define uchar unsigned char

uchar led=0x00;

void io_init(void);
void int_init(void);

void main(void)
{
        io_init();
        int_init();
        while(1);
}

void io_init(void)
{
        P0=0xff;
        P1=0xff;
        P2=0xff;
        P3=0xff;
}

void int_init(void)
{
        EX0=1;
        EA=1;
}

void interrupt0()interrupt 0
{
        uchar i=0,j=0,k=0,us=0;
        uchar addr[4]={0};

        EX0=0;

        for(i=0;i<255;i++)  //9ms内有高电平认为是干扰
        {
                if(P3&0x04)            //255的值实际时间为800us
                {
                        EX0=1;
                        return;
                }
        }
        while(!(P3&0x04));        //等待9ms低电平过去
           for(i=0;i<4;i++)
        {
                for(j=0;j<8;j++)
                {
                        while(P3&0x04);        //等待4.5ms高电平过去        
                        while(!(P3&0x04));        //等待0.56ms低电平后面的高电平
                        while(P3&0x04)                //计算这个高电平的时间
                        {
                                for(us=0;us<=32;us++);        //100us的延时语句
                                if((k++)>=30)                //高电平时间过长退出程序
                                {
                                        EX0=1;
                                        return;

                                }
                        }
                        addr[ i]=addr[ i]>>1;        //接收一位数据
                        if(k>=8)
                                addr[ i]=addr[ i]|0x80;        //高电平大于0.56ms,则为1
                        k=0;
                }
        }        

        P2=~(addr[2]);         //P2的LED显示二进制键值

        EX0=1;         
}           
红外解码教程
红外遥控系统一般分发射和接收两个部分
      发射部分的主要元件为红外发光二极管。目前大量使用的红外发光二极管发出的红外线波长为940mm左右,外形与普通φ5发光二极管相同。
      接收部分的红外接收管是一种光敏二极管。红外发光二极管一般有圆形和方形两种。由于红外发光二极管的发射功率一般都较小(100mW左右),所以红外接收二极管接收到的信号比较微弱,因此就要增加高增益放大电路。最近几年大多都采用成品红外接收头。
      成品红外接收头的封装大致有两种:一种采用铁皮屏蔽;一种是塑料封装。均有三只引脚,即电源正(VDD)、电源负(GND)和数据输出(VO或OUT)。红外接收头的引脚排列因型号不同而不尽相同,可参考厂家的使用说明。成品红外接收头的优点是不需要复杂的调试和外壳屏蔽,使用起来如同一只三极管,非常方便。但在使用时注意成品红外接收头的载波频率。红外遥控常用的载波频率为38kHz,这是由发射端所使用455kHz晶振来决定的。在发射端要对晶振进行整数分频,分频系数一般取12,所以455kHz÷12≈37.9kHz≈38kHz。也有一些遥控系统采用36 kHz、40 kHz、56 kHz等,由发射端晶振的振荡频率来决定。
      红外遥控的特点是不影响周边环境的、不干扰其他电器设备。室内近距离(小于10米)遥控中得到了广泛的应用。
        红外遥控在生产和生活中应用越来越广泛,不同的红外遥控芯片有不同的发码协议,但一般都是由引导码,系统码,键码三部分组成.
        引导码是告诉接收机准备接收红外遥控码.系统码是识别码,不同的遥控芯片有不同的识别码,以免搞错.
        遥控器上不同的按键有不同的键码,系统码和键码都是16位码,8位正码,8位反码.如SC6122的系统码是FF00,FF和00互为反码,键码1为EF10也是互为反码.
        SC6122的引导码为低电平为9000微秒,高电平为4500微秒.当然高电平不可能精确为9000微秒,在8000微秒到10000微秒都看作是正常范围,低电平在4000-5000之间都看作是正常范围.引导码后的32位编码(16位系统码和16位键码)不管高低电平,载波时间都是560微秒,但低电平持续时间是1125微秒,高电平持续时间是2250微秒,所以低电平除去载波时间大约是560微秒,高电平除去载波时间大约是1680微秒.低电平也有一个波动范围,在400-700之间都看作是正常的,具体多少可以通过示波器测量出来.高电平也有一个波动范围,在400-2000之间都看作是正常的,具体多少也是根据经验.当然范围越宽,捕捉红外线的范围也越宽,越精确.在捕捉到有高低电平之间,在560-1680之间取一个中间值1120微秒,认为小于1120微秒是低电平,大于1120微秒是高电平.

以下程序能在LCD上显示系统码和键码,按不同的按键,系统码不变,变的是键码.

#include <reg52.h>

#define c(x) (x*110592/120000)

sbit Ir_Pin=P3^3;

unsigned char code Led_Tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,
0xf8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};   //共阳极数码显示码0-F.
unsigned char code Led_Sel[]={0xe,0xd,0xb,0x7};

unsigned char Led_Buf[4]; //显示缓冲区
char Led_Index;           //位选         

unsigned char Ir_Buf[4];  //用于保存解码结果

//==============================================================
timer0() interrupt 1 using 1        //数码管扫描
{
        TL0=65536-1000;
        TH0=(65536-1000)/256;   //定时器0设定约1000us中断一次,用于数码管扫描
        P0=0xff;
        P2=Led_Sel[Led_Index];          //位选
        P0=Led_Tab[Led_Buf[Led_Index]]; //段选
        if(++Led_Index>3) Led_Index=0;  //四个扫描完了,到第一个数码管
}
//==============================================================
unsigned int Ir_Get_Low()
{
        TL1=0;
        TH1=0;
        TR1=1;
        while(!Ir_Pin && (TH1&0x80)==0);               
        TR1=0;           
        return TH1*256+TL1;
}
//=============================================================
unsigned int Ir_Get_High()
{
        TL1=0;
        TH1=0;
        TR1=1;
        while(Ir_Pin && (TH1&0x80)==0);
        TR1=0;
        return TH1*256+TL1;
}
//==============================================================
main()
{
        unsigned int temp;
        char i,j;
        Led_Index=1;

        TMOD=0x11;
        TL0=65536-1000;
        TH0=(65536-1000)/256; //定时器0设定约1000us中断一次,用于数码管扫描
        EA=1;
        ET0=1;
        TR0=1;

        Led_Buf[0]=0;
        Led_Buf[1]=0;
        Led_Buf[2]=0;
        Led_Buf[3]=0; //显示区设成0

        do
        {
                restart:
                while(Ir_Pin);
                temp=Ir_Get_Low();
                if(temp<c(8500) || temp>c(9500)) continue;//引导脉冲低电平9000
                temp=Ir_Get_High();
                if(temp<c(4000) || temp>c(5000)) continue;//引导脉冲高电平4500
                for(i=0;i<4;i++)         //4个字节
                        for(j=0;j<8;j++)         //每个字节8位
                        {
                                temp=Ir_Get_Low();
                                if(temp<c(200) || temp>c(800)) goto restart;
                                temp=Ir_Get_High();
                                if(temp<c(200) || temp>c(2000)) goto restart;
                                Ir_Buf[ i]>>=1;
                                if(temp>c(1120)) Ir_Buf[ i]|=0x80;
                        }
                Led_Buf[0]=Ir_Buf[2]&0xf;
                Led_Buf[1]=(Ir_Buf[2]/16)&0xf;
                Led_Buf[2]=Ir_Buf[3]&0xf;
                Led_Buf[3]=(Ir_Buf[3]/16)&0xf; //显示结果
        }
        while(1);
}
另一份红外线解码教程:
红外遥控系统一般分发射和接收两个部分
      发射部分的主要元件为红外发光二极管。目前大量使用的红外发光二极管发出的红外线波长为940mm左右,外形与普通φ5发光二极管相同。
      接收部分的红外接收管是一种光敏二极管。红外发光二极管一般有圆形和方形两种。由于红外发光二极管的发射功率一般都较小(100mW左右),所以红外接收二极管接收到的信号比较微弱,因此就要增加高增益放大电路。最近几年大多都采用成品红外接收头。
      成品红外接收头的封装大致有两种:一种采用铁皮屏蔽;一种是塑料封装。均有三只引脚,即电源正(VDD)、电源负(GND)和数据输出(VO或OUT)。红外接收头的引脚排列因型号不同而不尽相同,可参考厂家的使用说明。成品红外接收头的优点是不需要复杂的调试和外壳屏蔽,使用起来如同一只三极管,非常方便。但在使用时注意成品红外接收头的载波频率。红外遥控常用的载波频率为38kHz,这是由发射端所使用455kHz晶振来决定的。在发射端要对晶振进行整数分频,分频系数一般取12,所以455kHz÷12≈37.9kHz≈38kHz。也有一些遥控系统采用36 kHz、40 kHz、56 kHz等,由发射端晶振的振荡频率来决定。
      红外遥控的特点是不影响周边环境的、不干扰其他电器设备。室内近距离(小于10米)遥控中得到了广泛的应用。
        红外遥控在生产和生活中应用越来越广泛,不同的红外遥控芯片有不同的发码协议,但一般都是由引导码,系统码,键码三部分组成.
        引导码是告诉接收机准备接收红外遥控码.系统码是识别码,不同的遥控芯片有不同的识别码,以免搞错.
        遥控器上不同的按键有不同的键码,系统码和键码都是16位码,8位正码,8位反码.如SC6122的系统码是FF00,FF和00互为反码,键码1为EF10也是互为反码.
        SC6122的引导码为低电平为9000微秒,高电平为4500微秒.当然高电平不可能精确为9000微秒,在8000微秒到10000微秒都看作是正常范围,低电平在4000-5000之间都看作是正常范围.引导码后的32位编码(16位系统码和16位键码)不管高低电平,载波时间都是560微秒,但低电平持续时间是1125微秒,高电平持续时间是2250微秒,所以低电平除去载波时间大约是560微秒,高电平除去载波时间大约是1680微秒.低电平也有一个波动范围,在400-700之间都看作是正常的,具体多少可以通过示波器测量出来.高电平也有一个波动范围,在400-2000之间都看作是正常的,具体多少也是根据经验.当然范围越宽,捕捉红外线的范围也越宽,越精确.在捕捉到有高低电平之间,在560-1680之间取一个中间值1120微秒,认为小于1120微秒是低电平,大于1120微秒是高电平.

以下程序能在LCD上显示系统码和键码,按不同的按键,系统码不变,变的是键码.

#include <reg52.h>

#define c(x) (x*110592/120000)

sbit Ir_Pin=P3^3;

unsigned char code Led_Tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,
0xf8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E};   //共阳极数码显示码0-F.
unsigned char code Led_Sel[]={0xe,0xd,0xb,0x7};

unsigned char Led_Buf[4]; //显示缓冲区
char Led_Index;           //位选         

unsigned char Ir_Buf[4];  //用于保存解码结果

//==============================================================
timer0() interrupt 1 using 1        //数码管扫描
{
        TL0=65536-1000;
        TH0=(65536-1000)/256;   //定时器0设定约1000us中断一次,用于数码管扫描
        P0=0xff;
        P2=Led_Sel[Led_Index];          //位选
        P0=Led_Tab[Led_Buf[Led_Index]]; //段选
        if(++Led_Index>3) Led_Index=0;  //四个扫描完了,到第一个数码管
}
//==============================================================
unsigned int Ir_Get_Low()
{
        TL1=0;
        TH1=0;
        TR1=1;
        while(!Ir_Pin && (TH1&0x80)==0);               
        TR1=0;           
        return TH1*256+TL1;
}
//=============================================================
unsigned int Ir_Get_High()
{
        TL1=0;
        TH1=0;
        TR1=1;
        while(Ir_Pin && (TH1&0x80)==0);
        TR1=0;
        return TH1*256+TL1;
}
//==============================================================
main()
{
        unsigned int temp;
        char i,j;
        Led_Index=1;

        TMOD=0x11;
        TL0=65536-1000;
        TH0=(65536-1000)/256; //定时器0设定约1000us中断一次,用于数码管扫描
        EA=1;
        ET0=1;
        TR0=1;

        Led_Buf[0]=0;
        Led_Buf[1]=0;
        Led_Buf[2]=0;
        Led_Buf[3]=0; //显示区设成0

        do
        {
                restart:
                while(Ir_Pin);
                temp=Ir_Get_Low();
                if(temp<c(8500) || temp>c(9500)) continue;//引导脉冲低电平9000
                temp=Ir_Get_High();
                if(temp<c(4000) || temp>c(5000)) continue;//引导脉冲高电平4500
                for(i=0;i<4;i++)         //4个字节
                        for(j=0;j<8;j++)         //每个字节8位
                        {
                                temp=Ir_Get_Low();
                                if(temp<c(200) || temp>c(800)) goto restart;
                                temp=Ir_Get_High();
                                if(temp<c(200) || temp>c(2000)) goto restart;
                                Ir_Buf[ i]>>=1;
                                if(temp>c(1120)) Ir_Buf[ i]|=0x80;
                        }
                Led_Buf[0]=Ir_Buf[2]&0xf;
                Led_Buf[1]=(Ir_Buf[2]/16)&0xf;
                Led_Buf[2]=Ir_Buf[3]&0xf;
                Led_Buf[3]=(Ir_Buf[3]/16)&0xf; //显示结果
        }
        while(1);
}

IMG_20210314_102723.jpg (1010.01 KB, 下载次数: 67)

IMG_20210314_102723.jpg

IMG_20210314_102715.jpg (683.99 KB, 下载次数: 67)

IMG_20210314_102715.jpg

mmexport1538354052465.jpg (668.15 KB, 下载次数: 61)

mmexport1538354052465.jpg

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:886808 发表于 2021-3-15 09:34 来自手机 | 只看该作者
这才是当时小车拼制主板,上有播放用的扬声器等
回复

使用道具 举报

板凳
ID:886808 发表于 2021-3-15 09:39 来自手机 | 只看该作者
这才是当时的小车主板,原来照片是寻迹后改实验江外解码用。这个上面有扬声器和机械传动装置。

IMG_20210315_084739.jpg (948.98 KB, 下载次数: 67)

IMG_20210315_084739.jpg
回复

使用道具 举报

地板
ID:886808 发表于 2021-3-15 09:42 来自手机 | 只看该作者
dlkfqlxm 发表于 2021-3-15 09:34
这才是当时小车拼制主板,上有播放用的扬声器等

照片发不上?

IMG_20210315_084739.jpg (948.98 KB, 下载次数: 62)

IMG_20210315_084739.jpg
回复

使用道具 举报

5#
ID:639666 发表于 2022-10-11 08:04 | 只看该作者
dlkfqlxm 发表于 2021-3-15 09:39
这才是当时的小车主板,原来照片是寻迹后改实验江外解码用。这个上面有扬声器和机械传动装置。

老师你好,以前在杂志上看过你的文章,很想跟你联系
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表