购物车0种商品
IC邮购网-IC电子元件采购商城
思想与裸编程
(2011/10/27 9:58:00)

先声明一个概念,裸编程,我创造的名词,指的是在裸机上编写程序,裸机,在单片机领域就是指带着硬件的单片机控制系统,不要想歪咯。
在裸机上编程,就犹如在一片荒地上开垦,任何一锄头下去,都会碰到硬生生的石头,要说做这有什么味?拓荒者追求的是来年的绿洲。而我们这些开垦裸机的所谓的工程师们追求的是什么?我们当然追求的是完成一个任务。
我们一般都自称是高级知识分子,那么我们在拓荒的过程中应该想些什么?当然不是想着如何把任务完成,而应该首先想着我们在想些什么。绕了是不?绕了就对了,这一绕就绕出了思想。思想是一个简单的人在一个复杂的环境里做任何事情的统帅,它影响着一个拓荒者人生的每一个细节,当然也包括裸编程本身。
当一个人拿着锄头,一锄又一锄,汗滴脚下土的时候,我们能知道他们在想什么吗?当然这不好说,如果自己去锄就知道了。但是大抵也差不多,随便举几个吧:这太阳他娘的怎么这么毒?这石头他娘的咋这么多?这地种什么最好?这还有多少天能搞完?这样干太慢了,要是有台机械搞多好。当然这只是一部分,任何人可以想出很多想法来。
那么当我们在裸机上拓荒的时候,我们该想些什么?也许我们一般的想法是:先把一个简单的功能做了,先把一个重要的功能做了,今天终于把这个功能调试好了明天可以做下一个功能了,这个为什么不是我想象的那样的结果?真是莫名其妙!也等等一下吧。
如果拿来一个任务,搭好测试平台就开始做程序,想着一个功能一个功能的凑完,然后就自我陶醉着成功的喜悦,那这样做程序,基本就叫做没思想。有思想的做程序,是不能一下去就堆积源码的,因为那样只会让一堆生硬的数字怯生生的挤在一起,不管他们有没有多余,有没有矛盾。所以写源码之前,是要想想如何写的。也许很多人在写之前都想过类似的问题,比如把任务模块化后再组织程序。但是这样的想法只是任务上的事情,而并不是裸编程时的思想,裸编程的思想,应该是在组织任务模块过程中及编写裸程序时影响源码组织的指导思想,它直接决定着源码的质量。
一个数据结构,一个模块形成,一个单片机的指令,一个硬指令的运行机制,一个口线的驱动方式,一个中断的顺序,一个跳变的延迟,一个代码的位置,一个逻辑的组织,一个模块与模块之间的生(运行时的状态)死(不运行时的状态)关系等等,都是裸程序思想的组成部分。
这似乎很琐碎,但是裸程序原本就如此,它不同于上位机程序,有一个强大完善的操作系统支持。单片机里不可能植入操作系统,那样做就变味了,可不要有人跳出来说,某某某单片机就有操作系统了。裸程序就应该是建立在赤裸裸的硬件基础上的程序,只有有用的功能才有代码,裸程序的质量也许经常在应用中感觉不出来,也许你做和他做都能实现功能,但是好的裸程序有良好的可扩充性、可维护性,系统具有高稳定性和高性能。
而追求这种高品位的技术境界,就必须要有好的思想来指导。是不是看着有些迷糊?别说看得迷糊,我说都说迷糊了,总的来说,就是把一个优秀的灵魂,植入你的源码中,让你的源码具有一个优良的思想。

网友评论:其实,在组织显示屏幕和菜单时,使用面向对象的思想也是很不错的想法。我就是从这里开始的。避免在程序中出现大量switch套switch的情况.但是,有一个问题,抽象度越高,层次约多,浪费的物理资源就越多。所以,感激还要根据实际情况,组织程序。

网友评论:唉,论坛里高手真多,以后不要乱吹牛,免得恰到喉咙........
占座位学习,期待父对象的重要意义。。。。。。
我怎么觉得LZ是在讲C++的理念多一些呢

网友评论:面向对象裸程序的例子≡显示器控制程序[连载六]

