矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
查看: 112283|回复: 249

帮助新手学习单片机数码管电子钟:原理,c程序详解

  [复制链接]
发表于 2011-4-17 11:46:57 | 显示全部楼层 |阅读模式
这个帖子意在帮助有兴趣的初学者理解单片机驱动最基本的LED数码管电子钟的硬件原理,以及如何用c编程实现。图和代码是实打实的东西。这些内容对于仔细学过单片机的和会搞的人就不必浪费时间了。为了保持连续性,请勿跟帖。
实物图:重点是显示效果如下:
clock.jpg
硬件主要部分电路:
FIG.JPG
从以下几个部分解析:
1,8段led数码管的原理
2,单片机如何动态驱动多个数码管
3,单片机怎样构成电子钟
4,怎样用c语言编程
5,程序代码详解
1:8段led数码管的原理:再复习一下
    LED::发光二极管大家都用过吧?直流电源,串上限流电阻,再串上LED就成了一个小电灯,
   8段数码管就是把8个LED按数字“8”的笔画安排,使各个LED按要求发光就形成数字或其他符号了。见下图:
txt1.JPG

这个8字数码管由7个LED构成笔画,另一个LED为小圆点。这8个笔段通常以a b c d e f g h 表示,这个位置是固定的。
用电路图表示在右边。注意,数码管都是由笔段电极和公共电极构成的,而按制造时的内部接法不同分为共阳极和共阴极两种,看图就明白。老式单片机,吸收电流能力较强而吐出电流较弱,用共阳极接法多些。 新式单片机两种都可以用。
对于共阳极接法,单片机的口线通过限流电阻和LED的笔段电极--阴极连接,正好一个8位口对应一个数码管的各段,公共阳极因电流较大,超出单片机的驱动能力所以另外用一个晶体管控制,这个晶体管的基极则另外用一个口线控制:显然只有这点为0才能使得数码管发光。设a b c d e f g 均为低,h为高,则显示不带点的8字。
共阴极数码管则相反,只有笔端电极-阳极为高,公共电极:阴极为低时才能显示。显然这个制作用的是共阴极数码管。下面,列出共阴极管显示各个数字时笔段电位高低的关系,也就是让单片机的一个8位口设为P0口,如原理图,和笔段对应时的驱动二进制数据对应的16进数和显示的字形:举例说显示2,要让P0口输出十六进数0X5B
P0.7    P0.6    P0.5    P0.4    P0.3    P0.2    P0.1   P0.0
h         g          f         e         d         c         b         a
0         0         1         1         1         1         1         1         ==0X3F  显示“0“
0         0         0         0         0         1         1         0         ==0X06           1
0         1         0         1         1         0         1         1         ==0X5B           2
0         1         0         0         1         1         1         1         ==0X4F           3
0         1         1         0         0         1         1         0         ==0X66           4
0         1         1         0         1         1         0         1         ==0X6D           5
0         1         1         1         1         1         0         1         ==0X7D           6
0         0         0         0         0         1         1         1         ==0X07            7
0         1         1         1         1         1         1         1         ==0X7F            8
0         1         1         0         1         1         1         1         ==0X6F            9
0         1         0         0         0         0         0         0         ==0X40           —
此外还可以显示A b  c  d   E    F    G    H    L    P等,就不列举了。
另一点,上面小点h始终不显示 ,怎样显示它呢?以后用到再说,一般用它较少。好了休息一下。

评分

6

查看全部评分

 楼主| 发表于 2011-4-21 14:43:39 | 显示全部楼层

用C语言编程

