基本上初学者学习任何一款单片机都会写同样的一个程序——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上搞个开源项目吧,大家都过来看看,感兴趣的动手做一做,这样靠大家的智慧应该比我这只蜗牛跑得快。
最后,还是要感谢大家抽出宝贵的时间把这篇文章看完。希望大家多多发言……
用户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