上帖我们说到dispGetMaxColors()的一些设计思路,我们有很多很好的办法来实现它,但是我们有没有更好的管理办法来实现它,这才是我们要站在更高层次看问题的焦点,是更重要的。这也就是一个从传统思维到面向对象思维的一个重要的转折。
要想把这个函数转变为面向对象的逻辑结构,我们也要先做些准备工作。
首先说参数传递的思想。尽量减少参数传递,这是尊重C51系列8位单片机硬件现状的一项重要措施,记着,不要抱怨C51档次低,资源少,而是要在尊重和热爱C51的前提下,我们才有热情来发展我们的裸程序面向对象思想的,也就是说,无论我们面临的系统有多简陋,我们都有策略,来实现复杂的功能,而且从发展的眼光来看,产品的升级,并不是盲目的升级我的CPU,因为那样只会让产品设计者智商下降,所以我觉得C51的特色就是应该在简洁,越来越简洁,而不是越来越复杂。所以我希望我们把思想升级作为升级产品的一个发展方向。传递参数要减少指针、浮点等类型的数据传递,尽量以UCH与UINT为主,而且参数的数量不要太多,最理想的上限是2个,如果实在多了,就使用共享缓冲区,或者全局变量。最好是不要传递参数,呵呵。
本函数就利用了MonitorType省略了一个参数传递。
其次是我们要让父对象的接口函数与具体的子对象的多种可能性的功能实现剥离,这里我们就需要使用函数指针。函数指针也许我们一般用得少,但是其实并不是很复杂。先看我们函数的形式:
UINT dispGetMaxColors(void);
为该函数定义一个指针类型,只需做如下定义,就可以了:
typedef UINT (*dGMC)(void);
那么对于父对象中的dispGetMaxColors()函数,我们就只需要转换定义一个函数指针,在创建父对象的时候为它提供一个子对象对应功能调用的入口地址,就足够了。所以对于这个函数的实体将只在子对象中出现,而在父对象中只会出现一个变量的定义:
dGMCdispGetMaxColors;
为了给它赋初值,我们也可以定义一个空指针,作为一个未使用的判断标志:
#define NIL 0
那么初始化dispGetMaxColors的时候只需要写条如下语句就可以了:
dispGetMaxColors = NIL;
而且功能调用也很简单,与实质的函数是一样的:
if(dispGetMaxColors!=NIL) vMaxColors = dispGetMaxColors();
如果再加上约定,连前面的判断语句完全可以省略。因为我们的裸程序的程序空间实际上也是运行空间,不存在代码调入内存和移出内存的事情发生,所以我们不需要考虑程序内存的优化问题,只要我们规定对象一定是先创建后使用,判断语句就会变得没有意义,而且我们创建后即使不再使用,函数体我们也不会释放,因为它被放在程序空间内是固定死的,你想移出去,还不能实现呢。
第三,尽量让程序所使用的语法简单化,以减少编译器可能带来的差别而产生的理解上的误区。有人说C51是C的子集,这说法我认为不科学,只能说二者继承了C的基本精神,而在实质上它们针对的是不同的对象,所以也出现了一些不同的结果,所以我看到有些高手或者一些面试题弄出一些题目来让我望而生畏,也许我做一辈子的裸程序也做不出他们的题目,但是我并不觉得我不如他们。他们只不过是在编译器上花了很多时间研究他们的一些约定,而我并不想花时间去研究那些将来可能发生变化的东西,我希望我能用一个更简单的途径把我的事情做出色,我只关心我的项目的速度、代码的大小、运行的效率、维护的复杂度,所以我也建议和我交流的人能用一种通俗的方法来实现我们的功能,也不必过多的考虑我的程序在8位单片机上可以用16位单片机上也可以用,我们的系统要经常升级,但不要轻易去增加硬件成本。当然如果你有精力去研究那些约定,也没什么,只要你乐意。
好了,上面三条,只有第二条是我要说的关键,其他两条各人可以根据自己的具体情况来寻找一些快捷实用的方法。其实说来我们把父对象用函数指针来代替实体函数,这完全是一种思想,我们并没有使用复杂的语法,而是从管理上把对象分离开来,让不同的人做不同的事情,比较容易。但是同时我们又不能让这种中间环节影响我们程序的效率,所以我们完全可以自己寻求一些方法,而不必去循规蹈矩。我这样说也许会遭到一些非议,但是我可以告诉大家,计算机语言这门学科,本身就是一门人造科学,没有最好只有更好,我们没必要完全按照别人的思路去发展设计思想,所以也不要拿着人家的一些约定来引以为荣,那些东西,只有先学后学的问题,没有水平的差异;我们应该更注意的是,人家创造了工具,我们就用工具再来创造世界!如果你停留在欣赏工具的层次上,那就是无所鸟事了!
本帖实质上只说了一个转换,两条建议,这都不是具体的程序,而是思想。我想强调的,也不是格式,而是思想。下帖将再回到对象上,和大家探讨一下对象本身的组织问题,比如对象的层次关系、对象的创建、对象的书写等等,我也希望有人能有一些更好的方法回到帖子里,我们互相学习,共同提高。

