原创 Led非典型应用——感测外部光线

2010-6-16 22:32 3745 9 13 分类: MCU/ 嵌入式
本文章原创于 www.yafeilinux.com  作者:Jay , 转载请注明出处。

基本上初学者学习任何一款单片机都会写同样的一个程序——Led流水灯。就像初学C、C++、Qt之类的语言时都要写“hello world”程序一样。


        很少人知道,其实Led还有感测外界光线强弱的功能。这种现象并不神秘,就跟电动机也可以用作发电机一样,LED的这种特性是由光电管的光电特性决定的,早在1977年,Forrest M. Mims在他的“Engineer”’’s Notebooks”就提到过这种现象 。


        最初接触这种方法是在一个创意网站上,自己觉得很有意思,就在业余时间研究它。


        下面是我写的一段最简单的程序。材料:mega16(具有真正意义上的I/O口)一片。电阻2个(220欧左右),高亮红光Led(经验证这种Led最敏感)2个,没了。材料很简单吧^_^……按照下面的说明连接,so easy!烧好程序后,奇迹出现了,只要把手遮住检测LED上方的光线,指示LED就会点亮。


//检测led +–PORTC.2 – —-PORTC.3 显示led + —–PORTA.0 – —-PORTA.1


#include <mega16.h> 


#include <delay.h>


#define LedOn() {DDRA |= 0b00000011, PORTA |= 0b00000001; PORTA &= ~0b00000010;} 


#define LedOff(){DDRA |= 0b00000011, PORTA |= 0b00000010; PORTA &= ~0b00000001;} 


#define SCANDIF 50     //自定义阀值


#define INITCNT 100


unsigned int table[4] = {0}; 


void LedScan(void)


{


    unsigned int  j;


    DDRC |=   0B00001100;//设置端口方向   


    PORTC |=  0B00000100; //加正偏


    PORTC &= ~0B00001000;   


    PORTC &= ~0B00000100;//加反偏  


    PORTC |=  0B00001000 ; 


    PORTC &= ~0B00000100;//加零偏 


    DDRC &=  ~0B00001000; //设置为输入 


    PORTC &= ~0B00001000; 


    for(j=0;j<10000 && (PINC.3 == 1);j++)  //检测放电时间


    {


        delay_us(100);


    }


    table[0] = j;


}


void main(void) 


{


    unsigned char i; 


    unsigned int GateValue[4] = {0},ScanValue[4] = {0};


    DDRA = 0XFF;


    DDRD = 0XFF;


    OSCCAL="0XA8";


    DDRA|= 0b00000100;  //指示LED位于PA.0


    LedOn();           //建立LED感应阈值


    LedScan();          //空读一次


    for(i=0;i<INITCNT;i++) 


    {  


        LedScan();


        GateValue[0] += table[0];


    }


    GateValue[0]/=INITCNT;


    GateValue[1]/=INITCNT;


    LedOff();


    while(1) 


    { 


        LedScan();


        ScanValue[0] = table[0];


        if( ScanValue[0]>GateValue+SCANDIF) 


        { 


            LedOn();


        } 


        else


        {


            LedOff();


        }


    }


}


下面讲一下原理,大腕出场了……


LED电路应保证阳极能有效接+5V(1发光模式)和被拉地(2反向偏执,3读值状态)。


LED电路应保证阴极能处于GND(1发光模式),+5V(2方向偏执,LED充电(要能提供电流的驱动能力)),IO输入(3读值状态)。


状态1 正向导通LED发光。


状态2 LED方向通电,电路对LED内部电容充电。充电后LED能保持+5V一段时间


状态3 正极地,阴极接端口高阻状态。则LED内部电容和光电流源形成一个放电回路。当LED接受光照越强,放电越快。则越快回复到低电压,我们则检测LED充电后通过放电,led阴极电压从+5v到低电压(地)的放电时间来计算光照强度。


则2,3步骤循环则为LED检测环境光原理。


        看起来挺简单的……做起来就是另一回事了。反正我钻研了老半天。不过做东西都是需要个过程,现在再看这个程序,so easy!.


现在我可以扩展到控制四个LED,写了一个mega16+数码管+1302分段控制定时的程序。简单的说,它可以替代普通的按键,它不会老化而且超级便宜,这是它最大的优点。


          但是,它也是存在缺点的,就是感应的阀值不是自动调整的,中午和晚上外界光线不同,就会使它不稳定,除非再次调整阀值。我下一步想在每个“按键”两旁加个一直点亮的LED,给检测LED提供固定的光源,这样,在“出厂”前只需调整好阀值,就可以很稳定的工作了……


        既然,咱的网站是个开源的网站,我想,也在这个LED上搞个开源项目吧,大家都过来看看,感兴趣的动手做一做,这样靠大家的智慧应该比我这只蜗牛跑得快。


         最后,还是要感谢大家抽出宝贵的时间把这篇文章看完。希望大家多多发言……

PARTNER CONTENT

文章评论4条评论)

登录后参与讨论

用户1549036 2011-3-17 00:26

再看看,有点懂了

用户412065 2010-6-23 09:30

可惜了没有原理图. 不是太明白

用户371925 2010-6-18 12:13

可惜了没有原理图

dwwzl 2010-6-18 09:45

可以做着玩,批量时会发现特性一致性会不好!

用户1133690 2009-6-29 15:17

下载试试
相关推荐阅读
用户395791 2011-02-21 10:10
单片机实现贪吃蛇游戏
本文章原创于 www.yafeilinux.com  作者:雨?烟?, 转载请注明出处。最近忙完英语考试了,感觉轻松许多。手痒的很,想写点程序,在玩弄手机时看见自己的手机游戏里连个贪吃蛇都没有呢…为什...
用户395791 2011-02-13 16:20
Qt 的未来
2011年的春节刚过,当我们还不愿意从过年的懒散生活中清醒过来时,一则无法设想的新闻将我们惊醒!   一、事件突发: 1.北京时间2月11日下午消息,诺基亚与微软刚刚宣布,双方计划建立广泛的战略伙伴关...
用户395791 2010-07-17 13:37
Qt串口通信专题教程
本文章原创于www.yafeilinux.com 转载请注明出处。Qt串口通信专题教程前言去年我使用Qt编写串口通信程序时,将自己的学习过程写成了教程(Qt编写串口通信程序全程图文讲解),但是由于时间...
用户395791 2010-05-27 18:47
Qt Creator系列教程
Qt Creator系列教程        为了使更多的Qt初学者能尽快入门Qt,也为了Qt及Qt Creator的快速普及,我们花费大量精力写出了这一系列教程。虽然教程的知识可能很浅显,虽然教程的语...
用户395791 2010-03-26 17:51
二十七、Qt数据库(七)QSqlRelationalTableModel(原创)
声明:本文原创于yafeilinux的百度博客,http://hi.baidu.com/yafeilinux 转载请注明出处。讲完QSqlTableModel了,我们这次讲这个类的扩展类QSqlRel...
EE直播间
更多
我要评论
4
9
关闭 站长推荐上一条 /3 下一条