标题:
单片机红外反射开关程序问题求助
[打印本页]
作者:
lids
时间:
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
}
}
作者:
wulin
时间:
2019-9-26 15:01
设一个标志位,手挡置1,移开复位0,LED的灭除受时间控制外还受此标志控制。这样手挡在前面不移开,保持亮状态。
作者:
HAYUDA
时间:
2019-9-26 16:14
请问解决了么
作者:
bai_yun_123
时间:
2019-9-26 16:25
粗略的看了下,你有一个flag的变量没有定义,你确定程序没有报错吗?
作者:
bai_yun_123
时间:
2019-9-26 16:36
我看了下,有一部分逻辑我不知道,准确的说不知道你几个变量的用处,我提议把 if(ir_in==0) //手挡住 改成while循环, 里面加个if(ir_in==1) 判断,continue跳出当前循环,不知道count1的用处,可能需要那个改的这个循环外面
作者:
liuzx66
时间:
2019-9-26 18:16
这个程序有BUG,38k发射应该用一个中断或定时器自动生成。主程序只控制发射还是不发射
作者:
devcang
时间:
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状态
作者:
hantu
时间:
2019-9-27 07:57
置标志位呗
作者:
lids
时间:
2019-9-27 08:09
bai_yun_123 发表于 2019-9-26 16:25
粗略的看了下,你有一个flag的变量没有定义,你确定程序没有报错吗?
我发帖的时候误删了,工程里面有定义的
作者:
lids
时间:
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 载波
}
作者:
zxq9781
时间:
2019-12-8 16:52
楼主用的什么接收管?只脚带调制的 还是红外光敏晶体管?
作者:
李泽训
时间:
2019-12-10 13:23
先初始化一下
作者:
long2018
时间:
2021-9-8 14:23
楼主,能分享一下电路图不?程序测试过了吗?
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1