网友评论:好!看完了,还是有点模糊!
太概能理解那种思想了

网友评论:

面向对象裸程序的例子≡显示器控制程序[连载七]

前面的思想衍变过程已经说了很久了,面向对象的思想也就到了瓜熟蒂落呼之欲出的境界了。下面我就先图示一下裸程序设计中面向对象思想的层次关系:
[img][/img]
相信这张图已经足够说清楚我们在Keil C中如何用语言来组织我们的显示器对象disp了。disp是一个抽象的对象,它只是一种联系,完成对所有子对象d000、d001、d002到最多d255的归纳概括并提供一组被调用者所使用的功能接口。这些功能接口正是上贴所提到的函数指针。而具体的功能实现及不同显示对象对数据结构的要求,我们都可以交给子对象设计工程师自己去决定。
很显然,大家在这套方案具体的程序设计过程中,最主要的精力还是要放在自己做自己的问题上,多思考如何把事情做得更漂亮,而不必在代码编写时黏糊不清。父对象设计者必须要完成总体方案的设计,抽象思维多而具体工作量少,子对象的设计者则恰恰相反,只需要多考虑考虑具体的设计,而不必去担心别人是怎么用自己的东西。
很显然,作为总体设计者,必须要严格考虑这中间的数据交换关系,因为我们没有操作系统,所以对于可用的内存资源的使用法则,直接关系到我们整个系统的成败,混乱使用常常会导致系统崩溃,相对独立的代码则在编译过程中由Keil C直接安排好了,我们不需要去考虑它们对程序的影响。
例子中的显存大小及显存的位置都是我们方案成败的关键。我们都知道Keil C对单片机内存划分了四种,即data、idata、pdata、xdata四种,各种存储器的大小与特点都决定着我们代码的运行效果,我们既要考虑信息所需要的空间,又要考虑单片机处理时足够达到我们的视觉要求。在这个例子中,我觉得我们可以选择xdata来作为显存。为什么呢?因为我觉得只要我们处理得当,我们的单片机完全可以克服处理速度上的缺陷,所以我们可以优先满足信息量的要求,提供足够多的空间来实现我们想要的功能。
提速的方式有很多,比如:选择一些性能优越的新型单片机,传统的是12T的,现在有6T的,也有1T的,这让很多指令都会有更高的效率;适当的提高晶振频率;选择更科学的算法;等等。
好了,本帖先到这里吧,又觉得写多了。到目前为止,基本上可以去构造我们的对象了,如果你有兴趣,你可以使用#define进行一些伪码定义,把我们的对象定义得更美观一点,更接近C++一些,不过我要说的是:我们这里没有严格的类定义,所以定义时类与对象经常是没有界限的。

网友评论:面向对象裸程序的例子≡显示器控制程序[连载八]