有关C语言的书籍很多,其实也用不着我来多嘴,不过是想救自己自学C的一些体会来说道说道,对老鸟毫无意义,对新手可能有所帮助,要深入钻下去,还是看书吧,我这里是尽量用通俗理解说清楚一点,即使一下还不会用C编程,如果能看明白C的代码也好啊。事情总是一步一步,首先别怕,人家都能做出来,做出来就是给人用的,只要花力气,一定能学会。
1,为什么要用C。原因很多,既然大家都用,自然有好处,最大的好处就是它的基本语法对于不同的单片机都能用,只是具体细节不一样,而汇编对于不同的单片机完全没有通用性,其他就不多说了。
2。快速了解C语言
2。1.构成C语言的主要基本零件:
数据:数据类型,常量和变量
运算符,表达式:用他们来操作数据
函数:通过运算符、表达式和数据一起来完成所需要的功能。注意C语言只有函数,没有子程序。
2.。2 C语言的基本框架
下面逐一说明。
C语言的数据,计算机语言处理的就是数据,C语言也一样。
在程序中不变的数据是常量,在程序中可改变的数据是变量
为了限定常量和变量的取值范围,我们要用数据类型来说明。在51的C,简称51C,数据类型有:
字符型:char   :长度1字节(8位二进数)分为
有符号字符型  signed char  取值范围-128~+127
和无符号字符型 unsigned char 取值范围 0~255
默认为有符号型(不用加signed)
使用最多的是无符号型,必须加以unsigned 说明。例如 unsugned sec:这里sec就是一个变量,它是无符号字符型的,取值最大只能到255,如果写出sec=500;意思是给sec赋以数目500,那就错了。对于更大的数,我们使用
整型:int   :长度2字节(16位二进数)和字符型类似也有
有符号整型 (默认)取值范围-32768~+32767
无符号整型  unsigned int    取值范围 0~65535    例如unsigned int  sou=7850;正确,变量sou既然是无符号整型,它可以达到7850没问题。再大的数据就要用
长整型 :long   :长度4字节 (32位二进数,赶上电脑了)也有有符号和无符号两种
有符号长整型  (默认) 取值-2147483658~2147483647
无符号长整型  unsigned long  取值 0~4294967295 为了表示小数,还有
浮点型  float  :长度4字节,可表示7位有效十进数。运算中还有
指针型 *  长度1~3,它还具有上述类型。 51C还有一些独有的:
位标量 bit 只能取值0或1 ,例如 bit  yn 只可以 yn=0;或 yn=1,别看它简单,程序中这个很方便
可寻址位 sbit 用它来访问可寻址位,如sbit  P11=P1^1;用P11来访问P1口的P1.1,这个也用得多。
此外还有特殊故功能寄存器的sfr 和sfr16使用较少就不说了,使用最多的还是
unsigned char 和 unsigned int
常量:分为
整型:例如 123     -8   0xf9  0b 1110 0011 都是程序总就是以数字出现
浮点型   例如    123.45   75e3
字符型   例如‘A'    'a'    有单引号,注意C的大小写有区别,不可随意
字串型  例如"About U "  "V" 用双引号,V加了双引号尽管只有一个字符也是字串型的
变量类型上面都说了,在程序中,我们可以自己定义一个变量,然后使用它进行运算。
例如  先定义unsigend min ;unsigned sec
然后使用:min=sec-60等等。决不可未加定义就直接来一个sta=7..
完整地说,要定义一个变量,得给他戴上3顶帽子:
存储种类  数据类型  存储器类型  变量名
例如  static  unsigend char  data  num, 变量num是静态的,无符号字节 内部数据存储器
一般不用这多,存储种类就默认为auto不用写,unsigned char必不可少,存储器也不用指定。除非用到外部存储器等等,就不多说了
虽然说,用一个或一些字母就可以表示变量名,但是也不可任意为之,因为有些字是专用的,例如不能用数据类型int做变量名,类似的还有一些程序语句里的关键字,都不能做变量名,变量名除了大家常用的例如i 、 j   还可以用具有意义的便于记住,或者用汉语拼音也行,还要注意,变量名可以以字母打头,也可以用下划线打头,但是不可以数字打头。例如
unsigned  xy;     unsigned _23al;都可以,unsigned 5d就不行。
下面说C里面的运算符,表达式和语句,用他们来操作变量、常量,得到我们所需的结果。

[ 本帖最后由 wey05 于 2011-4-21 17:23 编辑 ]

评分

1

查看全部评分

回复 支持 2 反对 0

使用道具 举报

 楼主| 发表于 2011-4-17 15:15:16 | 显示全部楼层

继续

