找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2101|回复: 12
收起左侧

单片机红外反射开关程序问题求助

  [复制链接]
ID:140489 发表于 2019-9-26 10:31 | 显示全部楼层 |阅读模式
//红外反射开关,接收头HS0038B,发射管用pnp三极管驱动
//第一次上电,灯亮1秒后熄灭,
//手挡一次开,再挡一次关,如此循环
//实验板测试手挡一次开,再挡一次关 开关正常;
//但是有一个问题,如果手一直挡在前面,LED会不停的亮--灭        -- 亮--灭
//请大神们看下,怎样才能做到手挡在前面不移开,保持一种状态
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint  unsigned int

sbit ir=P2^4;    //红外发射
sbit ir_in=P3^2; //红外接收
sbit led=P1^1;        //

uint cont,cont1;
bit flag_key;         //按键按下标志
bit key_lock=0;


void delay(uint z)           //ms
{
        uint x,y;
        for(x=z; x>0; x--)
                for(y=114; y>0; y--);
}


void fa_38k()          //38k 载波                         //接收头前面有滤光片,发射管要用黑色热缩套管套起来
{                                  //不是很准,没有逻辑分析仪,搞不准,现在的反射距离在60厘米左右(发射管串100欧电阻)
        ir=0;                  
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();

        ir=1;
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
        _nop_();//_nop_();
}

void main()
{
        TMOD |= 0X01;                          //T0定时器,模式1, 16位计数
        TH0 = (65536-1000)/256;  //1ms初值 @12MHz晶振
        TL0 = (65536-1000)%256;


        ET0=1;
        TR0=1;
        led=0;
        delay(500);
        led=1;
        while(1)
        {
                if(flag==0 )
                {
                        fa_38k();  //发38K
                }
                else ir=1;           //停止发射






        if(ir_in==0)          //手挡住
        {
                flag_key=1;
                cont1++;
                key_lock=1;        
        }
        else flag_key=0; //手移开
        
        if(flag_key==1 && cont1==100)
        {         
                  ir=1;
                 cont1=0;
                 led = !led;
                 delay(1000);

        }

        
        if(ir_in==1) cont1=0;        //这句抗干扰很好,遥控器对着按,都没反应                        



        }
}

void timer0() interrupt 1
{
        TH0 = (65536-1000)/256;  //重装1ms初值
        TL0 = (65536-1000)%256;
                cont++;
        if(cont==100)  
        {        
                cont=0;
                flag=!flag;         //发100ms 38K,停100ms

        }

}


回复

使用道具 举报

ID:213173 发表于 2019-9-26 15:01 | 显示全部楼层
设一个标志位,手挡置1,移开复位0,LED的灭除受时间控制外还受此标志控制。这样手挡在前面不移开,保持亮状态。
回复

使用道具 举报

ID:616758 发表于 2019-9-26 16:14 | 显示全部楼层
请问解决了么
回复

使用道具 举报

ID:616759 发表于 2019-9-26 16:25 | 显示全部楼层
粗略的看了下,你有一个flag的变量没有定义,你确定程序没有报错吗?
回复

使用道具 举报

ID:616759 发表于 2019-9-26 16:36 | 显示全部楼层
我看了下,有一部分逻辑我不知道,准确的说不知道你几个变量的用处,我提议把 if(ir_in==0)          //手挡住  改成while循环,  里面加个if(ir_in==1) 判断,continue跳出当前循环,不知道count1的用处,可能需要那个改的这个循环外面
回复

使用道具 举报

ID:160500 发表于 2019-9-26 18:16 | 显示全部楼层
这个程序有BUG,38k发射应该用一个中断或定时器自动生成。主程序只控制发射还是不发射
回复

使用道具 举报

ID:277550 发表于 2019-9-27 00:59 | 显示全部楼层

        if(ir_in==0)          //手挡住
        {
                flag_key=1;
                cont1++;
                key_lock=1;        
        }
        else flag_key=0; //手移开
        
        if(flag_key==1 && cont1==100)
        {         
                  ir=1;
                 cont1=0;
                 led = !led;
                 delay(1000);

        }



计数器都是100就切换led状态
回复

使用道具 举报

ID:462827 发表于 2019-9-27 07:57 | 显示全部楼层
置标志位呗
回复

使用道具 举报

ID:140489 发表于 2019-9-27 08:09 | 显示全部楼层
bai_yun_123 发表于 2019-9-26 16:25
粗略的看了下,你有一个flag的变量没有定义,你确定程序没有报错吗?

我发帖的时候误删了,工程里面有定义的
回复

使用道具 举报

ID:140489 发表于 2019-9-27 09:49 | 显示全部楼层
程序已经改好了,抗干扰能力强,用遥控器对着不停的按,都不会有误动作;隔着5mm厚的玻璃也能感应
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint  unsigned int

sbit ir=P2^4;    //红外发射
sbit ir_in=P3^2; //红外接收
sbit led=P1^1;

#define const_key_time1 20  //感应去抖动延时的时间
uint uiKeyTimeCnt1=0; //感应去抖动延时计数器
uchar ucKeyLock1=0;   //感应触发后自锁的变量标志


bit fw; //

void delay(uint z)           //
{
        uint x,y;
        for(x=z; x>0; x--)
//            for(y=50; y>0; y--); //1.38 ms
                        for(y=10; y>0; y--);  //340us
}

         
void main()
{
        
        TMOD |= 0x02;        //设置定时器模式 8位自动重装
        TL0 = 0xF4;                //设置定时初值                  13us        @11.0592KHz
        TH0 = 0xF4;                //设置定时重载值               
        EA=1;
    ET0=1;
    TR0=1;
    led=0;
    delay(3000);
    led=1;
    while(1)
    {
     
                delay(2);        //间隔700us发一次340us 38k 载波
                fw=1;
                delay(1);
                fw=0;  
                        
                if(ir_in==1)        //没有感应 要及时清零一些标志
                {
               
                        ucKeyLock1=0;   //感应自锁标志清零
                        uiKeyTimeCnt1=0;//感应去抖动延时计数器清零
               
                }
                else if(ucKeyLock1==0)//有感应,且是第一次感应
                {       
                        ++uiKeyTimeCnt1;  //延时计数器
                        if(uiKeyTimeCnt1>const_key_time1)
                        {
                                uiKeyTimeCnt1=0;
                                ucKeyLock1=1; //自锁置位,避免一直触发
                                led = !led;
                        }               
                }
        }
}

void timer0() interrupt 1
{
        if(fw)
        ir=!ir;                   //发38k 载波
}
回复

使用道具 举报

ID:60656 发表于 2019-12-8 16:52 | 显示全部楼层
楼主用的什么接收管?只脚带调制的 还是红外光敏晶体管?
回复

使用道具 举报

ID:416239 发表于 2019-12-10 13:23 | 显示全部楼层
先初始化一下
回复

使用道具 举报

ID:292518 发表于 2021-9-8 14:23 | 显示全部楼层
楼主,能分享一下电路图不?程序测试过了吗?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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