搜索
bottom↓
回复: 74

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

[复制链接]

出0入0汤圆

发表于 2008-8-11 11:34:51 | 显示全部楼层 |阅读模式
LCD的驱动不像LED那样,加上电压(LED实际上是电流驱动)就可以长期显示的。
LCD驱动必须使用交流电压驱动才能保持稳定的显示,如果在LCD上加上稳定的直流电压,
不但不能正常显示,时间久了还会损坏LCD。一段LCD由背电极和段电极组成,需要显示时,
在背电极和段电极之间加上合适的交流电压(通常使用方波)。为了调节对比度,可以
调节方波中每半个周期中显示的时间(即占空比)来实现。

    通常,为了节约驱动口,将多个背电极连在一起,形成公共背电极端:COM。
另外,再将属于不同COM的段电极连接在一起,形成公共段电极端:SEG。当在某个COM和
某个SEG之间加了足够的交流电压之后,就会将对应的段点亮(实际上是变黑)。

    像万利的板子上使用的这种LCD,有4个COM,还有16个SEG。要想某一SEG显示时,
需要在对应的SEG和COM之间加上足够的交流电压。在万利的板子上,COM驱动使用了两个
电阻分压,输出电压为1/2Vcc,当不想让某位显示时,就将它的电压设置为1/2Vcc(通过
设置IO口为高阻态来完成),这样加在对应的SEG和COM之间的电压只有1/2Vcc,不足以
点亮对应的SEG。需要显示的,就将COM电压设置为0或者1,这样SEG电压跟COM电压相反的
段就被点亮了(变黑),因为它们之间的电压为Vcc。通过定期扫描每个COM,即可稳定的
在LCD上显示需要的图形了。需要显示字符或者数字时,自己先将对应的图案设计好,
在显示时,发送到相应的SEG和COM上即可。但是如果使用100%的时间都驱动的话,会造成
对比度太高,甚至出现不该显示的地方也显示了。因此在显示一段时间后,就将COM和SEG都
设置为低,以关闭它的显示,降低对比度。通过调节关闭时间的长短(PWM),可以调节
对比度。在下面的测试程序中,为了简化程序,使用了50%固定的占空比。

    为了方便描述,我们把COM为低电平时点亮叫做正亮,COM为高电平时点亮叫做负亮。
扫描每个COM分成4个阶段:正亮,关闭,负亮,关闭。因此对于本板子上的LCD驱动,
总共有16个状态,每个COM都有上面所说的4个状态。我们每隔2ms就切换一次状态,这样
整个扫描周期就是2*16=32ms,基本上感觉不到闪烁。

    但是需要注意的是,这个LCD中的每个COM并不是刚好对应着显示图案中的一个字符的位置。
每个COM都对应着每个显示字符中的相同4段!换句话说,要显示第一个字符位置的字符,每个
COM都要被用到。因此,要改变某个字符位置的显示,就需要改变每次COM输出时对应的SEG中
的4段。为此,建立一个缓冲区,当需要修改显示字符时,就修改缓冲区中的内容。这个缓冲区
有4行,每行中有16个SEG,对应着一个COM。需要修改显示时,把每行中对应的4个SEG设置为
需要的值,这样就实现了某个显示位置图案的修改。

    为了显示字符,需要事先把需要显示的字符按照SEG和COM的分布,制作成数据保存起来,
需要显示时,就把它复制到显示缓冲区中对应的位置去。另外,由于输入的参数是字符的ASCII码,
因此还需要将ASCII码转换为对应的字符图案的索引值。使用一个专门的函数来完成这些转换和
填充缓冲区,在需要修改显示数据时,就调用该函数。

    为了方便大家对这个LCD的驱动方式和编程,下面简单的画一下驱动的波形图。


驱动波形 (原文件名:LcdDriver.GIF)

    这里只画出2个SEG波形图,实际有16个SEG,只要你理解了2个SEG的,那么16个的也是一样的意思。