市面上买到的数码管,除了尺寸不同(驱动电流不同)以外,有单个的,双联体的,四联体的。单个的就是8个段电极和1个公共电极了,联体的,各个数码管的对应笔段内部已经连接好,也只有8个脚引出,各位数码管的公共电极则分别引出,例如4联的,一共有12根引脚。那又有什么区别呢?
单个的数码管,可以用于静态显示,也可用于动态显示。
多联的数码管只能用于动态显示。
所谓静态显示,就是数码管段电极接到一个硬件锁存器上,单片机控制口如P0,顺序输出各个数码管对应的驱动码,驱动码被分别锁存起来,再推动数码管。只要锁存器不变,数码管显示就不变。如有8个数码管,就有8个锁存器,它们同时可以显示8位不同的数字。这样的显示,明亮而稳定。但缺点就是硬件电路复杂了。但如果采用 串入并出的锁存器,可以减少单片机所需的口线,对于口线紧张的情况(如使用2051)有时还是要采用的。下面说说
2。单片机如何动态驱动多个数码管
所谓动态显示,是让几个数码管轮流显示,每一时刻只有一个管子点亮,其余都必须熄灭。方法是首先把所有数码管的公共电极电路都断开,这时大家都不显示,然后单片机输出字段数据,(例子是P0口),然后开通需要显示的数码管公共电极,这个管子就亮了。其他管子尽管也加上了相同的字段数据,但是他们的公共电极都还关着,当然也不会亮。拿这个例子来说,如果在P0口输出数据0X4F,也就是01001111,然后P2口输出0X01也就是0000 0001也就是P2口只有P2.0为高,其余都是低,那么Q8导通,最右一个(最低位)数码管就点亮:最低位或个位就显示“3”。
接下来P2口输出0,这个管子就熄灭了。大家一片黑。P0口输出0X5B。(数字“2”的笔段码),然后P2口输出0X02,也就是00000010,P2.1为高。.于是Q7导通,十位就显示数字“2”。
就这样一位位地显示下去,直到最高位,然后又从最低位开始。周而复始。只要每个管子点亮的时间较短,整个显示过程很快,那么由于人眼跟不上数码管亮灭的快速的变化,就可以显示出完整的数字了
一般,每个数码管只要点亮4毫秒,8个管子从头到尾依次亮灭一遍需要32毫秒多,1秒钟能刷新30多次,这样虽然也还有少许闪烁感,但显示已经很清晰了。
在动态显示的情况,数码管愈多则在完整的显示周期中一个管子分得的时间就越少,而使平均亮度降低为了显示清晰,管子的限流电阻就要减小,驱动电流就要增加。所以显示位数也不能够增加太多。一般8位是没有问题的。
上上面举例是从右往左依次显示,反过来行不行呢?当然可以。不过还要结合具体的应用条件决定,这个等到编程时再说。

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-4-18 11:05:57 | 显示全部楼层

接下来

好了,现在如果用8个数码管显示电子钟,各个数码管承担的任务就可以按照我们的要求安排了。以本实例说,从右至左依次是:秒个位,秒十位,分个位,分十位,横线,小时个位,小时十位,空白备用。比如说要显示45秒,那并不是说在P0口输出数据45然后依次开通秒个位和十位,而是:先把数字45分解为两个单独的数字4和数字5,然后找到他们所对应的共阴极数码管显示码:4对应的是16进数0X66(2进数0110 0110),5对应的是0X6D(2进数0110 1101),然后在P0口输出数字5的显示吗0X6D,P2口输出0X01,晶体管Q8开通于是最低位数码管显示“5”。持续一小会例如4毫秒,P0口输出0X00,不显示了,乘机P2口输出0X02(2进数0000 0010)开通Q7,再给P0口输出数字4的显示码0X66,此位显示4了,再持续4毫秒。。。于是时分秒就动态显示出来了。
然而我们做的是电子钟,时分秒要随时间按规律变化,因此下面就说说
时间信号源
单片机电子钟一般可以使用专用实时钟电路作为时钟源例如最常用的DS1302,优点是走时精准,加上后备电源(小电池或法拉电容)在单片机停电时依然正确走时,还有日历功能。不过它牵涉到对电路编程,这次就不说了。以后如果大家有兴趣专门再讲。再一个方法就是利用单片机自身的资源,通过软硬件结合,产生秒信号。有了秒信号,分和时就好办了。正好这个52单片机内部有3个定时-计数电路:定时计数器T0,T1,T2。作为定时器使用的情况下,它按照单片机的工作节奏:机器周期计数,而机器周期是依赖于精准的石英振荡器产生的振荡周期的,传统的AT89S51单片机,用12兆晶体时,机器周期是1微秒。STC89C52RD,用12兆晶体时则可以使用1微秒或0.5微秒两种。不过由于STC单片机为了保证串口编程速率没有误差,使用的是11.0592兆赫的晶体,这样机器周期就要长一点。这个必须须记住的。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-4-18 18:13:43 | 显示全部楼层

