段式LCD原理

最近做的一款产品中涉及到段式LCD的显示,在网上查询了很多资料,这篇资料对我的帮助最大,特别搜录下来供参考。

lcd段码屏 & 数码管(RT)
段码液晶屏最重要的参数:占空比、工作电压、偏压比。这三个参数都是非常重要的,都必须要满足。
驱动的方式:我们根据 LCD 的驱动原理可以知道,LCD的像素点上面只能够加上 AC的电压,LCD显示器的对比度则是由 COM脚上的电压值减去 SEG 脚上的电压值来决定,当这个电压差在大于 LCD 饱和电压时就能够打开像素点,小于 LCD 阈值电压时就能关闭像素点了,LCD 型的MCU 已经由内建的 LCD 驱动电路自动产生出LCD驱动信号了,因此只需要 I/O 口能仿真输出该驱动的信号,就能够完成 LCD 的驱动了。
段码液晶屏主要是有两种引脚,COM和SEG,和数码管比较像,但是,压差必须要是交替变化的,例:第一时刻是正向的3V,那么第二时刻就必须要是反向的3V,注意一点,如果你给段码液晶屏通直流电,那么不用多久这个屏幕就会报废,所以千万要注意.
1.段电极SEG、公共极COM
    一般段码屏有段电极和公共极,就像在图中,SEG为段电极,COM为公共极。段码屏中的每个段,都填充了一种特殊的液态晶体。在电场的作用下,晶体的排列方向会发生扭转,因而改变其透光性,从而可以看到显示的内容。一般电场电压就加在段电极和公共极的两端。
2.供电电压、偏压比(偏置比)Bias、占空比Duty
(1)占空比:1根COM线在扫描过程中所占的时间,假如一共用了2根COM线,Duty=1/2,假如一共用了3根COM线,Duty=1/3,假如一共用了4根COM线,Duty=1/4。
    HT1621一共可驱动4根COM,占空比 Duty 取值范围是1/2或1/3或1/4。
(2)偏压比:偏压就是用于控制液晶偏转角度的电压,HT1621的偏压比 Bias 取值范围是1/2或1/3。当供电电压为3.3V,偏压比为1/3时,求得偏压为 3.3V*(1/3)=1.1V
 共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管,当某一字段发光二极管的阴极为低电平时,相应字段就点亮,当某一字段的阴极为高电平时,相应字段就不亮。共阴数码管是指将所有发光二极管的阴极接到一起形成公共阴极(COM)的数码管,当某一字段发光二极管的阳极为高电平时,相应字段就点亮,当某一字段的阳极为低电平时,相应字段就配空不亮。
3.数码管公共极的连接不同
共阳数码管在应用时应将公共极COM接到+5V,共阴数码管在应用时应将公共极COM接到地线GND上。

     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的驱动方式和编程,下面简单的画一下驱动的波形图。 

    这里只画出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之间的关系图,如下图所示。

      图中显示,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个步骤,这样一个完整的扫描就完成了。

硬件连接:

1、如下的LCD显示屏:

 2、LCD与单片机的连接

 3、LCD内存组织形式

 

4、使用4-mux模式

从上面的码表看出LCD PIN25~31为NC,所以实际电路连接的时候使用了单片机的引脚为LCD0~LCD26和COM0~COM3。一共为27个segment和4个com,按照内存组织形式,LCD显示使用到的内存为LCDM0~LCDM14,LCD内存图中的Associated Common Pins 3 2 1 0按照内存中的顺序对应于COM3~COM0。若要显示码表中的A10:"0" LCD segments a+b+c+d+e+f+k+q;根据码表和LCD内存顺序为0xFC,0x28,占用4个segment(即PIN1~PIN4),占用2个字节LCDM1,LCDM2,给内存赋值LCDM1=0xFC(SEG1+SEG0),LCDM2=0x28(SEG3+SEG2),这样就可以在LCD上显示出0。

  • 32
    点赞
  • 187
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
以下是一个简单的段式LCD液晶显示程序示例,使用的是ATmega16单片机和AVR Studio编程环境: ```c #include <avr/io.h> #include <util/delay.h> #define LCD_DATA PORTD // 数据总线连接到PORTD口 #define LCD_CTRL PORTB // 控制线连接到PORTB口 #define RS PB0 // RS引脚连接到PB0口 #define EN PB1 // EN引脚连接到PB1口 void LCD_init(); // LCD初始化函数 void LCD_send_command(unsigned char command); // 发送命令函数 void LCD_send_data(unsigned char data); // 发送数据函数 void LCD_send_string(char *string); // 发送字符串函数 int main(void) { LCD_init(); // LCD初始化 while(1) { LCD_send_command(0x80); // 光标移动到第一行第一列 LCD_send_string("Hello, World!"); // 在LCD上显示字符串 _delay_ms(1000); // 延时1秒 LCD_send_command(0x01); // 清屏 _delay_ms(1000); // 延时1秒 } return 0; } // LCD初始化函数 void LCD_init() { DDRD = 0xFF; // 将PORTD口设置为输出模式 DDRB = 0x03; // 将PB0和PB1口设置为输出模式 LCD_send_command(0x02); // 回到初始状态 LCD_send_command(0x28); // 4位数据线,两行显示,5x8点阵 LCD_send_command(0x0C); // 显示开,光标开,光标闪烁关 LCD_send_command(0x06); // 光标右移,字符不移动 LCD_send_command(0x01); // 清屏 } // 发送命令函数 void LCD_send_command(unsigned char command) { LCD_DATA = (command & 0xF0); // 发送高4位 LCD_CTRL &= ~(1<<RS); // RS引脚置0,表示发送指令 LCD_CTRL |= (1<<EN); // EN引脚置1,产生脉冲 _delay_us(1); // 延时1微秒 LCD_CTRL &= ~(1<<EN); // EN引脚置0,结束脉冲 _delay_us(100); // 延时100微秒 LCD_DATA = ((command<<4) & 0xF0); // 发送低4位 LCD_CTRL |= (1<<EN); // EN引脚置1,产生脉冲 _delay_us(1); // 延时1微秒 LCD_CTRL &= ~(1<<EN); // EN引脚置0,结束脉冲 _delay_us(100); // 延时100微秒 } // 发送数据函数 void LCD_send_data(unsigned char data) { LCD_DATA = (data & 0xF0); // 发送高4位 LCD_CTRL |= (1<<RS); // RS引脚置1,表示发送数据 LCD_CTRL |= (1<<EN); // EN引脚置1,产生脉冲 _delay_us(1); // 延时1微秒 LCD_CTRL &= ~(1<<EN); // EN引脚置0,结束脉冲 _delay_us(100); // 延时100微秒 LCD_DATA = ((data<<4) & 0xF0); // 发送低4位 LCD_CTRL |= (1<<EN); // EN引脚置1,产生脉冲 _delay_us(1); // 延时1微秒 LCD_CTRL &= ~(1<<EN); // EN引脚置0,结束脉冲 _delay_us(100); // 延时100微秒 } // 发送字符串函数 void LCD_send_string(char *string) { while(*string) // 当字符串不为空时 { LCD_send_data(*string++); // 发送字符串中的每一个字符 } } ``` 以上代码中,LCD_init()函数用于初始化LCD显示屏,LCD_send_command()函数用于向LCD发送命令,LCD_send_data()函数用于向LCD发送数据,LCD_send_string()函数用于向LCD发送字符串。在主函数中,先进行LCD初始化,然后在循环中向LCD显示屏上循环显示“Hello, World!”字符串,并在每次显示后清屏,延时1秒后再次显示。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值