如图所示,所有偶数阶段都是关闭显示阶段,这时COM和SEG都是0,将不会有段被点亮,通过调节关闭
显示阶段所占的时间百分比,即可调节总体显示的对比度。SEG和COM之间电平相差1格的显示不出来或者
浓度不够,而SEG和COM之间电平相差2格的则可以显示出来或者浓度较深。例如第一阶段中的SEG1和COM1
之间相差2格,第三阶段中COM1和SEG1相差2格,因而SEG1和COM1之间的交叉点(即点1)被显示。又如
第九阶段的SEG1和COM3之间相差2格,第十一阶段中的COM3和SEG1之间相差2格,因而SEG1和COM3之间的
交叉点(即点5)被显示出来。其它点以此类推。

    最后,再来看看万利板子上的LCD的COM和SEG之间的关系图,如下图所示。


段码分布 (原文件名:LcdDriver1.GIF)


    图中显示,S0、S1、S2、S3属于第一个字符,在显示第一个字符时,只要在对应的COM选中时,
将需要显示的SEG放在上面即可。其余几个字符类似。例如要显示一个数字3,则应该将A段、B段、C段、D段、G段、K段显示。
某段显示,用1表示,不显示用0表示,得到的各段值如下:
X=0 I="0" A="1" DP="0"
F=0 H="0" J="0" B="1"
E=0 G="1" K="1" C="1"
L=0 M="0" N="0" D="1"
注意是低位在先的,把每行用十六进制来表示(高位在先),就是0x4,0x8,0xE,0x8。它们分别对应着
COM1~COM3选中时S3~S0的输出值。为了方便管理,将这4个十六进制值合并为一个2字节的值0x48E8保存。
其它各字符的构造方式相同。显示时,分别取出各段的值写入到对应的缓冲区去。

扫描LCD的程序流程如下:
①、COM1设置为低电平,其余COM为1/2高电平,设置PE口为需要的电平(16个段码),延时2ms;
②、4个COM、PE口均设置为低电平,关闭显示,延时2ms;
③、COM1设置为高电平,其余COM为1/2高电平,设置PE口为需要的电平(第一步16个段码的取反),延时2ms。
④、4个COM、PE口均设置为低电平,关闭显示,延时2ms;
然后对剩下的3个COM重复前面4个步骤,这样一个完整的扫描就完成了。

具体的实现代码比较长,这里就不再贴出了,在工程包中的LCD.C中可以查看。该测试工程包使用软件延时的
方法来实现LCD的扫描,实际使用时,可以将扫描代码放在定时器中断中处理。该测试程序使用一个时钟功能来
演示LCD的显示,显示为xx分xx秒。从这里下载整个测试的工程包(不下载的也可以去帮忙看看、顶一下,谢谢):
http://blog.ednchina.com/computer00/142101/message.aspx



注:站长阿莫将压缩包上传到我们网站了:

点击此处下载 ourdev_374354.rar(文件大小:47K) (原文件名:2.rar)

出0入0汤圆

发表于 2008-8-11 11:51:25 | 显示全部楼层
占位,留记号..

出0入0汤圆

发表于 2008-8-11 11:52:40 | 显示全部楼层
收藏

出0入8汤圆

发表于 2008-8-11 11:54:29 | 显示全部楼层
ST官方的应用笔记,使用的是ST7的16bit定时器实现的,原理与STM32上实现一样。压缩文件是笔记附带的工程例程。

点击此处下载 ourdev_374335.pdf(文件大小:200K) (原文件名:ST7 Software LCD driver.pdf)
点击此处下载 ourdev_374336.zip(文件大小:41K) (原文件名:ST7 Software LCD driver.zip)

出0入0汤圆

 楼主| 发表于 2008-8-11 12:06:36 | 显示全部楼层
俺这个是自己根据LCD的原理自己琢磨出来的,嘿嘿...

出0入0汤圆

发表于 2008-8-11 12:17:46 | 显示全部楼层
呵,圈圈大虾也来这吹水了。正好有个项目要用HT的cpu驱动段码LCD,学习学习。

出0入0汤圆

 楼主| 发表于 2008-8-11 12:21:17 | 显示全部楼层
呵呵~~~有时俺也会过来做点广告的~~~blog人气不够啊,得来拉拉人气~~~
头像被屏蔽

出0入0汤圆

发表于 2008-8-11 12:35:27 | 显示全部楼层
哈哈,欢迎啊。

帮楼主将压缩包也上传到楼主位了。COOL!

出0入0汤圆

 楼主| 发表于 2008-8-11 12:41:43 | 显示全部楼层
