欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

基于STC8的红外遥控灯

程序员文章站 2022-06-17 19:05:58
这个东西吧,就是单片机红外解码,然后控制继电器吸合从而控制灯产品,其实挺简单的,我都在犹豫要不要发出来,想了想还是发上来吧,毕竟还是很实用的(我一直在用,因为床头没开关,这样随手遥控开关灯还是很方便的)。其实遥控方式多种多样,蓝牙,WIFI,RF433,ZigBee,红外等等。考虑到实用,以及成本等各种因素,最终选择了红外遥控。因为不管是蓝牙,WIFI,RF433还是ZigBee,都需要手机遥控或者单独做一个遥控器,比如用蓝牙或者WIFI的时候,着急开灯,还得找到手机,解锁手机,打开APP,...

这个东西吧,就是单片机红外解码,然后控制继电器吸合从而控制灯产品,其实挺简单的,

我都在犹豫要不要发出来,想了想还是发上来吧,毕竟还是很实用的(我一直在用,因为床头没开关,这样随手遥控开关灯还是很方便的)。

其实遥控方式多种多样,蓝牙,WIFI,RF433,ZigBee,红外等等。

考虑到实用,以及成本等各种因素,最终选择了红外遥控。

因为不管是蓝牙,WIFI,RF433还是ZigBee,都需要手机遥控或者单独做一个遥控器,比如用蓝牙或者WIFI的时候,着急开灯,还得找到手机,解锁手机,打开APP,连接上设备,开灯。。。

太繁琐了,RF433和ZigBee呢则需要专门的遥控器,成本高,待机时间也不一定长。

红外则简单多了,这种遥控器简单又实惠,学单片机的几乎人人都有,对于开关灯这种只需要几个信号的设计来说是最好不过的了

基于STC8的红外遥控灯

同样接收电路也是相当的简单,一个接收头就搞定了。

基于STC8的红外遥控灯

选定了方案,接下来就是单片机了,这个设计太简单了,性能方面是没要求的,直接考虑最便宜又小巧的芯片。

说到价格和体积小巧,首先想到的就是STC8,STM8S003F3还有它的新唐替代品N76E003。

合计了一下还是选择STC8F2K08S2了,毕竟51太熟悉了,工程也简单。

然后就是代码,红外解析,串口打印,确保解码正确。。。

/********************************************************************************
*  描述:                                                                       *
*         遥控器接p3.2                                             *
                                                                    *
*******************************************************************************/
#include <reg51.h>
#include <intrins.h>
#define PD              0x02                    //PCON.1
sbit IRIN = P3 ^ 2;       //红外接收器数据线
//sbit RELAY= P1^4;         //继电器驱动线
//sbit BEEP = P1^5;         //蜂鸣器驱动线
sbit lr = P1 ^ 1;       //红外接收器数据线
sbit lr1 = P1 ^ 2;       //红外接收器数据线
extern char flag;
void IRdelay(char x);  //x*0.14MS
//void beep();

unsigned char  IRCOM[7];
//extern unsigned char Y0;
//extern  char busy;
/*******************************************************************/
void IRInit()
{
    IT0 = 1;                                    //使能INT1下降沿中断
    EX0 = 1;                                    //使能INT1中断
    //    IE |= 0x81;                 //允许总中断中断,使能 INT0 外部中断
    //    TCON |= 0x01;               //触发方式为脉冲负边沿触发

    IRIN = 1;                  //I/O口初始化
    //    RELAY=1;
}

