电子大神的日记本,供应链专家的功夫茶盘,在这里记录、分享与共鸣。

登录以开始

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

本文章原创于 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;iGateValue+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上搞个开源项目吧,大家都过来看看,感兴趣的动手做一做,这样靠大家的智慧应该比我这只蜗牛跑得快。

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

博主
XTXY_ESL
嵌入式实验室
祝贺http://www.yafeilinux.com/正式开通!欢迎访问!
点击跳转