您的位置 首页 设计

单片机引脚直接驱动LCD

LED数码管的驱动是比较简单也容易理解的,多位数码管一般是LED阵列的形式,每个数字使用一个公共端,不同数字的对应同笔段使用一个控制端;…

LED数码管的驱动是比较简略也简略了解的,多位数码管一般是LED阵列的方法,每个数字运用一个公共端,不同数字的对应同笔段运用一个操控端;驱动选用分时扫描没个数字位,动态显现。可是LED比较费电,我想做一个用电池供电的钟,用发光管电池就撑不了多久了。所以我考虑用液晶。
在这边的电子市场我买到一个4位笔段式液晶屏,4个数字最中心有冒号,边上还有几个箭头符号,一共有15个引脚,正合适用AVR来驱动做一个钟。
笔段式LCD屏的结构与LED数码管很类似,可是由所以液晶,作业机理上不同,驱动方法也有很大差异:
(1) LED有正负之分,液晶笔划没有。
(2) LED在直流电压下作业,液晶需求沟通电压,避免电解效应。
(3) LED需求电流供给发光的能量,液晶笔划显现状况下电流十分弱小。
(4) LED对细小电流不反响,液晶则很灵敏。
不难看出,用LED的驱动方法来对待LCD屏是行不通的。我在买回来测验这块屏之前没有意识到,所以走了不少的弯路。与LED驱动不同的是需求给每个笔划加上一个沟通电压。一般用30-60Hz的方波就能够了,频率再低显现会有所动摇,频率高了功耗也会添加,由于LCD对电路出现容性。并且,正负电压都能够“点亮”液晶。
好在AVR的I/O口能够三态输出,也便是除了高/低电平,还能够出现高阻抗,相当于断开衔接。所以我想到了这样的方法:不需求显现的那一组笔划对应的公共端悬空(I/O口挑选三态),那么就不会加上电压了。照这个思路,我的试验电路焊好,出来的显现却是一团糟:笔划都黑了看不清。我这才考虑到液晶自身的问题:阻抗高,并且有电容,是不行一边悬空的!这个道理或许跟CMOS输入端差不多。查找了一些关于液晶的材料,大致知道LCD屏不是那么简略的,驱动方法通常是1/N, 也便是电压不止凹凸两档。可是单片机I/O没有那么多输出状况能够挑选。
1/2 Bias驱动
不显现的液晶笔划两头电压持平,显现的不等。这样一个要求在扫描方法
下不能满足,所以改为电压等级不同。1/2 Bias驱动便是这样的,如下:
COM1 V+ —- —-
1/2 —- —- —- —-
GND —- —-
COM2 V+ —- —-
1/2 —- —- —- —-
GND —- —-
SEG1 V+ ——– ——–
1/2
GND ——– ——–
SEG2 V+ —- ——– —-
1/2
GND ——– ——–
如此,在 COM1,SEG1 挑选的笔划上,加上的电压为 -1/2, -1, +1/2, +1 … 在 COM1,SEG2 挑选的笔划上,加上的电压为 +1/2, -1, -1/2, +1 … 在 COM2,SEG1 挑选的笔划上,加上的电压为 -1, -1/2, +1, +1/2 …在 COM2,SEG2 挑选的笔划上,加上的电压为 0, -1/2, 0, +1/2 …
核算一下大致的均匀功率(假设液晶灰度与电压平方成正比,实践不是这样)前三者是相同的,都是 1+(1/2)^2=5/4, 关于最终一个 0+(1/2)^2=1/4 因而显现的功率比为 5:1, 显现状况会是这样:
SEG1 SEG2
: :
COM1 – – – O – – – O
: :
COM2 – – – O – – – x
AVR I/O没有才干输出 1/2 Vcc 的电压(ADC在这儿就不要考虑了, 糟蹋I/O还不如用静态液晶屏), 因而没有方法完成真实的 1/2 Bias驱动。可是注意到要供给一个一半电源电压也不是难事,已然AVR I/O口能够三态,咱们用两个电阻分压将端口“拉”到1/2 Vcc就好了,所以,1/2 Bias驱动的做法能够这样:
Vcc
|
[ ]
[ ] 1Meg
[ ]
|
Port pin—–+———— to LCD COMx
|
[ ]
[ ] 1Meg
[ ]
|
GND