用基本C来构造一个对象,我们必须要多摸索摸索,因为没有语法支持。但是我们不必抱怨,因为有些支持,C编译器做和我们做,效果都是差不多的。
构造对象我们首先要遵循数据与函数分开的原则,这样对我们创建新对象很有好处。也就是说我们把对象中的函数,都要写到与具体数据无关,那样当我们需要2个或2个以上对象时,我们只需要把数据重新复制一份,而具体的处理代码却不必重新写,这样我们就可以争取用最少的代码而获得最多的功能。
我很怕罗嗦的语法结构,所以我在上帖中希望有人能回我的帖,把上面的例子用语法总结出来,很遗憾却没有,我想偷懒都不成,所以只好把原来的帖子一个一个的翻出来再读。写说与伪指令相关的事情。看下面的例子:
#define Class(c) struct c
#define Object(o,c) struct c o
这两个伪码就会把我们的裸程序搞得挺象个C++的样子,其实也就是欺骗一下看官的眼球而已,如果你不屑一做,那就直接用struct也满好个。有了这两个定义,我们就把前面例子罗列一下,形成一个对象的样子来。
还有几个函数指针类型我们都把它们定义出来(下面定义忽略了参数定义):
typedefvoid(*dSAC)(……); // 显示一个字符指针类型
typedefvoid(*dSAL)(……); // 显示一行指针类型
再定义类:
Class(disp)
{
UCHMonitorType; // 数据变量定义
:
:
:
dSAC dispShowAChar; // 功能变量定义
dSAL dispShowALine;
:
:
:
};
相信这样已经足够说明问题了,这个类就是定义了一个对象所需要的全部数据,凡是涉及到代码的都可以作为同一类型的不同对象共有的财富,共同使用。比如我们要在我们的裸系统中企图同时支持最多两个显示器,那么我们就只需要创建两个对象,其实这里说的创建语法也很简单,就说定义两个变量好了,然后赋初始值给它,这就是创建。
先定义:
Object(FD000, disp); // 定义对象FD000,关联子对象D000
Object(FD001, disp); // 定义对象FD001,关联子对象D001
然后通过赋予初始值来创建它,这里再引入一个伪定义:
#defineCreateObject (o, mt, sac, sal){ \\
##o.MonitorType = mt; \\
##o.dispShowAChar = sac; \\
##o.dispShowALine = sal;}
这样我们就可以象模象样地使用我们的对象了:
CreateObject(FD000,0,soShowAChar000,soShowAChar000,soShowALine000);
这条语句创建了一个缺省显示器的父对象,其中so-是sub object的缩写,000是为编号为0的缺省显示器所安排的编号,最后一个是255,因为Monitor是UCH类型,所以最多可以建立255个类型的显示器。soShowAChar000、soShowALine000为缺省类型的显示器的具体处理函数的名字,函数体在子对象D000中去组织。
同样的方法我们为我们的裸程序创建另一个对象:
CreateObject(FD001,1,soShowAChar001,soShowAChar001,soShowALine001);
当然这个CreateObject只是一个例子,因为我们这个创建工作可能会有很长的参数,那么有丰富编程经验的高手,您是愿意如何组织您的创建过程呢?我想我没有必要在我的思想里去弄一个严谨的格式,思路是没有清晰路线的,它具有很大的延展性,只要能胜任“合理”这个词,您就可以大胆的去做。
本帖的最后我想提出一个问题:MonitorType将何去何从?

网友评论:面向对象裸程序的例子≡显示器控制程序[连载九]

上帖说到的对于对象在Keil C中的一些构造,用到了一些#define所进行的一些伪定义,这些定义其实并没有多少真正的意义,唯一的意义就是让我们的语言看起来更象个面向对象的语言。
面向对象的语言中,变量或函数的作用域分成三类:public、private、protect。这分类主要是处理语言模块的封装问题,其直接表现的效果就是变量或函数能使用的范围。protect类型在我们这里可以不予考虑,因为我们并不十分强调继承关系,而只是统一都称为一种文档的组织关系#include。
而对于public与private则还是有比较方便的办法实现的。对于public,我们可以使用extern来进行定义,或者什么定义都不带,在#include后面的范围内都是有效的。所以要定义一个public非常容易,只要做下列定义就可以了:
#definepublic
或者
#definepublicextern
就可以了。
对于作用域的限制,还有一个重要的限制就是哪些变量用什么办法约束起来,从而成为一个属主的私有成员。
当然,这样的约束,写在一起,是个好办法。说实在的,只要你有足够的精力,即使不写在一起,只要不搞错,又有何不可?只是我们为了减少不必要的麻烦,所以我们总希望我们的代码只花我们尽量少的精力,那才是最理想的,那么我们就肯定要首先要求把它们写在一起,然后我们还希望它们不仅仅是只在一起,还希望编译器真正认为它们是被我们创建的某个对象私有的,那么我们就可以使用static来进行约束。全局静态变量或函数的定义,可以将该变量或函数的作用域限制在本文档内部,这就是一种私有性。因为我们完全可以做到在一个文档中只书写一个对象。因此我们就可以如定义public一样来定义 private:
#defineprivatestatic
那么这样我们就可以为对象书写一些私有成员,如:
privateUCHsoCursorPositionRow000 = 0;
privatevoidsoSetCursorPosition000(void);
如果我们并不想用这么多的private来限制这些成员,那么伪限制也是一种好办法,也就是说只是在书写格式上告诉看官,我的这段定义是私有成员,那么我们可以做如下的修改:
#defineprivate
#definepublic

