找回密码
 立即注册
查看: 643|回复: 8

用8G1K08做的红外感应开关,感应距离30厘米,下面的程序和电路看看合适

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2024-12-06 08:15:07
已绑定手机

12

主题

22

回帖

129

积分

注册会员

积分
129
发表于 2024-11-4 14:12:29 | 显示全部楼层 |阅读模式
本帖最后由 DebugLab 于 2024-11-4 14:24 编辑

截图202411041410081820.jpg


#include"stc8.h"
#include"intrins.h"//使用nop()函数需引用此文件

typedef unsigned char    uint8_t;
typedef unsigned int     uint16_t;
typedef unsigned long    uint32_t;

//280us @11.0592MHz

                    TH1 = 0xF3; \
                    ET1 = 1; \
                                TR1 = 1
void Timer1_Init(void)                //280微秒@11.0592MHz
{
        AUXR |= 0x40;                        //定时器时钟1T模式
        TMOD &= 0x0F;                        //设置定时器模式
        TL1 = 0xE7;                                //设置定时初始值
        TH1 = 0xF3;                                //设置定时初始值
        TF1 = 0;                                //清除TF1标志
        TR1 = 1;                                //定时器1开始计时
}




//引脚定义
sbit LED=P5^4;                //指示灯
sbit IR_IO=P5^5;    //红外发射
sbit KEY=P3^0;        //按键
sbit JS_OUT=P3^1;        //红外接收
sbit OUT1=P3^2;        //数据输出1
sbit OUT2=P3^3;        //数据输出2
//数据定义
bit IR_Flag=0;                //红外数据接收完成标志位
u8 IR_time=0;                //下降沿之间的时间计数值
u8 IR_data[9];                //引导码+8个位数据各自占用的时间
bit IR_TimeFlag;            //红外发射延时到标志
unsigned char count;        //280us

static u8 IR_bit;                        //变量IR_bit用于指示红外数据的位数
//函数声明
void delay(u16 count);                //延时函数声明
void Time0_init(void);                //定时计数器0初始化函数
void Time1_init(void);                //定时计数器1初始化函数
void Int0_init(void);                //外部中断0初始化函数
u8 IR_decode(void);                        //红外解码函数


void Delay13us(void)        //@11.0592MHz  //13us延时,38KHZ载波频率,占空比50% 1/38K=26.3us
{
        unsigned char data i;

        i = 46;
        while (--i);
}





void send_Ir(unsigned int i)  //发送高电平//38Khz载波发射,发射i个周期
{
         while(i--)
         {
    IR_EN=1;  //1个载波信号 1个周期  50%的38KHZ  时间26.3us
         Delay13us();
         IR_EN=0;
         Delay13us();}
}
void no_send_Ir(unsigned int i)  //发送低电平   ,不发射载波
         {
         while(i--)
         {
   
         IR_EN=0;
         Delay13us();
                 Delay13us();
         }
}




void send_rc5_0(void)
{
        send_Ir(14);
no_send_Ir(14);
        
}
void send_rc5_1(void)
{
        send_Ir(15);
no_send_Ir(15);
        
}






        
        --------------主函数----------------------------