取电阻 1Meg 是归纳耗电与分压作用考虑的。这样在 COMx 就能够发生三种电压值,就到达了1/2 Bias动态驱动的意图。完成起来在前面的基础上添加电阻即可,我的屏有4个公共端,因而用了8个电阻,数字就能够显现出来了。
尽管显现确实做到了,可是作用却不能让我满足。具体表现便是需求正对着LCD屏看才是很明晰的;假设斜着看,就或许一片混浊了,没有到达有用。用2节Ni-MH供电时分正着看没问题,用2节干电池(电压进步一点)就不是很明晰了。如前面的剖析,那些没有被挑选的笔段其实也加上了改动的电压,只不过与挑选的比段比较电压均匀有效值低一些。这两个的差异满足明显,才干确保显现作用。
再剖析 1/2 Bais 驱动在我的LCD屏上 1/4 分时扫描的成果:一个周期内,“点亮”的笔段均匀功率=1^2+(1/2)^2+(1/2)^2+(1/2)^2=7/4, 而没有被“点亮”的笔段为=0+(1/2)^2+(1/2)^2+(1/2)^2=3/4, 两者之比 7:3
跟前面的比如剖析比照看出,从 1/2 分时扫描变到 1/4 分时扫描,显出来的笔段和不显的笔段上,电压发生均匀功率的比照从 5:1 变到 7:3 了。我测验从软件上改动扫描时序,也不能改善显现作用,看来 1/2 Bias 不够用的了。
我查了Nokia 3310液晶手册其间关于LCD电压输出时序的描绘。刚好里边有一个图,绘出了行和列操控线上的波形。从坐标轴上看出Vlcd和Vss之间别的还有4个电压等级。这么多种电压用AVR I/O完成现已不现实了。
我再考虑选用带有LCD驱动功用的MCU, AVR只要一款ATmega169, 封装方法不适合DIY。Microchip有一款PIC16F913, 有28DIP的封装,看上去正合适。暂时不知道价格,我先找来它的手册看看。具体看了LCD驱动模块的部分,我发现PIC16F913也只要1/2 Bias驱动和1/3 Bias驱动两种选项,分时最多为1/4分时驱动,关于我的屏正好。
1/3 Bias 驱动需求将Vcc–GND之间的电压三等分,一个周期驱动波形示例如下:
COM1: V+ ——–
2/3 ——–
1/3 ——–
GND ——–
COM2: V+ ——–
2/3 ——–
1/3 ——–
GND ——–
SEG1: V+ ——–
2/3 ——–
1/3 ——–
GND ——–
SEG2: V+ ——–
2/3 ——–
1/3 ——–
GND ——–
在 (COM1,SEG1) 笔段上,电压为 +1, -1/3, -1, +1/3 … 在(COM1,SEG2)上为 +1/3, +1/3, -1/3, -1/3 … 在(COM2,SEG1)上:+1/3, +1/3, -1/3, -1/3 … 在(COM2,SEG2)上:-1/3, +1, +1/3, -1 …
所以核算均匀功率,在 (COM1,SEG1)和(COM2,SEG2)上面是 2*1^2+2*(1/3)^2=20/9 在(COM1,SEG2)和(COM2,SEG1)上面是 4*(1/3)^2=4/9, 两者之比 5:1
假设不是上图的 1/2 分时驱动而是 1/4 分时驱动,这个份额将变为
2*1^2+6*(1/3)^2 vs 8*(1/3)^2 = 3:1
若将本来的 1/2 Bias 改用 1/3 Bias 驱动,关于我的LCD屏这个比值从 7:3 改善为 3:1 了。已然PIC16F913只规划了 1/2 Bias与1/3 Bias,用起来应该问题不大。
AVR单个I/O口要完成4种电压输出——不行能吧,我是想不出来了。AVR最多只要三种电压输出,能不能对这个电压再做等分呢?一番思索之后我想这样行不行:就4等分吧.
COM1: V+ ——–
3/4
1/2 ——– ——–
1/4
GND ——–
COM2: V+ ——–
3/4
1/2 ——– ——–
1/4
GND ——–
SEG1: V+
3/4 ——– ———
1/2
1/4 —————-
GND
SEG2: V+
3/4 —————-
1/2
1/4 ——– ———
GND
我的做法便是 SEGx 输出有两种:3/4*Vcc 和 1/4*Vcc, 而 COMy 输出有三种:Vcc, GND, 1/2*Vcc. 关于每个I/O口,并不需求4种电压输出。当然这样跟1/3 Bias驱动是不相同的,可是却到达了 1/3 Bias 驱动的作用,只不过加在液晶笔段上的电压绝对值最大不是 Vcc 而是 3/4*Vcc 了,因而电源电压也需求进步。这儿核算省掉。
这种驱动方法我称之为 “伪1/3 Bias驱动”. 关于 COMy 的处理和前面相同,关于 SEGx, 将I/O输出电压改动一下,高电平3/4*Vcc, 低电平1/4*Vcc就好了。我的做法是:
/————– I/O Port pin
|
[ ]
[ ] 1Meg
[ ]
|
to LCD SEGx ————–+
|
[ ]
[ ] 1Meg
[ ]
|
|
1/2 Vcc
这儿的 1/2 Vcc 能够将电源电压用电阻分压得到,我想的方法是直接接个几uF电容到GND, 试验是成功的。由于跟着扫描的进行,这个当地的均匀电压是输出高电平和低电平的一半。
现在我做了一个Mega48V的秒计数器,再改改就能把钟做出来了。

 
这是我的程序:(由于刚刚开端用AVR,从最简略的开端,就直接用汇编了)
Timer2用外接32768晶振供给时钟,整个体系耗电大约30微安。
; lcddisplay.asm
; Test raw LCD display
.include “m48def.inc”
.org 0x0000
rjmp start
.org OC2Aaddr
rjmp isr_timer2
.org 0x0020
table:
.DB 0b11101101, 0b00101000, 0b10110101, 0b10111001
.DB 0b01111000, 0b11011001, 0b11011101, 0b10101000
.DB 0b11111101, 0b11111001
start:
ldi r16, 1<out MCUCR, r16 ; disable all I/O pull-up
ldi r16, 1 ldi r16, 1<sts TCCR2A, r16 ; CTC mode
ldi r16, 31
sts OCR2A, r16 ; preset compare A
ldi r16,1<; ldi r16,1<sts TCCR2B, r16
ldi r16, 1<out TIFR2, r16 ; clear flag
ldi r16, 1<sts TIMSK2, r16 ; enable interrupt on compare match A
ser r16
out DDRD, r16 ; Port D output — LCD segment control
clr r5
ldi r16, 0x55
mov r6, r16
clr r7
clr r8
ldi r16, 9
mov r10, r16
mov r11, r16
mov r12, r16
mov r13, r16
dec r10
sei ; enable global interrupt
ldi r16, (1<out SMCR, r16 ; use Idle mode here, waiting 1 second
clr r2
iniw:sleep
dec r2
brne iniw
ldi r16, (1<out SMCR, r16 ; use power-save mode
nop
nop
clr r2
loop:
nop
nop
sleep
nop
nop
dec r2
dec r2
breq adjtime
rjmp loop
adjtime:
ldi r17, 10
inc r10
cp r10, r17
brne updcount
clr r10
inc r11
cp r11, r17
brne updcount
clr r11
inc r12
cp r12, r17
brne updcount
clr r12
inc r13
cp r13, r17
brne updcount
clr r13
updcount:
rcall calcor
rjmp loop
isr_timer2:
clr r16
out DDRC, r16 ; float all COMx pins
bst r4, 1
brts show34
bst r4, 0
brts show2
mov r0, r5
ldi r18, 1
rjmp sel
show2:
mov r0, r6
ldi r18, 1<<1
rjmp sel
show34:
bst r4, 0
brts show4
mov r0, r7
ldi r18, 1<<2
rjmp sel
show4:
mov r0, r8
ldi r18, 1<<3
sel:
bst r4, 2
brtc lcden
com r0
com r16
lcden:
out PORTC, r16
out PORTD, r0
out DDRC, r18
iext:inc r4
reti
calcor: ; translate R10~~R13 to R5~~R8
clr r5
clr r6
clr r7
clr r8
ldi ZH, high(table<<1)
ldi ZL, low(table<<1)
add ZL, r10
lpm ; load table data to R0
rcall filler
ldi ZL, low(table<<1)
add ZL, r11
lpm
rcall filler
ldi ZL, low(table<<1)
add ZL, r12
lpm
rcall filler
ldi ZL, low(table<<1)
add ZL, r13
lpm
rcall filler
ret
filler:
rol r0
rol r5
rol r0
rol r5
rol r0
rol r6
rol r0
rol r6
rol r0
rol r7
rol r0
rol r7
rol r0
rol r8
rol r0
rol r8
ret
 

弥补一下, 液晶屏的引脚与笔划的对应跟LED数码管或许不相同, 我这个屏是这样的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
< 1f 1a 2f 2a 3f 3a 4f 4a > — —- COM1
< 1g 1b 2g 2b 2g 3b 4g 4b > — —- COM2
< 1e 1c 2e 2c : 3e 3c 4e 4c > — —- COM3
1d 1h 2d 2h 3d 3h 4d — —- COM4
其间 12,13,14,15 是4个公共端; 2,3操控第一个数字; 4,5第二个; 7,8第三个; 9,10第四个。

############################################################

前年,有一个家用热水器操控项目,硬件与软件是分开搞的.为了省本钱,硬件工程师不必专用液晶驱动%&&&&&%,把我搞得够呛.整个项目20天时刻,光液晶驱动程序用去了10多天.
I/O端口SEG与COM口别离串接一只电阻,再并联一只电阻到地,

这样,对液晶来讲,I/O口是电源/地,守时改动SEG/COM的H/L电平,相当于1/2VCC的沟通信号.
当SEG/COM一起为H或L电平常,对液晶来讲,都是关,SEG/COM电平不等时,段码就能显现出来.
理解了这个道理,用C言语写出来不难.

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/ziliao/sheji/266155.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部