好的,你们的论坛转贴太麻烦了,图片、文件还得一个个重新上传过,不能直接复制粘贴的...
我干脆直接只写链接算了,不然一个个搞,搞一个小时都转不完...

http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=1387960&bbs_page_no=1&bbs_id=3011

出0入0汤圆

发表于 2008-8-11 13:05:14 | 显示全部楼层
向圈圈克服困难无私奉献的精神致敬!

出0入0汤圆

发表于 2008-8-11 13:10:04 | 显示全部楼层
学习一下!

出0入0汤圆

发表于 2008-8-11 19:13:40 | 显示全部楼层
圈圈出品,必是精品

出0入0汤圆

发表于 2008-8-11 20:00:11 | 显示全部楼层
但是如果使用100%的时间都驱动的话,会造成对比度太高,甚至出现不该显示的地方也显示了。因此在显示一段时间后,就将COM和SEG都设置为低,以关闭它的显示,降低对比度。

应该好像不是这个意思

出0入0汤圆

 楼主| 发表于 2008-8-11 20:56:34 | 显示全部楼层
你可以调节这个占空比试试,就可以得到不同的对比度。

出0入8汤圆

发表于 2008-8-12 11:22:56 | 显示全部楼层
STM32F10xxx LCD glass driver firmware

http://www.st.com/stonline/products/literature/anp/14144.pdf

出0入50汤圆

发表于 2008-8-13 17:36:04 | 显示全部楼层
用这个原理驱动过一个产品的LCD,效果不错。2.5ms中断一次,20ms完成一次扫描,50HZ的刷新率。用的是MEGA8,省掉了一片HT1621

出0入0汤圆

发表于 2008-8-19 09:16:11 | 显示全部楼层
强贴留名...

出0入0汤圆

发表于 2008-8-20 17:35:15 | 显示全部楼层
按楼主所给的时序图用PIC16F84A 成功驱动 三位LCD


(原文件名:LCD.jpg)

//引入头文件*********************************************************
#include          "delay.h"
#include          "delay.c"
#include      <pic1684.h>

//字符查表***********************************************************
     const unsigned char Lcd[10] = {0x3f, 0x06, 0x5b, 0x4f, 0x66,
                                    0x6d, 0x7d, 0x07, 0x7f, 0x6f};  

//*******************************************************************
//函数名称:port_init();
//输入参数:无
//输出参数:无
//功能描述:端口设置
//建造日期:2008.06.03
//*****************************************************************
void PortInit(void)
{
     PORTA = 0xff;                                         //A 口设置
     PORTB = 0xff;                                         //B 口设置

     TRISA = 0x00;                                         //   
     TRISB = 0x00;                                         //
}

//*******************************************************************
//函数名称:main();
//输入参数:无
//输出参数:无
//功能描述:主要程序
//建造日期:2008.06.03
//*******************************************************************
void main(void)                                            //
{   
     unsigned char temp[3];
     unsigned char i, j;
      
     PortInit();                                           //脚位设置
   
     temp[0] = Lcd[1];
     temp[1] = Lcd[2];
     temp[2] = Lcd[3];
     
     while (1)
      {
       PORTA = 0b11111110;                                 //正亮显示
       TRISA = 0b11111110;

       PORTB = temp[0];
       DelayMs(2);

       PORTA = 0b11111000;                                 //关闭显示
       TRISA = 0b11111000;

       PORTB = 0x00;
       DelayMs(2);

       PORTA = 0b11111111;                                 //负亮显示
       TRISA = 0b11111110;

       PORTB = temp[0] ^ 0xff;
       DelayMs(2);

       PORTA = 0b11111000;                                 //关闭显示
       TRISA = 0b11111000;

       PORTB = 0x00;
       DelayMs(2);                                         

       PORTA = 0b11111101;                                 //正亮显示
       TRISA = 0b11111101;

       PORTB = temp[1];
       DelayMs(2);

       PORTA = 0b11111000;                                 //关闭显示
       TRISA = 0b11111000;

       PORTB = 0x00;
       DelayMs(2);

       PORTA = 0b11111111;                                 //负亮显示
       TRISA = 0b11111101;

       PORTB = temp[1] ^ 0xff;
       DelayMs(2);

       PORTA = 0b11111000;                                 //关闭显示
       TRISA = 0b11111000;

       PORTB = 0x00;
       DelayMs(2);

       PORTA = 0b11111011;                                 //正亮显示
       TRISA = 0b11111011;

       PORTB = temp[2];
       DelayMs(2);

       PORTA = 0b11111000;                                 //关闭显示
       TRISA = 0b11111000;

       PORTB = 0x00;
       DelayMs(2);

       PORTA = 0b11111111;                                 //负亮显示
       TRISA = 0b11111011;

       PORTB = temp[2] ^ 0xff;
       DelayMs(2);

       PORTA = 0b11111000;                                 //关闭显示
       TRISA = 0b11111000;

       PORTB = 0x00;
       DelayMs(2);
      }  
}