3.单片机怎样构成电子钟

任何一个钟,手表也好,大本钟也好,有三个部分:心脏=走时机构,脸面=显示装置,再加上调节装置:对表。
以上所说,是数码管的基本显示原理。下面再仔细说说具体到这个电子钟的显示安排。
由图可知,8个数码管从右到左,分别是秒个位,秒十位;分个位,分十位;横杠;小时个位,小时十位。还剩下最左一位备用。
按现在的动态显示方式,是从左到右一个个轮流点亮、熄灭数码管,周而复始。对于具体的一个时间值例如10时35分24秒,在显示前先要把时分秒分别拆开为十位数和个位数,要显示哪个数,除了开通对应数码管的公共阴极,还要给字段电极加上这个数字的显示码。对照原理图,过程可以是这样的:
首先P2口为0,当然P2.0到P2.7都是0,数码管全部关断,漆黑一片,准备显示。
P2口为0x01,这时仅仅P2.0为1,Q8开通。然后P0口输出0X66——数字4的显示码,最低位立即显示4。维持数毫秒,然后P0口输出0,管子灭了。趁机把P2口输出0X02,仅仅P2.1为1,Q8关闭,Q7开通,然后P0口输出数字2的显示码0X5B,秒十位显示2了。就这样,轮流把P2口的各位输出1,然后P0口加上显示代码并维持一会儿,最后就动态地显示出完整的时间数值了。注意,在转到下一个显示位置前,先关掉显示代码。下面说说怎样用单片机的定时器取得时间源。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-4-19 00:50:41 | 显示全部楼层

怎样使用定时/计数器:16位定时器

51单片机有2个16位定时计数器C/T0和C/T1,52机还多一个C/T2有控制串口的作用先不管他,C/T0 和CT1既是计数器又是定时器,怎么说?它的工作方式可以人为改变的,如果它输入的是P3.4引脚上的脉冲,那么就对这些脉冲计数计数值送到16位(二进位)寄存器TH0(高8位)TL0(低8位)中,如果它输入的是单片机的机器周期振荡脉冲tm那就成了定时器。下面用一个简化图表示它是如何工作的
timer.JPG

外部脉冲计数器这次用不上,用的是定时器,图中画的是C/T0,C/T1也是一样,但是C/T0和C/T1的工作都是受特殊功能寄存器TCON和TMOD控制,这个只有一套,然而计数器则各是各的图上画的是TH0和TL0,对于C/T1则它有TH1和TL1。
我们知道,机器周期是石英晶体振荡器分频而来,这个东西是比较精准的,频率误差一般在5-20ppm甚至更低,51是晶振12分频,STC机也可选6分频,甚至有单周期(不分频)的高速型,以12分频为例,假设晶振是12兆的,那分频后的机器周期tm就是1微秒,如果计数4000次就是4毫秒,用它来控制前面说的数码管显示倒是不错,而且计数40000次就是40毫秒,经过250个40毫秒是多少呢?1秒!干嘛是40毫秒呢,一次连续计数1000000,不就是1秒吗?不行!因为16位计数器最大才能计数65536,计数40000还在其范围内,要计数1百万那相差太远了。
要是定时计数器CT0(CT1也一样)工作起来,就要正确设定控制它的特殊寄存器TMOD 和TCON,还要给TH1、TH0正确的预置值,最后再使它工作。先看TMODE和TCON:如上图所示,TMOD的高4位控制C/T1,低4位控制C/T0.就以C/T0说事,
最低位M1M0是工作方式选择,这两位00:方式0,13位计数,01:方式1:16位计数。10,方式3,自动加载8位计数,11,方式4;两个8位计数器,现在我们使用16为计数器,所以M1为0,M0为1.
C/T为0时机器周期脉冲可以进来计数,那好,把它置0.
GATE位为0时允许计数开关闭合。所以置它为0。现在只要把TCON寄存器的TR0置位1,计数通路开关就闭合上机器周期脉冲就能够进入计数TL0-TH0。.可见设定好这两个寄存器的相关位,定时器就可以跑起来。但是定时时间长短,就要给TH0]TL0正确的预置值。
假如预置值是0,那么显然定时时间是65.536毫秒(12兆晶振)预置值是65534那么一个脉冲就把它装满再来一个脉冲就溢出中断了,两个脉冲之间的时间就是1微秒。一般来说,可以用以下公式计算预置值:
TH0=(65536-tx*f/1200000)/256
TL0=(65536-tx*f/1200000)%256,
上式中,tx是定时时间,微秒;f是晶振频率,赫兹,特别是STC使用的晶振为了满足串口下载0误差,通常是11059200的。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-4-19 15:32:35 | 显示全部楼层