private
UCHsoCursorPositionRow000 = 0;
voidsoSetCursorPosition000(void);
public
voidsoShowAChar000(void);
voidsoShowALine000(void);
这样写没有定义任何变量的作用域,而只是为代码加上了一些欺骗眼球的伪码,这样做其实对程序实质没有任何帮助,但是得益的是我们程序设计的思想。也许我们只用了一两个很简练的伪码,却表达了很深奥很深奥的逻辑寓意——这是一段表达对象的代码,你不用做任何注解就明了的代码。这其实也正是思想的精髓所在,你把一团乱麻理顺了,你把一盘散沙促拢了。
表达对象思想的书写中,封装是一个很重要的组织概念,封在一起的是一个整体,就如人家端个显示器给你一样,你不要管里头的电子束是怎么射出来的,一共有几颗螺丝钉固定着显象管,你所要关注的,只是那些接头和按钮。
static在封装中还可以起另一个作用,就是为某一个功能封装一个隶属于该功能的局部变量,你可以对该变量进行初始化,但是你在实际应用中你不能感觉到它的存在,它的生命周期是无期的,但是拥有它的函数却可以生死轮回。下面是一个调节亮度的例子:
#defineBRIGHTINC1
#defineBRIGHTDEC0

voidsoAdjustBright000To(bitBrightInc)
{
staticUCHBright = 32;// 初始化:最大亮度为64,初始化亮度为32
if(BrightInc)
{// 亮度增加
if(Bright<64)Bright++;
}
else
{//亮度减少
if(Bright)Bright--;
}
}

网友评论:写得好!

网友评论:看不懂,先做做记号,等懂了,再给你回个话.

网友评论:很棒哦,还有原创性,支持啊!

网友评论:我感觉很抱歉的是,此帖以后添加的速度将会减缓,一个是工作上有时候会要忙,另外是正准备把这个思想系统成书,对本帖的思想进行更正规的描述,旨在唤起我们追求技术的热情,引导更多的人用正确的方向来指导我们获得更多的成功,在此过程中,我会逐渐添加一些新的内容,也希望广大同仁与我一起探讨问题,谢谢大家的关注,非常感谢!

网友评论:关注下

网友评论:再写一点可以出书了,呵呵~

网友评论:

好帖!这样思路上的指导远比具体的实践指导更有实际意义。

知其然不知其所以然是很多人的毛病,会用就行了,自我满足了,而不去追根求底不去想怎样能把事情做到更好。

我一直觉得大道不传是因为传不了,因为大道理是很难用语言来表述清楚的。我们的语言有时候是那么的苍白无力,交流上的匮乏使我们民族有太多的优秀文化思想无法流传下去。

楼主的帖子不仅仅能应用在单片机开发设计上,更可以广泛的应用在日常的生活中、我们处理生活事物当中去。

从裸程序开发说出去,扩展开,是本文的一个特色,更是千古丰碑的一篇文章。

看到这样好的文章,我实在不甘心放弃一个签名的机会。同时也希望楼主不要辜负大家的期望继续更新下去。

最后问一句,下一章啥时候出?您快点啊,大伙都等的特着急啊,不赶紧更新对不起党和人民还有21IC广大的网友啊~~~啊~~~

网友评论:又学习了 多谢 多谢

网友评论:

裸编程的思想,应该是在组织任务模块过程中及编写裸程序时影响源码组织的指导思想
不晓得和模块化编程有啥子区别?
面向对象只是听说过,还没用过,还是有点看不懂

网友评论:写得好,不过好多地方不明白,平常一直觉得有点意思的就是用结构体封装,似乎有那么一点面向对象的意思,但是在分析任务时,头脑里全是面向过程的,新手之言,请砸砖

网友评论:最近工作上忙着改产品,所以没时间来忽悠,不过我会经常来关注一下朋友们的回帖,然后致力写一本系统性的书,尽量增加思路分析的例子,并增加例子的代表性与广泛性,力求让大家都能轻易看懂,如看小说一样的具有可读性,谢谢朋友们的支持