出0入0汤圆

发表于 2008-8-20 17:36:52 | 显示全部楼层
只是灰度低了点..如何提高灰度..请楼主指点一下.....

出0入0汤圆

发表于 2008-8-20 17:41:34 | 显示全部楼层
仿真波形..和楼主的时序图完全一样...

(原文件名:LCD.jpg)

出0入0汤圆

 楼主| 发表于 2008-8-24 17:15:41 | 显示全部楼层
提高对比度,可以缩短关断时间(即图中的所有偶数阶段),而奇数部分的时间保持不变。通过调整关断时间的长短,可以调节对比度。

出0入0汤圆

发表于 2008-8-24 21:46:50 | 显示全部楼层
记号,楼上的lcd片从什么地方购买的,有地址吗?

出0入0汤圆

发表于 2008-8-24 21:56:44 | 显示全部楼层
记号

出0入0汤圆

发表于 2008-8-27 22:13:12 | 显示全部楼层
to 【17楼】 ivws
请问你的lcd片从什么地方购买的,给个连接好吗?

出0入0汤圆

发表于 2008-9-8 01:08:21 | 显示全部楼层
mark

出0入0汤圆

发表于 2008-9-8 19:32:32 | 显示全部楼层
mark~~~

出0入0汤圆

发表于 2008-9-10 18:42:39 | 显示全部楼层
记号!

出0入0汤圆

发表于 2008-9-16 23:33:49 | 显示全部楼层
这种驱动方法对LCD有什么要求吗,市场上比较多的段码LCD是1/4&nbsp;DUTY,1/3&nbsp;BIAS,用这种方法可以直接驱动吗,以前有个帖子介绍单片机IO口驱动LCD的方法,是驱动1/3&nbsp;BIAS的LCD,也采用圈圈的方法,不过效果不是很好,又多加了一组电阻才行,如果采用此方法是不是要求LCD为1/2&nbsp;BIAS。

出0入0汤圆

 楼主| 发表于 2008-9-17 00:04:38 | 显示全部楼层
是的,这个LCD是1/2偏压的。

出0入0汤圆

发表于 2008-9-25 14:25:14 | 显示全部楼层
oo牛啊



1/2偏压,

1/3偏压

学习了.

出0入0汤圆

发表于 2008-9-25 15:19:35 | 显示全部楼层
to&nbsp;【24楼】&nbsp;ndust&nbsp;





这个LCD&nbsp;是在我们广西南宁卖的.....不知道是哪进货的..应该是在深圳.

出0入0汤圆

发表于 2008-10-3 11:33:07 | 显示全部楼层
MARK~

出0入0汤圆

发表于 2008-11-10 20:25:26 | 显示全部楼层
mark!

出0入0汤圆

发表于 2009-3-23 17:37:44 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-3-23 21:08:29 | 显示全部楼层
原来用HT做过类似的,就是用IO口模拟1/2偏压,效果很好.

出0入0汤圆

发表于 2009-5-16 22:10:44 | 显示全部楼层
做个记号,学习了

出0入0汤圆

发表于 2009-7-24 16:35:16 | 显示全部楼层
学习学习

出0入0汤圆

发表于 2009-9-15 13:48:39 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-10-6 18:06:01 | 显示全部楼层
向00学习

出0入0汤圆

发表于 2010-1-13 17:00:06 | 显示全部楼层
学习一下!

出0入0汤圆

发表于 2010-1-22 16:35:50 | 显示全部楼层
惭愧,之前都没明白是怎么回事

出20入0汤圆

发表于 2010-2-9 15:56:13 | 显示全部楼层
这里的高人实在是太多了