使用定时器的要点

如上所说。使用定时器就是1:设置相关寄存器,2:设定预置值。例如,使用T0作为16位定时器,定时时间40毫秒,T1作为16位定时器,定时时间4毫秒。
TMOD:它的各位应该是:
D7—-T1的GATE:0
D6— T1的C/T:0
D5— T1的M1 :0
D4— T1的M0 :1(16位计数M1:0 M0:1)
D3—-T0的GATE:0
D2— T0的C/T:0
D1— T0的M1 :0
D0— T0的M0 :1(16位计数M1:0 M0:1)
综合起来,TMOD的设置值是00010001,16进数就是0X11。
TCON:只有TR1控制T1的启动计时,TR0控制T0的启动计时,什么时候需要启动计时器,就把这两位分别置1即可,要停止计时,就把这两位分别置0。.
定时器的中断:当定时器使用方式1、方式2的时候,一旦TH1、TL1或TH0、TL0装满,再加一个计时脉冲就会“溢出”,TH1 TL1或TH0 TL0会被清除掉,先前放进去的预置值也没有了,这时定时器会使得TCON的TF1或TF0置位为1,通常我们都是把定时器设为中断工作方式,这时会引发定时器中断,单片机会暂停其他程序的处理转而处理中断程序,一般中断程序是很小的,编写时主要是重新充填预置值,以及发出检测信号等,随即结束中断程序还原先前运行的程序。
为了使用定时器中断,还必须在启动定时器(置位TR1或TR0)之前,设置好中断控制寄存器IE。在IE中,只需设置ET0位:T0中断、ET1位:T1中断和EA位:总中断即可。
寄存器设置就这么多,下面按要求,T0定时40毫秒,使用11.0592晶振,按以上算式:
TH0=(65536-40000*11059200/12000000)/256=112=0X70;
TL0=0
T1定时4毫秒,晶振相同则
TH1=(65536-4000*11059200/12000000)/256=241=0XF1
TL1=(65536-4000*11059200/12000000)%256=154=0X9A
实际上编程时这样的常数计算可交由编译器去完成,所以只要列出式子便可。
最后,再说说调校按键的原理:
从原理图上看P1口的P1.2和PI.4分别接有按键K1、K2用来调整小时和分钟,为简单计省去了调秒的按键。
它的工作是:首先PI口输出高电平,按后检查P1.2和P1.4的引脚:如果为高,没有按键,如果为低,有键按下。通常的按键处理,是延时10毫秒再检测电位,目的是避开由于按键未达到稳定状态会因弹跳发生的多次短暂通断。这个例子就是利用数码管扫描的时间来达到延时目的:亮一个数码管后检测按键,如发现按下就计数一次,下一个数码管再捡测,辱国检测5次都是按下则确认为按下,转去把小时或分钟加1。至此,数字钟的基本原理就说完了,下次就看看怎样通过C语言编程把这些功能都组织起来让它有规律地工作,首先我们需要了解程序流程。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-4-20 18:06:21 | 显示全部楼层

程序流程