/**********************************************************/
void IR_IN(void) interrupt 0
{
    unsigned char j, k, N = 0;
    EX0 = 0;
    IRdelay(15);
    if (IRIN == 1)
    {
        EX0 = 1;
        return;
    }
    //确认IR信号出现
    while (!IRIN)            //等IR变为高电平,跳过9ms的前导低电平信号。
    {
        IRdelay(1);
    }

    for (j = 0; j < 4; j++)   //收集四组数据
    {
        for (k = 0; k < 8; k++)  //每组数据有8位
        {
            while (IRIN)            //等 IR 变为低电平,跳过4.5ms的前导高电平信号。
            {
                IRdelay(1);
            }
            while (!IRIN)          //等 IR 变为高电平
            {
                IRdelay(1);
            }
            while (IRIN)           //计算IR高电平时长
            {
                IRdelay(1);
                N++;
                if (N >= 30)
                {
                    EX0 = 1;
                    return;
                }                  //0.14ms计数过长自动离开。
            }                        //高电平计数完毕
            IRCOM[j] = IRCOM[j] >> 1;                //数据最高位补“0”
            if (N >= 8)
            {
                IRCOM[j] = IRCOM[j] | 0x80;   //数据最高位补“1”
            }
            N = 0;
        }
    }

    if (IRCOM[2] != ~IRCOM[3])
    {
        EX0 = 1;
        return;
    }

    IRCOM[5] = IRCOM[2] & 0x0F;   //取键码的低四位
    IRCOM[6] = IRCOM[2] >> 4;     //右移4次,高四位变为低四位

    if(IRCOM[5] > 9)
    {
        IRCOM[5] = IRCOM[5] + 0x37;
    }
    else
        IRCOM[5] = IRCOM[5] + 0x30;

    if(IRCOM[6] > 9)
    {
        IRCOM[6] = IRCOM[6] + 0x37;
    }
    else
        IRCOM[6] = IRCOM[6] + 0x30;

    /*
    ;================================
    ;******  红外遥控器键值表  ******

    ;  4c     0e      4d      0d
    ;  0f     4f      4e      0c
    ;  0b     4b      4a      08
    ;  48     12      16      4C
    ;  40     48      04      00
    ;  02     05      54      4D
    ;  0A     1E      0E      1A
    ;  1C     14      0F      0C



    	 0x45		0x46		0x47

    	 0x44		0x40		0x43

    	 0x07		0x15		0x09

    	 0x16		0x19		0x0d

    	 0x0c		0x18		0x5e

    	 0x08		0x1c		0x5a

    	 0x42		0x52		0x4a
    ;================================  */
    //SBUF=IRCOM[2];
    switch(IRCOM[2])
    {
    case 0x45:
    //	   case 0x46:
    //	   case 0x47: lr=1;lr1=1;flag=1; break;

    case 0x44:
    case 0x07: //lr=1;lr1=1;flag=1; break;
    case 0x16:
        if(flag == 1)
        {
            lr = 0;
            lr1 = 0;
            flag = 0;
        }
        else
        {
            lr = 1;
            lr1 = 1;
            flag = 1;
        }
        break;
    default:
        lr = 0;
        lr1 = 0;
        flag = 0;

    }
    EX0 = 1;
    _nop_();
    _nop_();
    //    PCON = IDL;                                 //MCU进入IDLE模式
    PCON = PD;                                  //MCU进入掉电模式
    _nop_();
    _nop_();
}


/**********************************************************/
void IRdelay(unsigned char x)    //x*0.14MS
{
    unsigned char i;
    while(x--)
    {
        for (i = 0; i < 100; i++) {}
    }
}

然后就是去掉串口程序(不去也没事儿,考虑到没啥用处了,本着低功耗原则就去掉了)加上继电器,指示灯(继电器吸合时,指示灯熄灭,继电器断开时,指示灯点亮),进行吸合判断,进入低功耗。。。

/********************************************************************************
*  描述:                                                                       *
*         遥控器接p3.2                                             *
*         LED接p1.1  继电器接p1.2                                             *
*                                                                              *
*******************************************************************************/
#include <reg51.h>
#include <intrins.h>
#define  NOP() _nop_()  /* 定义空指令 */

sfr     VOCTRL      =   0xbb;
#define IDL             0x01                    //PCON.0
#define PD              0x02                    //PCON.1

//测试工作频率为6MHz

sfr     T2L         =   0xd7;
sfr     T2H         =   0xd6;
sfr     AUXR        =   0x8e;
sfr     P1M0        =   0x92;
sfr     P1M1        =   0x91;
sbit lr = P1 ^ 1;       //红外接收器数据线
sbit lr1 = P1 ^ 2;       //红外接收器数据线
sbit key = P3 ^ 3;       //红外接收器数据线

char flag = 0;


extern void IRdelay(unsigned char x);      //函数声名
extern void IRInit();    //extern 是引用IR.C中的函数



void IR_IN1(void) interrupt 2
{
    IRdelay(10);
    if(key == 0)
    {
        if(flag)
        {
            lr = 0;
            lr1 = 0;
            flag = 0;
        }
        else
        {
            lr = 1;
            lr1 = 1;
            flag = 1;
        }
    }
    while(key == 0);
}

main()
{
    lr = 0;
    lr1 = 0;
    VOCTRL = 0x00;                              //掉电模式时使用内部SCC模块,功耗约1.5uA
    //  VOCTRL = 0x80;                              //掉电模式时使用外部SCC模块,功耗约0.15u
    IRInit();
    P1M0 = 0xff;                                //设置P1.0~P1.7为推挽输出模式
    P1M1 = 0x00;
    IT1 = 1;                                    //使能INT1下降沿中断
    EX1 = 1;                                    //使能INT1中断
    key = 1;
    EA = 1;
    lr = 0;
    lr1 = 0;
    while(1)
    {

        _nop_();
        _nop_();
        //    PCON = IDL;                                 //MCU进入IDLE模式
        PCON = PD;                                  //MCU进入掉电模式
        _nop_();
        _nop_();

    }


}

就这么简单,完事儿啦,接着进行画PCB,集成化,小型化

因为涉及到220V家庭用电,所以还得考虑安全性,于是使用了集成封装的220转5V电源模块,继电器使用的是10A 250VAC   SRD-05VDC

基于STC8的红外遥控灯

焊接好实物图如下

基于STC8的红外遥控灯

基于STC8的红外遥控灯

测试功能没问题,由于程序功能简单,使用STC8的内部IRC晶振频率6MHz,如果使用其他频率,修改红外时序IRdelay()函数里的延时即可。

下载地址https://download.csdn.net/download/qq_22848695/13107865

最后提醒:由于涉及到220V家庭用电,请一定一定要小心,万不可大意。

 

本文地址:https://blog.csdn.net/qq_22848695/article/details/109643091

相关标签: 单片机