51单片机做电子相册-fat32文件系统
51单片机做电子相册文/张彬杰
http://cache.amobbs.com/bbs_upload782111/files_12/ourdev_421069.jpg
(原文件名:实物图3.jpg)
本文介绍的电子相册如图,通过51单片机,自动播放SD/MMC卡存储设备的图像。电子相册具有传统相册无法比拟的优越性:图、文并茂的表现手法,随意修改编辑的功能,永不褪色的恒久保存特性。而我们通过简单的电路,自己动手就可以实现了。
一、电路可实现功能
http://cache.amobbs.com/bbs_upload782111/files_12/ourdev_421070.jpg
(原文件名:实物图4.jpg)
如图所示,整个播放器的电路由彩色液晶【左】、SD/MMC卡槽【中】和51单片机最小系统【右】3个部分组成。彩色液晶用于图像的显示,SD/MMC卡槽用于插入存储设备,51单片机最小系统用于控制和播放图像。使用时,将SD/MMC卡格式化成fat32文件系统,然后把bmp格式图片复制到SD/MMC卡,即可自动播放。
二、所需元器件及材料
整个播放器几乎没使用什么分立元件。使用了一片LM1117-3.3及它的若干外围元件,进行电源电压转换,把电源电压稳定到3.3V。选用SST89E58RD单片机做为主控制芯片。它有1k的内部RAM ,有硬件SPI接口,最高可用40M晶振。单片机的外围元件组成了51最小系统。最后买了个SD/MMC卡槽,方便插入SD/MMC卡。彩色液晶屏幕的分辨率是160x128,自带SPFD54124B控制器,这样只要通过发送命令就可以方便显示图像了。更具体的元器件,请看电路原理图,就不再一一介绍了。
三、电路原理
http://cache.amobbs.com/bbs_upload782111/files_12/ourdev_421072.gif
(原文件名:电子像册原理图.gif)
电路原理如图。关键是如何和SD/MMC卡连接,以及如何和彩色液晶连接。然而它们的连接方式都是直接连接的,直接和单片机的I/O口连接,很方便。在电源方面,用USB充电器的5v电源,经过LM1117-3.3稳压模块,转换成3.3v电压。当然了,如果有3.3v的电源,也可以直接使用。剩下的就是单片机最小系统了。
四、SD卡的特点和通讯协议:
1、两个可选的通信协议:SD模式和SPI模式
2、可变时钟频率0-25MHz
3、工作电压范围:2.0-3.6V
4、卡片带电插拔保护
5、兼容MMC卡命令
SD卡有两个可选的通讯协议:SD模式和SPI模式。SD模式是SD卡标准的读写方式,但是在选用SD模式时,往往需要选择带有SD卡控制器接口的单片机,或者必须加入额外的SD卡控制单元以支持SD卡的读写。然而,一般单片机没有集成SD卡控制器接口,若选用SD模式通讯就无形中增加了产品的硬件成本。在SD卡数据读写时间要求不是很严格的情况下,选用SPI模式可以说是一种最佳的解决方案。因为在SPI模式下,通过四条线就可以完成所有的数据交换,并且目前市场上很多单片机都有现成的SPI接口电路,采用SPI模式对SD卡进行读写操作可大大简化硬件电路的设计,具体请看电路原理图了。
由于SD卡兼容MMC卡命令。所以,使用MMC卡的命令集。SD/MMC卡每次通信,传输48位,即6字节的数据。第1字节是命令,紧接着4字节是参数,一般用于指定SD/MMC卡的字节地址。 最后,一个字节是校验码。一般,命令也就用到0x40复位命令、 0x41初始化命令、 0x51读扇区命令、0x58 写扇区命令。硬件SPI接口电平上,设置单片机的时钟线,默认为1,设置数据在时钟的后沿移位。注意,在初始化阶段最好设置SPI频率为128分频,较低速度。等初始化完成再把分频系数改为4分频,较高速度,正常使用SD/MMC卡。
五、重点器件的选择理由及介绍
单片机的内存要大于512字节,因为SD/MMC卡的数据读写是512字节为单位的。并且要有SPI接口,因为程序使用SD卡的SPI通讯协议。所以,我选用SST89E58RD单片机作为主控制芯片。彩色液晶要选自带控制器的,因为一般单片机不带液晶控制器。彩色液晶的具体控制方式要看技术手册了,不同控制器,它的控制方法不一样。如果没有彩色液晶,用熟悉的128X64的黑白液晶练习下也行。
六、制作过程介绍
我用了两片万用板,一片用来固定SD/MMC卡槽。另一片用来做单片机最小系统。在淘宝网上买了一片1.8英寸的彩色液晶。使用了这3个部分组成一个整体,并用插针插座连接。电源用USB接口的5v电压,所以在万用板上焊接了miniUSB接口。当然,如果想要携带方便,也可以使用电池供电。
七、使用效果
http://cache.amobbs.com/bbs_upload782111/files_12/ourdev_421067.jpg
(原文件名:实物图1.jpg)
http://cache.amobbs.com/bbs_upload782111/files_12/ourdev_421068.jpg
(原文件名:实物图2.jpg)
如图在彩色液晶上显示图像。显示完一幅图像后,延迟2秒,继续显示下一幅。图像与图像之间从左往右,从上往下快速的切换。文件名以3位数字命名,存放在根目录下,从000开始,顺序读取。当读取不到下一个文件时,重新从000读取。Bmp文件是r-g-b 5-5-5存放的高彩色图象,图像大小为:160x128。可用Photoshop,另存为产生。 顶不错 能共享源码??? 有源代码吗? 楼主真是强人! 不错~~ 厉害 楼主只是来炫耀的吗? 没有代码共享 做的很不错啊 很好啊,支持 楼主还在么? 厉害,厉害 期待的人一群。 LZ能上源代码不///./emotion/em020.gif 关注中 从楼主的行文,积分,图片来看---广告贴 广告 还行起码有点东西,但有点参考代码的话估计就不会有问题了 。 等代码 Mark! 支持,关注 很是期待楼主的源代码啊!对图像处理不懂啊! 强,期待 代码,代码!!创意不错地 不错啊 :)都想马上做一个了:) gg 楼主创意不错,记录一个!
收藏创意。 都期待到我这里!!好像还是没共享!!。。。。。。 以为忘了密码,所以一直没上传。等过两天上传。 等待源码 楼主创意不错,记录一个!
收藏创意。 由于不能上传文件。
就直接黏贴程序了。
1、main.c文件,它是主程序,内容如下:
#include "SD_MMC.c"
#include "LCD_160_128.c"
#include "SST89x5x4.H"
#include "fat32.c"
#include "show_bmp16.c"
#include "show_bin.c"
//程序入口
main()
{
lcd_init();
SPCR=0X5F; //128分频【最低速度】,高电平,后沿移位
while(sd_init()==0);
SPCR=0X5C; //4分频【最高速度】,高电平,后沿移位
sd_read(0);
s_p_c = sd_512;
fat_area= sd_512;
fat_area= fat_area<<8; fat_area += sd_512;
fat_size= sd_512;
fat_size= fat_size<<8; fat_size += sd_512;
base_s=fat_size*2+fat_area;//根目录扇区,2簇,开始簇。
while(1)
{
read_root_sector();
name++;
if(success==0) name=0;
if(success==1) show_frame_bmp16();
if(success==2) show_frame_bin();
root_c=0x2;
success=0;
cluster_end=0;
}
} 2、LCD_160_128.c文件,它是液晶驱动,内容如下:
#ifndef LCD_160_128
#define LCD_160_128
_delay_ms(int t)
{
int i,j;
for (i=0;i<t;i++) for(j=0;j<120;j++);
}
sbit CS=0xb2;
sbit RS=0xb3;
sbit RW=0xb4;
sbit Rd=0xb5;
sbit PWM=0xb6;
sbit RST=0xb7;
sfr num_out = 0xa0;
//命令1字节
void send_command(unsigned int Cmd)
{
CS=0;
RS=0;
num_out=Cmd;
RW=0;RW=1;
CS=1;
}
//数据1字节
void send_byte(unsigned char Data)
{
CS=0;
RS=1;
num_out=Data;
RW=0;RW=1;CS=1;
}
//1字节命令,1字节数据
void write_com(unsigned int Cmd,unsigned int num)
{
CS=0;
RS=0;num_out=Cmd;RW=0;RW=1;
RS=1;num_out=num;RW=0;RW=1;
CS=1;
}
//初始化
void lcd_init(void)
{
CS=1; RW=1; Rd=1; RS=1;
RST=0;
_delay_ms(1);RST=1;
send_command(0x11);_delay_ms( 1 );// sleep out/power on(SLPOUT)
send_command(0x20); // display inversion off
send_command(0x38); // ID mode off (IDMOFF)
send_command(0x13); // Normal display mode on (Partial mode off)
// color mode Interface pixel format(COLMOD)
write_com(0x3A,0x05); // 16-bit/pixel , 1-times data transfer
write_com(0xC0,0x00); // power control 1 (PWCTR1) , GVDD voltage set 4.65
write_com(0xC1,0x05);_delay_ms( 1 );
// VCOMH voltage set 4.10V
write_com(0xC5,0xc7); //;c0h VCOMH voltage set 4.175V
write_com(0xC6,0x07);_delay_ms( 1 );
send_command(0xE0);
send_byte(0x21);
send_byte(0x11);
send_byte(0x21);
send_byte(0x22);
send_byte(0x22);
send_byte(0x33);
send_byte(0x03);
write_com(0x36,0xA0); // MY=1; MX=0; MV=0; ML=0; RGB=0
send_command(0x37);
send_byte(0x00);
send_byte(0x00); // display on
send_command(0x29);
}
//液晶定位
void LCD_SetArea( unsigned char x0, unsigned char y0, unsigned char x1, unsigned char y1 )
{
send_command(0x2A);
send_byte(0x00);
send_byte(x0);
send_byte(0x00);
send_byte(x1);
send_command(0x2B);
send_byte(0x00);
send_byte(y0);
send_byte(0x00);
send_byte(y1);
}
#endif 3、SD_MMC.c文件,它是SD、MMC卡驱动,内容如下:
#ifndef SD_MMC
#define SD_MMC
#include "SD_MMC_DATA.c"
#include "SST89x5x4.H"
void send_byte(unsigned char);
sbit sd_mosi = P1^5;
sbit sd_miso = P1^6;
sbit sd_clk= P1^7;
sbit sd_cs = P1^4;
//读写sd卡时序,高位先发。
unsigned char sd_rw(unsigned char a)
{
SPDR=a; //spi输出
while((SPSR&0x80)==0);
SPSR=0;
return SPDR;
}
//6字节命令
unsigned char sd_cmd(unsigned char *p)
{
unsigned char i,a=0;
sd_cs=1;
sd_rw(0xff);
sd_cs=0;
for(i=0;i<6;i++) sd_rw(*p++);
sd_rw(0xff);
a=sd_rw(0xff);
return a;
}
//mmc/sd 卡初始化
unsigned char sd_init(void)
{
unsigned char cmd[]={0x40,0x00,0x00,0x00,0x00,0x95};
unsigned char i=0;
for(i=0;i<10;i++) sd_rw(0xff);
i=0;
if(sd_cmd(cmd)!=0x01) return 0;
cmd=0x41;cmd=0xff;
while(sd_cmd(cmd)!=0X00) if( (++i)>200 ) return 0;
return 1;
}
//读指定扇区512字节,跳转sd_512data_r()函数处理。
unsigned char sd_read(unsigned long address)
{
unsigned char cmd[]={0x51,0x00,0x00,0x00,0x00,0xff};
address=address<<9;
cmd=(address>>24);
cmd=(address>>16);
cmd=(address>>8);
cmd=(address>>0);
if(sd_cmd(cmd)!=0x00) return 0;
while(sd_rw(0xff)!=0xfe);
sd_512data_r();
sd_rw(0xff);sd_rw(0xff);
return 1;
}
//读指定扇区512字节,跳转sd_512data_r_direct()函数处理。
unsigned char sd_read_direct(unsigned long address)
{
unsigned char cmd[]={0x51,0x00,0x00,0x00,0x00,0xff};
address=address<<9;
cmd=(address>>24);
cmd=(address>>16);
cmd=(address>>8);
cmd=(address>>0);
if(sd_cmd(cmd)!=0x00) return 0;
while(sd_rw(0xff)!=0xfe);
sd_512data_r_direct();
sd_rw(0xff);sd_rw(0xff);
return 1;
}
#endif 4、SD_MMC_DATA.c 文件,它是SD、MMC卡处理函数,内容如下:
//读512字节数据
#ifndef SD_MMC_DATA
#define SD_MMC_DATA
unsigned char sd_rw(unsigned char a);
xdata unsigned char sd_512 _at_ 0x0000;
void send_byte(unsigned char);
sd_512data_r()
{
unsigned int i;
for(i=0;i<512;i++) sd_512=sd_rw(0xff);
}
sd_512data_r_direct()
{
unsigned int i;
for(i=0;i<512;i++) send_byte(sd_rw(0xff));
}
#endif 5、fat32.c 文件,它是简单的fat32文件系统,内容如下:
#ifndef fat32
#define fat32
#include"sd_mmc.c"
unsigned inti=0,j,l=54;
unsigned long addr,x_addr,y_addr,root_s=0,base_s=0,cluster=0,first_c,root_c=0x2;
unsigned char s_p_c = 0;
unsigned char fat_area = 0;
unsigned intfat_size = 0;
unsigned intname=0;
unsigned char success=0,cluster_end=0;
int k,bmp_16;
//根目录扩展簇
extern_boot_cluster()
{
sd_read(fat_area+root_c/128);//“簇地址记录”所在扇区
i=root_c%128; //每扇区128条“簇地址记录”,4字节簇地址
root_c =sd_512;
root_c =root_c<<8;
root_c+=sd_512;
root_c =root_c<<8;
root_c+=sd_512;
root_c =root_c<<8;
root_c+=sd_512;
if(root_c==0x0fffffff)cluster_end=1;//结束标志
}
//在根目录,读文件起始簇号,1扇区16条文件记录
file_first_cluster()
{
for(i=0;i<512;i+=32)
{
if(
sd_512 == (0x30+name%1000/100)&&
sd_512 == (0x30+name%100/10)&&
sd_512 == (0x30+name%10/1)&&
sd_512 == 'B'&&
sd_512 == 'M'&&
sd_512== 'P')
{
first_c = sd_512;
first_c = first_c<<8;
first_c+= sd_512;
first_c = first_c<<8;
first_c+= sd_512;
first_c = first_c<<8;
first_c+= sd_512;
success=1;
break;}
if(
sd_512 == (0x30+name%1000/100)&&
sd_512 == (0x30+name%100/10)&&
sd_512 == (0x30+name%10/1)&&
sd_512 == 'B'&&
sd_512 == 'I'&&
sd_512== 'N')
{
first_c = sd_512;
first_c = first_c<<8;
first_c+= sd_512;
first_c = first_c<<8;
first_c+= sd_512;
first_c = first_c<<8;
first_c+= sd_512;
success=2;
break;}
}
}
//读根目录扇区
read_root_sector()
{
while(cluster_end==0)
{
for(j=0;j<s_p_c;j++) //1簇,j扇区,根目录文件读取
{
root_s=(root_c-2)*s_p_c+base_s+j;
sd_read(root_s);
file_first_cluster(); //寻找文件,定位首簇
if(success>0) break;
}
if(success>0) break;
extern_boot_cluster(); //读根目录下1簇
}
}
#endif 5、show_bmp16.c 文件,它是简单的BMP文件处理函数,内容如下:
#ifndef show_bmp16
#define show_bmp16
#include "SD_MMC.c"
#include "lcd_160_128.c"
#include "fat32.c"
line1()
{
for(i=512-(320-l);i<512;i+=2)
{
send_byte( (sd_512<<1)|(sd_512>>7) );
send_byte( (sd_512<<1)& 0xe0 | sd_512& 0x1f );
}
}
line2()
{
for(i=0;i<l;i+=2)
{
send_byte( (sd_512<<1)|(sd_512>>7));
send_byte( (sd_512<<1)&0xe0 | sd_512&0x1f);
}
}
line3()
{
for(i=l;i<l+320;i+=2)
{
send_byte( (sd_512<<1)|(sd_512>>7));send_byte( (sd_512<<1)&0xe0 | sd_512&0x1f);
}
}
//显示1幅图像
show_frame_bmp16()
{
LCD_SetArea(0,0,159,128); send_command(0x2C);
for(bmp_16=79;bmp_16>=0;bmp_16--)
{
if(bmp_16>=s_p_c)
{
cluster = first_c;
for(k=bmp_16/s_p_c; k>0; k--)
{
sd_read(fat_area+cluster/128);i=cluster%128;//每扇区128条簇地址记录【fat】
cluster =sd_512;cluster=cluster<<8;
cluster+=sd_512;cluster=cluster<<8;
cluster+=sd_512;cluster=cluster<<8;
cluster+=sd_512;
}
x_addr=(cluster-2) * s_p_c + base_s + bmp_16%s_p_c;
}
else
x_addr=(first_c-2) * s_p_c + base_s + bmp_16%s_p_c;
sd_read(x_addr);
line1();
if( (bmp_16+1)>=s_p_c)
{
cluster = first_c;
for( k=(bmp_16+1)/s_p_c; k>0; k--)
{
sd_read(fat_area+cluster/128);i=cluster%128;//每扇区128条簇地址记录【fat】
cluster =sd_512;cluster=cluster<<8;//4字节簇地址
cluster+=sd_512;cluster=cluster<<8;
cluster+=sd_512;cluster=cluster<<8;
cluster+=sd_512;
}
y_addr=(cluster-2) * s_p_c + base_s + (bmp_16+1)%s_p_c;
}
else
y_addr=(first_c-2) * s_p_c + base_s + (bmp_16+1)%s_p_c;
sd_read(y_addr);
line2();
l=512-(320-l);
if(l>=320)
{
l-=320;
sd_read(x_addr);
line3();
}
}
_delay_ms(14000);//2秒等待
}
#endif 留名 6、show_bin.c 文件,它是简单的BIN文件处理函数,内容如下:
#ifndef show_bin
#define show_bin
#include "SD_MMC.c"
#include "lcd_160_128.c"
#include "fat32.c"
show_frame_bin()
{
LCD_SetArea(0,0,159,128);send_command(0x2C);
cluster=first_c;
while(1)
{
addr = ( (cluster-2) * s_p_c + base_s); //簇地址 转换 扇区地址
for(i = 0;i<s_p_c;i++) sd_read_direct(addr+i); //每簇扇区数
sd_read(fat_area+cluster/128);
i=cluster%128; //每扇区128条簇地址记录【fat】
cluster = sd_512;
cluster=cluster<<8;
cluster+= sd_512;
cluster=cluster<<8;
cluster+= sd_512;
cluster=cluster<<8;
cluster+= sd_512;
if(cluster==0x0fffffff) break;
}
_delay_ms(14000);//2秒等待
}
#endif SST89x5x4.H头文件就不上传了。
以上是所有的文件及其内容。
保证编译通过,并能使用。 支持楼主 不错 顶一下 不错 好东东啊..保存起来,慢慢看... 不错支持一个 强帖~~MARK一下 记号 回家看 BMP啊 mark 很强,要是我自己能做出来就好了. 请问一下显示屏的型号。零买的话价格大概是多少? 彩色液晶屏幕的分辨率是160x128,自带SPFD54124B控制器。
http://shop35330111.taobao.com/有卖。 确实不错,如果液晶改用旧的手机屏也能用吗? 你就是张彬杰吧,《无线电》09年第4期的文章就是你写的吧。
很好!!
我正好有个1.8英寸的屏,也想用只是不只道怎么写驱动。希望能交流交流! 太感谢了~~ sd_read(0);
s_p_c = sd_512;
fat_area= sd_512;
fat_area= fat_area<<8; fat_area += sd_512;
fat_size= sd_512;
fat_size= fat_size<<8; fat_size += sd_512;
base_s=fat_size*2+fat_area;//根目录扇区,2簇,开始簇。
sd_read(0); 是读物理扇区0 的数据,还是读逻辑扇区0 的数据。从程序来看好像是读逻辑扇区0 的数据。
不知程序是如何找到逻辑扇区0 的具体位置,请教一下。
有人制作成功了吗? 1、其它液晶的驱动(其实主要就是初始化代码),卖液晶的会送代码的。
2、sd_read(0x00000000) 函数可以读SD卡或MMC卡 物理0扇区(512字节默认大小)的数据。 新版电子相册 = AVR-M16L单片机、一片SD卡、一块2.8寸液晶 。
http://cache.amobbs.com/bbs_upload782111/files_15/ourdev_447864.jpg
(原文件名:1.jpg)
已经完成:
1、引脚模拟SPI,SD卡读数据
2、液晶驱动
将要完成:
1、硬件SPI
2、FAT32文件系统
3、BIN图片数据文件读取
可能的设想:
1、加光敏电阻1个,经过AVR的AD可以动态的调整液晶背光亮度。
2、加3个电阻,AVR模拟USB接口。可以下载程序和图片。 谢谢,答复。
物理0扇区与逻辑0扇区是有一个偏移量的,读物理0扇区的数据如何来满足下面程序所需要的数据呢?程序中也没有判断和处理呀?
s_p_c = sd_512;
fat_area= sd_512;
fat_area= fat_area<<8; fat_area += sd_512;
fat_size= sd_512;
fat_size= fat_size<<8; fat_size += sd_512;
base_s=fat_size*2+fat_area;//根目录扇区,2簇,开始簇。
这些数据是逻辑0扇区(启动扇区)中的数据。 ding 关于SD卡的逻辑扇区和物理扇区
leijiamin 发表于: 2009-4-13 15:24 来源: IC开发网
看了几个朋友的帖子,个人认为大家对于逻辑扇区和物理扇区有点混淆了。
就SD卡本身来说,物理扇区指的是卡内部的flash上的块。由于flash的一些特性决定SD卡需要一个芯片对这些块进行管理。当我们的板卡,不管是通过SPI还是SD模式,发出指令的时候,对于SD卡来说,使用的都是逻辑扇区。比如说我们的程序需要读取扇区0,那么这个时候,就是逻辑扇区0,到了SD卡的管理芯片,这个逻辑扇区可能被转换到物理扇区12。这个转换对于我们程序来说是透明的。当我们对扇区0进行修改时,管理芯片就会将新的数据写到物理扇区13,同时将物理扇区13标注为逻辑扇区0。
对于文件系统来说,SD卡就是一个块设备,文件系统需要的就是物理扇区,就是上文中的逻辑扇区。当我们把SD卡上的数据读出来,组建成一个文件系统后,就能获得更高层次的逻辑扇区,从而引进簇的概念。
所以如果不是为了做SD卡,根本不需要去了解第一层的关系。对于我们做Host的来说,只需要知道SD卡就是一个块设备,从扇区0到扇区n,n由SD卡自身决定。因为SD卡默认的出厂都会被格式化为FAT格式,所以我们所要做的,就是从扇区0读取数据,构建一个符合FAT标准的文件系统。当然,如果你要实现ext2的格式也是可以的。没有研究过ext2格式,不过想来ext2也是基于块存储结构的,那么和FAT其实是一样的。只是逻辑上的数据结构不同而已。
对于FAT格式来说,我想大家指的逻辑扇区0是存放文件内容的扇区0吧,而物理扇区0就是存放MBR/Partition Table的扇区吧。不知道大家是不是这个意思。如果是这样的话,那么我建议才文件系统的数据建构中,设置一个偏移值,就是从MBR到Data的偏移,这个偏移是可以从MBR里面算出来的。
--来自互联网 mark mark 牛 MARK 牛人啊!佩服!
可能这里面液晶驱动是最难的吧。 mark 很不错 mark 好贴 谢谢 顶一下,谢谢分享。 学习中@! 本人也有个关于数据采集的项目,用到SD卡存储海量数据,想问一下要在单片机建立DS卡的FAT32文件系统,需要多大内存的单片机? 回复:【74楼】 racemaker
728字节以上就可以了。 新版的电子相册:
技术指标:
1、支持FAT32文件系统
2、支持16位、24位、32位BMP图片
3、支持240*320、480*640、720*960、960*1280、
320*240、640*480、960*720、1280*960分辨率图片
主要DIY元器件:
1、SD或MMC卡
2、AVR单片机
3、彩色液晶
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3529481&bbs_page_no=1&bbs_id=1000 mark,顶 原来这也有~LZ的帖子~~MARK~~ Mark! 强 做个记号。。。 记一个 mark 好 too mark! mark 我也秀一下~~
实验的版本,用的SD卡
http://cache.amobbs.com/bbs_upload782111/files_21/ourdev_498221.jpg
(原文件名:4581_12511734300m6u.jpg)
http://cache.amobbs.com/bbs_upload782111/files_21/ourdev_498222.jpg
(原文件名:2.jpg)
最终成品,改用TF卡,单面布线,增加了光电感应开关~~
http://cache.amobbs.com/bbs_upload782111/files_21/ourdev_498223.jpg
(原文件名:DSC00132.jpg)
http://cache.amobbs.com/bbs_upload782111/files_21/ourdev_498224.jpg
(原文件名:DSC00165.jpg)
http://cache.amobbs.com/bbs_upload782111/files_21/ourdev_498225.jpg
(原文件名:DSC00170.jpg)
VB做的上位机
点击此处下载 ourdev_498226.rar(文件大小:153K) (原文件名:相片转换器.rar) 顶!
MARK 厉害厉害!!! 学习!! 感谢分享,标记! 有没有具体教程啊?? mark mark hao 不错 顶一下 mark 强帖,顶 强帖留爪印。 mark 太牛了~顶 牛人,MARK