void main(void)
{
        u8 num=0;                        
        //STC8G系列单片机除P3.0和P3.1外,所有I/O上电均为高阻输入状态,需先配置再使用
        P3M0 &= ~0x0f;
  P3M1 &= ~0x0f; //P3.0-3.3引脚为准双向口模式
        P5M0 |=0x30;                //P5.4引脚为推挽输出模式
        P5M1 &= ~0x30;                //P5.5引脚为推挽输出模式
           
        
        
        Time0_init();                //定时计数器0初始化函数
        Time1_init();                //定时计数器1初始化函数
        Int0_init();                //外部中断0初始化函数
        EA = 1;                                //开中断
        delay(100);                        //等待配置稳定

        IR_IO = 1;                         //红外发射置高
        while(1)
        {
                Send_IR(IR_SENDDATA);        //红外发送数据
                delay(20000);        
                  
                if(IR_Flag=JS OUT)                                //红外数据接收完成
                {
                        IR_Flag=0;                        
                        if(IR_decode() == IR_SENDDATA) LED = ~LED;//红外接收正确改变指示灯状态
                }
               
                OUT1=1;
                OUT2=2;
        }
}
//-------------------------延时函数----------------------------
void delay(u16 count)
{
        while(count--)
        {
                _nop_();
        }
}
//-------------------------定时器0初始化----------------------------
void Time0_init(void)        //139微秒@11.0592MHz
{
        AUXR &= 0x7F;        //定时器时钟12T模式,工作方式2
        TMOD &= 0xF0;        
        TMOD |= 0x02;        
        TL0 = 0x80;               
        TH0 = 0x80;               
        TF0 = 0;                //清除标志
        ET0 = 1;                //使能T0中断
        TR0 = 1;                //启动T0
}
//-------------------------定时器1初始化---------------------------
void Time1_init(void)        //278微秒@11.0592MHz
{
    AUXR |= 0x40;//模式2 1T
    TMOD &= 0x0F;
}
//-------------------------外部中断0初始化-------------------------
void Int0_init(void)
{
        IT0 = 1;        //触发方式为下降沿触发
        EX0 = 1;        //使能INT0中断
}
//-------------------------红外接收解码-------------------------
u8 IR_decode(void)
{
        u8 j,k;                                                               
        u8 IR_Value = 0;
        k=1;                                                        //先让变量k等于1,因为k为0时取出的将会是“引导码的时间间隔”

        for(j=0;j<=7;j++)                                //内层循环8次为了拼合8个数据位为1个字节
        {
                if(IR_data[k]>5)                        //若“时间间隔”比5大那肯定是“1码”反之为“0码”
                        IR_Value|=0x80;                        //通过按位或运算高位填1
                if(j<7)                                                //若数据没有拼合完8次
                        IR_Value>>=1;                        //通过右移运算“腾出”位置准备下一位判定
                k++;                                                //下标变量自增
        }
        return IR_Value;                                //返回红外接收的数据
}
//-------------------------外部中断0服务函数-------------------------
void INT0_ISR() interrupt 0
{
        if(IR_time>8)        //判断引导码(0.56ms+1.12ms)
                IR_bit=0;        //清除位数变量,确保当前IR_bit为0,表示引导码
        IR_data[IR_bit]=IR_time;                //存储相应位时间宽度
        IR_time=0;                                                //清零时间宽度计数值
        IR_bit++;                                                //位数变量自增
        if(IR_bit==9)                                        //如果达到了9位(引导码+8个数据位)
        {
                IR_Flag=1;                                        //红外数据接收完成标志位置1
                IR_bit=0;                                        //位数变量清零
        }
}
//-------------------------定时器0中断服务函数-------------------------
void TIMER0_ISR() interrupt 1
{
        IR_time++;
}
//-------------------------定时器1中断服务函数-------------------------
void TIMER1_ISR() interrupt 3
{
        count--;
        if(count == 0)
        {
                IR_TimeFlag = 1;
                ET1 = 1;//
        }
}



截图202411041410191914.jpg
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:468
  • 最近打卡:2025-06-17 06:26:47
已绑定手机

19

主题

3231

回帖

5285

积分

论坛元老

积分
5285
发表于 2024-11-4 14:17:49 来自手机 | 显示全部楼层
接收电路不完整吧
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:469
  • 最近打卡:2025-06-17 09:09:48
已绑定手机

79

主题

5137

回帖

9134

积分

超级版主

DebugLab

积分
9134
发表于 2024-11-4 14:28:06 | 显示全部楼层
红外反射到不了30cm,也就10~15cm
DebugLab
回复 支持 反对

使用道具 举报 送花

1

主题

12

回帖

51

积分

注册会员

积分
51
发表于 2024-11-4 15:28:29 来自手机 | 显示全部楼层
就是时间太长了
回复 支持 反对

使用道具 举报 送花

1

主题

12

回帖

51

积分

注册会员

积分
51
发表于 2024-11-4 16:19:38 来自手机 | 显示全部楼层
soma 发表于 2024-11-4 14:17
接收电路不完整吧

keil5老是有点问题,能帮忙看一下吗
回复 支持 反对

使用道具 举报 送花

1

主题

12

回帖

51

积分

注册会员

积分
51
发表于 2024-11-4 16:20:36 来自手机 | 显示全部楼层
接收输出只要一个高电平和低电平
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:409
  • 最近打卡:2025-06-17 00:48:11

8

主题

353

回帖

2476

积分

金牌会员

积分
2476
发表于 2024-11-4 16:41:11 | 显示全部楼层
用红外遥控接收头来做检测,太过灵敏,收发发射管都要套长套管增加指向性,并且使用编码验证抑制干扰
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2024-12-06 08:15:07
已绑定手机

12

主题

22

回帖

129

积分

注册会员

积分
129
发表于 2024-11-4 19:50:43 | 显示全部楼层
客户要求的
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:3
  • 最近打卡:2024-12-06 08:15:07
已绑定手机

12

主题

22

回帖

129

积分

注册会员

积分
129
发表于 2024-11-4 19:51:37 | 显示全部楼层
是有一个隔离导管
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-6-18 00:17 , Processed in 0.192881 second(s), 96 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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