|
带读取功能的LED扫描棒制作说明 ---------M8LightTalk2 作者:Mljda 发布地址:ouravr.com 发布时间:2008.11.28 1 思路来源: 大学时,跟老师做的led类项目,所以关注LED,切投入少,而且很炫,谈情说爱时很有效果。某日 2 文献: Very Low-Cost Sensing and Communication.Pdf 见了LED作为常见光感(LedTouch光感触摸键盘,环境光检测),和做短距无线传输的应用思路。(发光与监测(通信)协议.doc文件自翻译) An optical sensing approach based on light emitting diodes.pdf 细致分析了LED的发光和感光原理。和部分原理性应用。 LED senses and displays ambient-light intensity.pdf 专讲LEDtouch文章。(DOC文件自翻译) ThinkGeek LightTalk II.mht 原装主页(自己判断) 相关链接: http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=1386729&bbs_page_no=1&search_mode=4&search_text=AAVVRR&bbs_id=9999 http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=859325&bbs_page_no=1&bbs_id=1000 http://ouravr.com/bbs/bbs_content_all.jsp?bbs_sn=1337063 旧广告请忽略广告,看相关资料。 3 电路分析: 1)根据资料,LED工作与图(1)三种状态 (原文件名:led3态.JPG) 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检测环境光原理。 1 LED阳极驱动 为了驱动多个(LightTalk 32个)LED反光,所以阳极采用三级光构建驱动电路: 为了使三极管完全断开,所以使用rc2限流,和rc1上拉电路,限位基极电压。 RC3保证在三级管导通时,电流主要流向LED,驱动LED。 三极管断开时,能把LED阳极拉地。(过大电阻起不到拉地作用,如同上拉驱动电路电阻太大就没驱动能力。)。 2 LED阴极读取。直接采用芯片IO操作简单(IO扩展在本例中不适用,只能由芯片IO直接读取LED阴极电平变化,32点8bit共4片,且芯片工作尝试失败。)LED独立限流电阻,可以保证LED电流近似一致(如果使用共限流电阻,LED内阻由于电阻并联效果,较小的LED会吸收过多电流。发光不一致,切释放电流不一致,读值判别失误。) (原文件名:采样电路图.JPG) 1 Ctrl0输出高电平,且(lc1上拉电阻)则PNP基极为正,则PNP关断,LED阳极被(lc2)拉低。 1 )PB输出低电平 LED不工作 2 )PB输出高电平 LED反向充电 3 )PB高阻态输入 读取LED电压值 2 Ctrl0输出低电平,PNP基极拉低,则PNP导通,LED阳极接正。 1)PB输出低电平 LEDs导通,LED发光 2)PB输出高电平 LED不工作 4 功能分析 Lighttalk功能特点就是能读取白色纸上的黑色背景。LED能感光,但距离近。根据光能量特性和反射性质。红外光线能量传递最好,则在可见光波段,则红色LED为首选(见资料)。 LED发射什么波长的光,那么它就可以很好的接收这个波长的光。LED发射的波段能被同型号的LED很好接收,所以就使用同一类型的LEDs,一个做背景光,一个做检测用LED。 Mega8,8位机是8位端口,采用两组端口,在一组发光是,另一组检测背景光。 两组LEDs交替排列 (原文件名:组采样.JPG) 01,02...07为PORTD驱动 11,12为.....17为PORTB驱动 01,02亮,则为1x组LED,提供了背景光。 图一:01,02发光,11对应一个白点,则反射回被11检测的光强。判断为白点 图二:01,02发光,11对应一个黑点,则反射回被11检测的光弱。判断为黑点 5 注意 (原文件名:照片 0010.jpg) (原文件名:照片 0020.jpg) 1 焊接温度影响了LED放电曲线(原来好的点,修正其它点,这点发烫后,检测有偏差) 2 电阻似乎精度是(5%)影响,需使用1%电阻会有改善检测的一致性。 3 测试版可以使用直插模式(如上图)。减少焊接损坏影响 4 使用时,LED应与纸面保持2-3mm距离。反射效果最好(黑暗环境,LED两侧挡光)。 6 程序 简要。需特定头文件支持。看程序包 按键启动采样RAM保存摇动回显M8LightTalk2 /* * * 程序名称:周期读引脚电平值(低电平为真)(ledtouch,lighttalk2电路支持) * 入口参数:引脚端口地址【绝对地址,几PORTD等】 * (*(volatile unsigned char *)(addrPin)) * 出口参数:无符号字节(端口值,1白,0黑) * 注意事项:需计时器0 US 延时支持. * LightTalk2.h->_runTimer0_TimeUS(x).... * * 原意是通过硬件计时监测放电周期,结果 * 程序效果介于延时判断和周期检测方式合并,还可以优化,减少检测 * 时间。(×原理还需细化×) */ #define RD_PINS_TIME 7 /* 读端口次数,如果有效值大于一半,则为读取到真 */ unsigned char ReadPinsAsLowInTimePeriod(unsigned int addrPin) { unsigned char i; unsigned char RdVal[RD_PINS_TIME]={0}; unsigned char bitShift=0x01; unsigned char bitStore=0; unsigned char bit1Cnt=0; for(i = 0 ; i < RD_PINS_TIME ; i++) { _runTimer0_TimeUS(180); do { _breakTimer0OV(); RdVal = (*(volatile unsigned char *)(addrPin)); /*通过SRAM绝对地址读取端口,程序可扩展*/ }while( !(RdVal == 0xFF) );/*_breakTimer0OV() 读取引脚1,检测到高电平 下一步*/ /* 开始新检测周期 */ _runTimer0_TimeUS(170); do { RdVal = (*(volatile unsigned char *)(addrPin)); if( !(RdVal == 0xFF) )/* 读取引脚0,检测到低电平 */ { break; } }_whileTimer0OV(); _stopTimer0(); } /* 结算采样数组,有效次数大于等于总采样数,*/ /* 则为采样到亮点 1,否则黑点 0 */ for(char j=0;j<8;j++) { for(i = 0;i < RD_PINS_TIME;i++) { if( (RdVal & bitShift ) == 0){bit1Cnt++;} } if(bit1Cnt>= (RD_PINS_TIME/2))bitStore |= bitShift; bit1Cnt=0; bitShift<<=1; } return bitStore; } /* * * 程序名称:读取led组值(ledtouch,lighttalk2) * 入口参数:无 * 出口参数:无 * 注意事项:需端口操作宏;Timer0硬件us查询延时支持 * LightTalk2.h->_ledsAnode_High(LEDS0);// 阳极 * _ledsCathode_ChangeToOutputLow(LEDS0);// 阴极 * ....... * _runTimer0_TimeUS(250);....... * typedef struct INT2CHAR;//整型<->字节2 * U8 ReadPinsAsLowInTimePeriod(U16); * suartInt2bitPrint(U16); * * */ void readLeds(INT2CHAR *I2Cptr) { INT2CHAR i2cVal; /********************************************************/ /* ISP有影响,除去下载线,效果ok */ /* 开背景光 Turn ON*/ _ledsAnode_High(LEDS0);/* 阳极 */ _ledsCathode_ChangeToOutputLow(LEDS0);/* 阴极 */ /* 反向偏执 充电 */ _ledsAnode_Low(LEDS1); _ledsCathode_ChangeToOutputHig(LEDS1); _runTimer0_TimeUS(250); _waitTimer0OV(); /* 反向偏执 检测光 */ _ledsCathode_ReadIO_Hi_Z(LEDS1); _runTimer0_TimeUS(250); _waitTimer0OV(); _runTimer0_TimeUS(250); _waitTimer0OV(); i2cVal.i8[0]=ReadPinsAsLowInTimePeriod(LEDS1ADDR); _ledsAnode_Low(LEDS0);/* 阳极 Turn OFF*/ _ledsCathode_ChangeToOutputHig(LEDS0);/* 阳极 */ /********************************************************/ /* ISP有影响,除去下载线,效果ok */ /* 开背景光 Turn ON*/ _ledsAnode_High(LEDS1);/* 阳极 */ _ledsCathode_ChangeToOutputLow(LEDS1);/* 阴极 */ /* 反向偏执 充电 */ _ledsAnode_Low(LEDS0); _ledsCathode_ChangeToOutputHig(LEDS0); _runTimer0_TimeUS(250); _waitTimer0OV(); /* 反向偏执 检测光 */ _ledsCathode_ReadIO_Hi_Z(LEDS0); _runTimer0_TimeUS(250); _waitTimer0OV(); _runTimer0_TimeUS(250); _waitTimer0OV(); i2cVal.i8[1]=ReadPinsAsLowInTimePeriod(LEDS0ADDR); _ledsAnode_Low(LEDS1);/* 阳极 Turn OFF*/ _ledsCathode_ChangeToOutputHig(LEDS1);/* 阳极 */ _ledsCathode_ChangeToOutputHig(LEDS0);/* 复位为输出 */ I2Cptr->i16 = valPack(i2cVal); //c2iVal.i16 = valPack(i2cVal); //suartInt2bitPrint(c2iVal.i16); } /* 程序功能:解包,整型值至双字节型,偶数位合成一个字节,奇数位合成一个字节 入口参数:整型数 val 出口参数:INT2CHAR结构体变量。整型至双字节 */ INT2CHAR valUnPack(unsigned int val) { char i; unsigned char bit2Char = 0 ; unsigned int bitShift = 0 ; INT2CHAR tmp; tmp.i16=0; bitShift = val; for(i = 0; i < 8*sizeof(bit2Char); i++) { bit2Char>>= 1; if(0x0001 & bitShift)/* 奇数 */ { bit2Char |=0x80; }else { // bit2Char |=0x00; } bitShift>>= 2; } tmp.i8[0] = bit2Char; bit2Char =0; bitShift = val; for(i = 0; i < 8*sizeof(bit2Char); i++) { bit2Char>>= 1; if(0x0002 & bitShift)/* 偶数 */ { bit2Char |=0x80; }else { // bit2Char |=0x00; } bitShift>>= 2; } tmp.i8[1] = bit2Char; return(tmp); } /* 程序功能:打包,把奇数位,偶数位字节合成一个整型数 入口参数:INT2CHAR结构体val,低字节奇数位,高字节偶数位 出口参数:整型 */ unsigned int valPack(INT2CHAR val) { char i; unsigned char bitShift = val.i8[0]; unsigned int bit2int0 = 0,bit2int1 = 0; for(i = 0;i < 8*sizeof(bitShift) ;i++ ) { bit2int0>>= 2 ; if(bitShift & 0x01) { bit2int0 |=0x8000; }else { // bit2int0 |=0x0000; } bitShift>>= 1 ; } bitShift = val.i8[1]; for(i = 0;i < 8*sizeof(bitShift) ;i++ ) { bit2int1>>= 2 ; if(bitShift & 0x01) { bit2int1 |= 0x4000; }else { // bit2int1 |= 0x0000; } bitShift>>= 1 ; } return( bit2int0 | bit2int1 ); } 点击此处下载 ourdev_520976.rar(文件大小:1.87M) (原文件名:发布包.rar) |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|