程序流程是我们编程的依据,按照流程可以理解单片机的工作循环,否则上来就是一堆代码,要看清楚不是很容易的。单片机都是循环工作。主要理解他是怎么循环的,看下图:
bloc.jpg
左边就是主要的工作循环。开机后,首先初始化,给各个变量赋值,其中还有一个自检过程。以及设置定时器并加以启动。
然后进入程序循环。在循环中,单片机要顺序查询显示时间4ms到了没有,到了就要移入下一位数码管显示,移位后再检查40ms定时。否则直接检查40ms定时。如果定时已到,就处理时间累加以及时分秒递增。然后查询按键K1、K2就这样周而复始。而两个定时器在初始化启动后,就进行定时,时间一到就触发定时中断,设置定时标志以供主循环查询,同时还要恢复预置值并进入下一轮定时。
按键检测,先看电平高低,高:无键,低:有键。这里不另设延时,而按照显示移位循环5次后还为低,就是确有按键,转入按键处理。整个流程还是比较简单的,
回复 支持 反对

使用道具 举报

     
发表于 2011-4-21 03:41:59 | 显示全部楼层
插个队。顶你一下讲得如此详细。
回复 支持 反对

使用道具 举报

发表于 2011-4-21 05:18:18 | 显示全部楼层
TH0=(65536-tx*f/1200000)/256
TL0=(65536-tx*f/1200000)%256,


a lot simpler than that:

#define F_XTAL 12000000ul //xtal for a 12-state 8051
#define MSB(word_t) ((word_t) >> 8) //msb of a word
#define LSB(word_t) ((word_t) & 0x00ff) //lsb of  a word

period=(F_XTAL / 12000000) * tx; //period for the timer
TH0 = MSB(-period);  //load the msb for a count-up timer
TL0 = LSB(-period);  //load the lsb for a count-up timer

you will also find that 1) you can improve long-term timing accuracy by a) using auto-reloading (mode 2); or b) using the Roman Black approach - google for it; 2) you need to implement a way to correct for xtal inaccuracy.

hope it helps.
回复 支持 反对

使用道具 举报

     
发表于 2011-4-21 08:48:23 | 显示全部楼层
怎么不用51单片机的T2定时器?16位自动重载方式定时的误差为0.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-4-21 14:41:41 | 显示全部楼层
原帖由 Paktu 于 2011-4-21 08:48 发表
怎么不用51单片机的T2定时器?16位自动重载方式定时的误差为0.

是的,你说得对,用方式2最好,但因为这里用的是现成的STC板子,为了保证232通信速率没有误差,晶振是11.0592兆赫,要是自己使用51板和12兆晶振,机器周期是整数1微秒就好了
另外这只是个例子,旨在说明51的基本实例,要进一步提高计时精度,还需要改进,或者使用实时钟芯片更有价值,如大家有兴趣下次就介绍使用液晶LCD1602和实时钟ds1302的例子吧

[ 本帖最后由 wey05 于 2011-4-21 14:54 编辑 ]
回复 支持 反对

使用道具 举报

发表于 2011-4-21 20:06:38 | 显示全部楼层
晶振是11.0592兆赫,要是自己使用51板和12兆晶振,机器周期是整数1微秒就好了


that's actually fairly easy to solve, using a different approach:

#define F_XTAL 11059200ul //xtal at 12.0592Mhz
#define F_CPU (F_XTAL / 12) //cpu
#define PERIOD_SEC (F_CPU) //a full second
#define PERIOD_HALFSEC (F_CPU / 2) //half a second
#define PERIOD PERIOD_HALFSEC //tick advances every half a second
#define PERIOD_ERROR 0 //error term for each period

unsigned long tmr_counter=0; //tmr_counter

in your isr:

  tmr_counter+=0x10000ul; //tmr running in 16 bit
  if (tmr_counter >= PERIOD) {//overflown?
    tmr_counter-=PERIOD+PERIOD_ERR;  //reset tmr_counter;
    //update time below
  }

in your main code, you set up the timer to run in 16 bit mode.

with this approach, you will have very accurate long-term timing.
回复 支持 反对

使用道具 举报

发表于 2011-4-21 20:07:36 | 显示全部楼层
also, you can use any crystal: all you need to do is to revise the F_XTAL definition to reflect correctly the crystal you are using and recompile the code.
回复 支持 反对

使用道具 举报

     
发表于 2011-4-21 22:39:21 | 显示全部楼层

回复 18# millwood 的帖子

这个能详细注释下或讲下不?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2024-4-20 05:43

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表