出0入0汤圆

发表于 2010-2-9 20:58:53 | 显示全部楼层
回复【29楼】computer00 电脑圈圈
是的,这个LCD是1/2偏压的。
-----------------------------------------------------------------------

你好,我弄了很久这个了,点亮没问题
但暗亮,原来要使用1/2偏压的片子,我的都是1/3偏压的

原来如此,豁然开朗!!

支持computer00 电脑圈圈

出0入0汤圆

发表于 2010-2-9 21:21:13 | 显示全部楼层
jh

出0入0汤圆

发表于 2010-2-9 21:50:06 | 显示全部楼层
哪里有4com 1/2偏压的lcd???

出0入0汤圆

发表于 2010-3-27 11:30:06 | 显示全部楼层
顶起呀

出0入0汤圆

发表于 2010-5-10 18:59:48 | 显示全部楼层
学习下

出0入0汤圆

发表于 2010-5-10 21:34:13 | 显示全部楼层
mark

出0入85汤圆

发表于 2010-5-10 21:35:05 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-5-16 15:35:10 | 显示全部楼层
活到老,学到老!

出0入0汤圆

发表于 2010-5-16 15:49:07 | 显示全部楼层
记号~~

出0入0汤圆

发表于 2010-5-21 11:48:44 | 显示全部楼层
圈圈真是无所不知啊,佩服!记号一下。

出0入0汤圆

发表于 2010-5-30 21:47:22 | 显示全部楼层
我试了一下,怎么效果不太好啊!不是想显示的段太暗,就是不想显示的太亮,怎么调都不行,郁闷啊!

出0入0汤圆

发表于 2010-6-10 22:58:20 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-6-15 18:03:20 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-6-19 15:54:31 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-2-25 22:36:46 | 显示全部楼层
cool

出20入186汤圆

发表于 2011-3-6 22:18:32 | 显示全部楼层
学习了,lcd

出0入0汤圆

发表于 2011-3-10 16:17:05 | 显示全部楼层
回复【楼主位】computer00 电脑圈圈
-----------------------------------------------------------------------

你好,我手头有这样一块屏,是1/2 duty 的,看你的程序,我想不明白应该如何编码,
点击此处下载 ourdev_621426KAAY4V.pdf(文件大小:34K) (原文件名:lcd_disp.pdf)

出0入0汤圆

发表于 2011-3-17 18:55:31 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-3-26 20:42:42 | 显示全部楼层
Mark。。谢谢楼上的诸位。

出0入0汤圆

发表于 2011-3-26 22:04:26 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-3-26 22:51:22 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-9-16 10:04:31 | 显示全部楼层
学习,谢谢!

出0入0汤圆

发表于 2011-11-2 17:27:18 | 显示全部楼层
收藏

出0入0汤圆

发表于 2012-2-10 16:23:43 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-2-10 16:33:26 | 显示全部楼层
mark

出0入0汤圆

发表于 2013-7-17 19:15:37 | 显示全部楼层
太好了楼主,,最近正在学习研究段式LCD,,您的资料对我太有用。 ,,万分感谢

出0入0汤圆

发表于 2013-7-18 11:06:38 | 显示全部楼层
00大神好厉害,,茅塞顿开啊

出0入112汤圆

发表于 2013-7-20 09:59:05 | 显示全部楼层
你还写过USB的书,真是厉害!
我手上有一块数字万用表的LCD,LCD没有直接引出引脚而是用导电胶与电路板相连、又没标型号和引脚,不知LCD的引脚排序有没有规律呢?能否用信号源5Vp-p、500HZ的交流加到引脚上测出COM端、SEG端?

出0入112汤圆

发表于 2013-7-20 10:00:06 | 显示全部楼层
ivws 发表于 2008-8-20 17:35
按楼主所给的时序图用PIC16F84A 成功驱动 三位LCD

LCD显示效果不错,在那里买的?多少钱?

出0入0汤圆

发表于 2013-8-12 14:56:33 来自手机 | 显示全部楼层
mark……
顶一个…

出0入0汤圆

发表于 2013-8-12 17:04:12 | 显示全部楼层
哈哈哈                                学习了                  

出0入0汤圆

发表于 2018-9-21 21:48:30 | 显示全部楼层
学习了。。。。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-19 21:08

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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