你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

万利的STM32学习板上的LCD(无驱动段式玻璃片式)驱动原理及编程实现

[复制链接]
goodboy3021 发布时间:2011-4-12 20:27
LCD的驱动不像LED那样,加上电压(LED实际上是电流驱动)就可以长期显示的。
# o2 R" s0 ^# h( I" Q% ]! wLCD驱动必须使用交流电压驱动才能保持稳定的显示,如果在LCD上加上稳定的直流电压,
; [2 K9 R- x7 N6 F% \不但不能正常显示,时间久了还会损坏LCD。一段LCD由背电极和段电极组成,需要显示时,
1 P5 g# r1 O" K在背电极和段电极之间加上合适的交流电压(通常使用方波)。为了调节对比度,可以
1 @/ y5 e3 q; h7 k+ f& C调节方波中每半个周期中显示的时间(即占空比)来实现。 / F9 g; a7 a( r  I( [
+ i; H9 u$ n8 v1 h! l+ E
    通常,为了节约驱动口,将多个背电极连在一起,形成公共背电极端:COM。 % {* k$ b( l- N9 z
另外,再将属于不同COM的段电极连接在一起,形成公共段电极端:SEG。当在某个COM和
; K0 @, ]3 ^9 \' L某个SEG之间加了足够的交流电压之后,就会将对应的段点亮(实际上是变黑)。
5 o5 M$ [9 Q9 O- b1 t6 k1 I" d& g. y5 [  n8 u1 M5 e: y
    像万利的板子上使用的这种LCD,有4个COM,还有16个SEG。要想某一SEG显示时,
# g4 H2 {/ c/ u( c) K需要在对应的SEG和COM之间加上足够的交流电压。在万利的板子上,COM驱动使用了两个
5 l5 {( O" |. p1 I# l1 o% u! V) h4 R电阻分压,输出电压为1/2Vcc,当不想让某位显示时,就将它的电压设置为1/2Vcc(通过
9 x# s6 ]3 c9 C' j7 Q! A% j设置IO口为高阻态来完成),这样加在对应的SEG和COM之间的电压只有1/2Vcc,不足以 + v# E% a6 v. |
点亮对应的SEG。需要显示的,就将COM电压设置为0或者1,这样SEG电压跟COM电压相反的 0 {+ H$ Q3 t& Z1 N
段就被点亮了(变黑),因为它们之间的电压为Vcc。通过定期扫描每个COM,即可稳定的
. }/ D0 W( j8 g4 w+ }, n/ p在LCD上显示需要的图形了。需要显示字符或者数字时,自己先将对应的图案设计好,
' u, c# v! f4 b! e. {. K在显示时,发送到相应的SEG和COM上即可。但是如果使用100%的时间都驱动的话,会造成 " m" C- a! y5 X3 ~- j+ `8 P1 d, {5 D
对比度太高,甚至出现不该显示的地方也显示了。因此在显示一段时间后,就将COM和SEG都 ) j/ L  A5 [; g1 `' K
设置为低,以关闭它的显示,降低对比度。通过调节关闭时间的长短(PWM),可以调节
) S+ U3 p9 y$ h, a5 F2 ?0 j' N对比度。在下面的测试程序中,为了简化程序,使用了50%固定的占空比。 8 R- V6 X. M2 k" |4 k+ z) m. O

) c4 G$ a7 H9 @1 [" @/ E! K    为了方便描述,我们把COM为低电平时点亮叫做正亮,COM为高电平时点亮叫做负亮。
6 x7 y) v, t  G4 Y- B9 ]. B6 h扫描每个COM分成4个阶段:正亮,关闭,负亮,关闭。因此对于本板子上的LCD驱动,
* Z- g7 |1 h: }" v, ?总共有16个状态,每个COM都有上面所说的4个状态。我们每隔2ms就切换一次状态,这样
# e+ B) K- G9 M! G3 i7 Q1 P0 ~整个扫描周期就是2*16=32ms,基本上感觉不到闪烁。 3 @) q( X) ~+ j5 c* K
; R/ L% s. M; S' f  u
    但是需要注意的是,这个LCD中的每个COM并不是刚好对应着显示图案中的一个字符的位置。 8 z2 k2 R- N1 e& S5 U5 r- E0 v& p# [! g8 |
每个COM都对应着每个显示字符中的相同4段!换句话说,要显示第一个字符位置的字符,每个
- N% |! E+ _  x' R' d; s* i' v2 `# `COM都要被用到。因此,要改变某个字符位置的显示,就需要改变每次COM输出时对应的SEG中 # j9 J2 C( s+ l5 _
的4段。为此,建立一个缓冲区,当需要修改显示字符时,就修改缓冲区中的内容。这个缓冲区 ' z- h$ T, P. Z% l& Y9 q
有4行,每行中有16个SEG,对应着一个COM。需要修改显示时,把每行中对应的4个SEG设置为 " R% ~4 M$ b) j' a
需要的值,这样就实现了某个显示位置图案的修改。
$ Q/ u" x6 {1 f6 p2 h2 J
$ L# @9 N% X+ ?. @) s& W- G% Q    为了显示字符,需要事先把需要显示的字符按照SEG和COM的分布,制作成数据保存起来, - m, ]& E! L0 w& i
需要显示时,就把它复制到显示缓冲区中对应的位置去。另外,由于输入的参数是字符的ASCII码, ) [2 X. ?" ~  p5 v3 f1 R' l
因此还需要将ASCII码转换为对应的字符图案的索引值。使用一个专门的函数来完成这些转换和 % p9 z* {# z3 Z" X. s: ~1 |( }$ J
填充缓冲区,在需要修改显示数据时,就调用该函数。
6 A$ V, q4 W: q: y4 g) d5 k6 T4 v6 C+ f! O+ ]5 W( w7 M& u. z. L
    为了方便大家对这个LCD的驱动方式和编程,下面简单的画一下驱动的波形图。
& O% z2 R! I9 A5 B8 O4 r9 _& {) n9 M5 g
 
6 f1 U) H& ]( J6 ^1 C, L - a2 H' D* L- d% t, S5 v# y
驱动波形 (原文件名cdDriver.GIF) + q' ^) H) f( X/ h0 s
/ x$ J6 d9 v+ |! L- u4 r# c, x3 v
    这里只画出2个SEG波形图,实际有16个SEG,只要你理解了2个SEG的,那么16个的也是一样的意思。
% r9 L0 h' U3 @5 s5 L) s  ^$ K; a如图所示,所有偶数阶段都是关闭显示阶段,这时COM和SEG都是0,将不会有段被点亮,通过调节关闭
- D, ^$ S! S3 [& o2 o, O- B1 L显示阶段所占的时间百分比,即可调节总体显示的对比度。SEG和COM之间电平相差1格的显示不出来或者 0 S) g8 m4 O5 B8 m9 d" M
浓度不够,而SEG和COM之间电平相差2格的则可以显示出来或者浓度较深。例如第一阶段中的SEG1和COM1
( J; m/ G' W6 a之间相差2格,第三阶段中COM1和SEG1相差2格,因而SEG1和COM1之间的交叉点(即点1)被显示。又如
. p: Y" K1 F6 o. K第九阶段的SEG1和COM3之间相差2格,第十一阶段中的COM3和SEG1之间相差2格,因而SEG1和COM3之间的
8 U  P+ d. F& L. x0 f' C# L1 |4 v6 t交叉点(即点5)被显示出来。其它点以此类推。
. n8 _- s" z0 D8 Q- M) z7 v& F
    最后,再来看看万利板子上的LCD的COM和SEG之间的关系图,如下图所示。
' r" H% ~  t  `# _0 \, r4 f& U0 k# G1 E% u( ?( f0 v& h7 c
 $ r8 _# k6 @4 e1 w/ G' i

8 [! x. j0 ?/ S6 i4 \# c6 l段码分布 (原文件名cdDriver1.GIF) 
1 y* @+ J2 W* M; L2 t! E
# @$ c" N- ?* G  s  g" V% Q( o' p% z/ P) @
    图中显示,S0、S1、S2、S3属于第一个字符,在显示第一个字符时,只要在对应的COM选中时,
. w& h+ G2 Z% I! |* M将需要显示的SEG放在上面即可。其余几个字符类似。例如要显示一个数字3,则应该将A段、B段、C段、D段、G段、K段显示。 : |" b( S* ~8 U9 p
某段显示,用1表示,不显示用0表示,得到的各段值如下: ; A$ w2 D$ x5 V' E1 x/ Z$ q
X=0 I="0" A="1" DP="0" % R% x0 G+ [7 ]1 _$ a
F=0 H="0" J="0" B="1" * Q; S7 [  Q, @
E=0 G="1" K="1" C="1"
5 R7 n# Y+ q1 ?4 V* W) N% z! d! KL=0 M="0" N="0" D="1" 3 K6 I9 O  l& T  g: s$ Q
注意是低位在先的,把每行用十六进制来表示(高位在先),就是0x4,0x8,0xE,0x8。它们分别对应着 2 a* h9 K9 r0 E5 r
COM1~COM3选中时S3~S0的输出值。为了方便管理,将这4个十六进制值合并为一个2字节的值0x48E8保存。 1 V: i- k6 I# o8 t  m
其它各字符的构造方式相同。显示时,分别取出各段的值写入到对应的缓冲区去。 4 R+ E9 U) q) U* R

1 o9 ?8 c2 d; s. t; a$ Z/ b) a扫描LCD的程序流程如下: # N9 r, H4 a% Y0 A: `
①、COM1设置为低电平,其余COM为1/2高电平,设置PE口为需要的电平(16个段码),延时2ms; ! J  S. z3 n* B
②、4个COM、PE口均设置为低电平,关闭显示,延时2ms; 2 X1 s, f6 A) g5 M. v$ i- W
③、COM1设置为高电平,其余COM为1/2高电平,设置PE口为需要的电平(第一步16个段码的取反),延时2ms。
7 u- w& S  I1 M" n④、4个COM、PE口均设置为低电平,关闭显示,延时2ms; 8 r; n' T, Y6 C0 ~0 R
然后对剩下的3个COM重复前面4个步骤,这样一个完整的扫描就完成了。 ' P3 `4 h2 j2 B1 y7 B6 z

6 A! v0 G; M2 g: n( E/ V) f) i具体的实现代码比较长,这里就不再贴出了,在工程包中的LCD.C中可以查看。该测试工程包使用软件延时的 1 y- Q2 t& h" |* v! ~- n: C
方法来实现LCD的扫描,实际使用时,可以将扫描代码放在定时器中断中处理。该测试程序使用一个时钟功能来
# S% F: _. f! n5 s1 J; ^- l演示LCD的显示,显示为xx分xx秒。从这里下载整个测试的工程包(不下载的也可以去帮忙看看、顶一下,谢谢): 2 j4 {- q- d: C! h" u' O
http://blog.ednchina.com/computer00/142101/message.aspx
. N. ?. X. H: Q/ {6 c1 j5 [
* Z3 c  B' v" m6 r/ K" z; b 
赞 收藏 评论1 发布时间:2011-4-12 20:27

举报

1个回答
泉水叮咚-257423 回答时间:2011-4-26 10:48:09

RE:万利的STM32学习板上的LCD(无驱动段式玻璃片式)驱动原理及编程实现

说的很详细,就是图片看不到
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版