网友评论:阳春白雪和着盖寡。
问:先生是做什么的?
答:玩单片机的。
问:单片机--------什么玩艺儿?
答:是玩思想。
问:-------------??

网友评论:做个记号!回头来学习!

网友评论:好好学习天天向上

网友评论:写的好

网友评论:支持,顶...

网友评论:先顶后看
呵呵

网友评论:怎么没啦!呵呵!学习学习,现在正好可以用上这种思想中的一点点!还不会用

网友评论:要用就用C++好了,单片机没有C++的就用ARM好了。

网友评论:随着单片机性能越来越高,编程思想也在转变。
话说,为了通用,必然要牺牲性能

网友评论:跟高焕堂写的oopc意思差不多。

网友评论:顶!继续

网友评论:很琐碎的说

网友评论:很有思想。

网友评论:看了一次不是很清楚,再看看

网友评论:c++,最近在看。。

网友评论:这中思想正是我追求的,支持~





1#

网友评论:占位

网友评论:收藏啦

网友评论:顶。。学习中。。。

网友评论:可以借助面向对象的思想

网友评论:听课,学习中。

网友评论:听课

网友评论:没有c++,楼主在c语言上像三脚猫一样跳舞.

建议大家用c++去学习,然后回到c语言中体会如何实现.
这些东西在软件工程和构架里面的基础.学计算机的都很懂.

刚完成一个10多人年的项目.

网友评论:占个位,好好看看!

网友评论:来看看,

网友评论:占个座

网友评论:有此等高人为后辈铺路,实乃幸事也!

网友评论:学习。

网友评论:顶一下

网友评论:好贴,顶一下!

网友评论:经验之谈,顶!

网友评论:顶 顶 顶顶顶

网友评论:读了,思考一下,想一下,消化一下,转化一下。

网友评论:有党的风范

网友评论:自我陶醉吧

网友评论:
没有c++,楼主在c语言上像三脚猫一样跳舞.

建议大家用c++去学习,然后回到c语言中体会如何实现.
这些东西在软件工程和构架里面的基础.学计算机的都很懂.

刚完成一个10多人年的项目. ...
icecut 发表于 2010-8-31 13:35
没想到这个帖子还在活跃。C++尽管在思想上是一种成熟的技术,并配有编译器的支持。但是C++同时还约束了自由行为思想。
你尽管懂了C++,但是不懂得中国现状与开发心理。在C++里抽象对象比自由抽象对象要难得多,而且单片机是从**做起的,而C++就是一层浓雾,让开发者常常迷失在这层雾中。
我这帖正是抛弃了这些语法约束,直接使用人人皆知的普通C语言,来达到同样的目的,只需要转换一下思想就可以了。最主要的是,这种做法更自由,开发者可以自己控制硬件资源的分配情况,而不必去学习更抽象的资源分配理论。

看你对C++比较熟悉,也做了大项目,这是好事,有高级语言的使用资本。但是这资本并没什么好炫耀的,因为我相信懂C++的人一定很多,但是在单片机上用C++,我认为还不如用C,因为我觉得,把内存调度交给编译器,不如控制在自己手中灵活。我也很少在帖子里去推崇C++,也是这个道理。而且我过去是做计算机软件的,也从没想过因为自己用过了面向对象语言就去贬基本语言,因为C++并非什么地方都适用!

谦虚是进步之本!你可以炫耀你的项目,但是不要炫耀C++,因为那根本与你没什么关联。

网友评论:强烈支持。

网友评论:嗯,81楼说得太好了,其实在写代码的时候,我们并不想知道模块内部是怎么操作的,但是,在运行的时候,每一个地方每一个角落我们都想知道内部是怎么操作的,使系统完全掌握在自己手中。

网友评论:楼主太强大了,膜拜啊。。。
但是太多了,先复制下来,今后有空再慢慢看

网友评论:楼主人才。。顶起

网友评论:体会一下编程思想来了

网友评论:此贴必须要狂顶
俺先收录了俺正在研究不知对俺有没有好处 先收录好东西不能错过

再次顶作者

浏览:(861)| 评论( 0 )
博文评论

  • 昵 称:
  • 内 容:10~250个字符
  • 验证码: 验证码看不清楚?请点击刷新验证码
  •                      
  • 博文分类

    热点博文

    最新博文

    最新评论

    IC电子元件查询
    IC邮购网电子元件品质保障