用I/O 驱动LCD
在现今的电子产品中,LCD 显示被广泛的应用。LCD 显示驱动有内建于 MCU 中
的亦有独立于 MCU 单一的驱动 IC。这些 LCD 能驱动的点数一般比较多,在一些需
要显示点数不多的应用中这些 IC 就显的浪费。所以在这里我们介绍一种用 I/O 来
驱动 LCD 做显示的方法来满足一些点数不多的显示应用。
1. I/O 驱动LCD 原理
LCD 的显示原理请参考 3.6 节,这里不多叙述。大家都知道 I/O 口最多只能有
三种状态: 高电平,低电平及悬空状态(Floating)如何造出 LCD 驱动波形呢? 下
面我们以 2X8(2 个 COM 和 8 个 SEG)的例子来做一介绍。观察图 5-14,这是一个
1/2bias,1/2duty 的 LCD 驱动波形,观察 COM0 和 COM1 可以发现同一时间内只有
一个 COM 口有输出,它的平均电压为零。节点信号 SEGMENT 则表示要显示的数据,
如果节点信号与 COM 口之间有出现脉冲,代表对应的这个点是亮的,反之则是暗
的。在知道要显示的内容的情况下,如果是要显示,那么 SEGMENT 的信号就和 COM
相反而产生脉冲,如果是不显示,那么 SEGMENT 的信号就和 COM 的信号一样而两
端之间没有脉冲,没有显示。
有了 LCD 驱动波形的概念之后,接着就可以着手
设计
领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计
电路了,观察 SEGMENT
上的波形,对微控制器来讲不是问题,VLCD=1,VSS=0 就能造出漂亮的方波。那
COMMON 上面的阶梯波怎么解决呢? 其实只要利用 I/O Port 三种状态就可实现,如
图 1-1 所示,PD1、PD2 为 COM0、COM1 的输出波形,利用两个分压电阻以及 I/O Port
的特性,表 1-1 是它的真值表,由此表不难看出,要产生 VDD 或者 0 电压,只要
利用端口输出 1或者 0就可以产生,可是没有直接输出 1/2 VDD(V1)。其实要产生
1/2VDD 是很简单的,因为当 I/O Port 设成输入时形成一个高阻抗的状态,对 COM
而言所看到的只是 R1 和 R2 分压而已。所以我们 将 R1=R1=100K 欧姆,那么在 COM
端来说就是 1/2VDD 的电压了。
表 1-1 图 1-1 1/2 bias 与 1/2 duty
图 1-2
同理如果您需要 1/3 bias 的场合,如图 1-3 所示再变化一下 I/O 的状态,但是
SEGMENT 与 COMMON 都需要电阻分压,而且驱动一条 LCD Pin 需要两个 I/O,不管
对多点数或者少点数来说,都十分不经济,相对地程序也会更复杂。
PD1 COM0 电压
0 VSS
1 VLCD
Floating V1
GND1
PD0/vpp2
PD13
OSCI/PE04
OSCO/PE15
PD26
PC07
PC18
PC29
PC310 PB0 11
PB1 12
PB2 13
PB3 14
sda/PA0 15
PA1 16
PA2 17
PA3 18
REM 19
VDD 20
SH
67P33A
U1
SH67P33A
R1
100K
R3
100K
R2
100K
R4
100K
VCC
C1 104
E1
47uF/16V
SEG0
SEG1
SEG2
SEG3
SEG4
SEG5
SEG6
SEG7
COM0
COM1
SEG01
SEG12
SEG23
SEG34
SEG45
SEG56
SEG67
SEG78
COM09
COM110
LCD1
PANAL
图 5-16 1/3bias 原理及真值表
图 1-3
2. 电路设计
利用 SH67P33 的 PORTD1,2 来做为 COM 口,PORTA,B 共 8 个 I/O 做为 SEG 来驱
动 2个 8段 LCD 显示“Po”,原理图如图 5-4-2。其真值表如 1-2 所示。
表 1-2
SEG0 SEG1 SEG2 SEG3 SEG4 SEG5 SEG6 SEG7
COM0 1A 1B 1C 2A 2B 2C
COM1 1F 1G 1E 1D 2F 2G 2E 2D
程序设计
例[2-1]
;;;;;;;;;;;;;;;;system
define ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IE EQU 00H ;中断允许标志
IRQ EQU 01H ;中断请求标志
PA EQU 08H ;PORT A 数据寄存器
PB EQU 09H ; PORTB 数据寄存器
PC EQU 0AH ; PORT C 数据寄存器
PD EQU 0BH ; PORT D 数据寄存器
PE EQU 0CH ; PORT E 数据寄存器
PACR EQU 16H ; PORT A 输入输出控制寄存器
PBCR EQU 17H ; PORT B 输入输出控制寄存器
PCCR EQU 18H ; PORT C 输入输出控制寄存器
PDCR EQU 19H ; PORT D 输入输出控制寄存器
PECR EQU 1AH ; PORT E 输入输出控制寄存器
PMOD EQU 12H ;BIT0-BIT2:载波输出时钟预分频设定
;BIT3:下拉允许控制位
DPL EQU 10H ;数据指针低位
DPM EQU 11H ;数据指针中间位
R2
50K
R1
50K
R3
50K
pa
pb out
pa pb out(vcc)
1 1
10
01
0 0
1
2/3
1/3
0
1/3 bias design
DPH EQU 12H ;数据指针高位
INX EQU 0FH ;间接索引寄存器
;;;;;;;;;;;;;;;; ram
define ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ACCBK EQU 20H ;备份 ACC 寄存器
SCANFLAG EQU 2CH ;信号输出扫描寄存器
COMP EQU 1H ;0=扫描 COM0 端 1=扫描 COM1 端
CYCLE EQU 2H ;0=扫描端口的前半周期, 1=扫描端口的后半周期
TEMP EQU 30H ;4 位临时寄存器
TEMPL EQU 31H ;8 位临时寄存器低位
TEMPH EQU 32H ;8 位临时寄存器高位
PABUF EQU 38H ;PORTA 输出缓冲
PBBUF EQU 39H ;PORTB 输出缓冲
PCBUF EQU 3AH ;PORTC 输出缓冲
SEG0 EQU 40H ;LCD 显示区 ;PA0 端输出
SEG1 EQU SEG0+1 ;LCD 显示区 ;PA1 端输出
SEG2 EQU SEG0+2 ;LCD 显示区 ;PA2 端输出
SEG3 EQU SEG0+3 ;LCD 显示区 ;PA3 端输出
SEG4 EQU SEG0+4 ;LCD 显示区 ;PB0 端输出
SEG5 EQU SEG0+5 ;LCD 显示区 ;PB1 端输出
SEG6 EQU SEG0+6 ;LCD 显示区 ;PB2 端输出
SEG7 EQU SEG0+7 ;LCD 显示区 ;PB3 端输出
;;;;;;;;;;;;;;;; CONSTANT
define ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
COMCR EQU PDCR ;定义 COM 端输入输出控制寄存器
COM EQU PD ;定义 COM 输出端口
IET0 EQU 04H ;
SCALE8 EQU 0100B ;
ORG 0000H
JMP RESET ;复位入口地址
JMP ONLYRET
JMP T0ISR ;定时器 T0 中断入口地址
JMP ONLYRET
JMP PBCISR ;PBC 中断入口地址
PBCISR:
ONLYRET:
RTNI ;推出 PBC 中断
;LCD 刷新 32hz,FRAME=1000/32HZ=31.25ms,所以 FRAME/4=7.8125ms 约等于 8ms。
;定时器 8ms 溢出,振荡器采用内部 4M RC,系统时钟采用 16 分频。
;定时器设置为计数 250,所以初值为 6。
;所以 8000/250=32,算出 timer0 预分频 32/4=8
T0ISR:
STA ACCBK,00H ;备份 ACC 到寄存器在 ACCBK
LDI WDT,08H ;清除 watchdog 计数
EORIM SCANFLAG,CYCLE ;切换扫描端口输出周期
LDA SCANFLAG,00H
STA TEMP,00H
ANDIM TEMP,03H
SBI TEMP,03H
BAZ CANCOM11 ;扫描 com1 的后半周期
SBI TEMP,02H
BAZ SCANCOM10 ;扫描 com0 的后半周期
SBI TEMP,01H
BAZ SCANCOM01 ;扫描 com1 的前半周期
SCANCOM00: ;扫描 com0 的前半周期
LDI COMCR,0010B ;COM0 输出,COM1 输入
LDI COM,0000B ;COM0 输出低电平
LDI PABUF,0FH
LDA SEG0,00H ;输出 SEG0.0 到 PA0
BA0 $+2
ANDIM PABUF,1110B
LDA SEG1,00H ;输出 SEG1.0 到 PA1
BA0 $+2
ANDIM PABUF,1101B
LDA SEG2,00H ;输出 SEG2.0 到 PA2
BA0 $+2
ANDIM PABUF,1011B
LDA SEG3,00H ;输出 SEG3.0 到 PA3
BA0 $+2
ANDIM PABUF,0111B
LDA PABUF,00H
STA PA,00H
LDI PBBUF,0FH
LDA SEG4,00H ;输出 SEG4.0 到 PB0
BA0 $+2
ANDIM PBBUF,1110B
LDA SEG5,00H ;输出 SEG5.0 到 PB1
BA0 $+20
ANDIM PBBUF,1101B
LDA SEG6,00H ;输出 SEG6.0 到 PB2
BA0 $+2
ANDIM PBBUF,1011B
LDA SEG7,00H ;输出 SEG7.0 到 PB3
BA0 $+2
ANDIM PBBUF,0111B
LDA PBBUF,00H
STA PB,00H
JMP T0RET
SCANCOM10: ;扫描 COM0 后半周期
LDI COMCR,0010B ;COM0 输出,COM1 输入
LDI COM,0010B ;COM0 输出高电平
LDI PABUF,00H
LDA SEG0,00H ;输出 SEG0.0 到 PA0
BA0 $+2
ORIM PABUF,0001B
LDA SEG1,00H ;输出 SEG1.0 到 PA1
BA0 $+2,00H
ORIM PABUF,0010B
LDA SEG2,00H ;输出 SEG2.0 到 PA2
BA0 $+2
ORIM PABUF,0100B
LDA SEG3,00H ;输出 SEG3.0 到 PA3
BA0 $+2
ORIM PABUF,1000B
LDA PABUF,00H
STA PA,00H
LDI PBBUF,00H
LDA SEG4,00H ;输出 SEG4.0 到 PB0
BA0 $+2
ORIM PBBUF,0001B
LDA SEG5,00H ;输出 SEG5.0 到 PB1
BA0 $+2
ORIM PBBUF,0010B
LDA SEG6,00H ;输出 SEG6.0 到 PB2
BA0 $+2
ORIM PBBUF,0100B
LDA SEG7,00H ;输出 SEG7.0 到 PB3
BA0 $+2
ORIM PBBUF,1000B
LDA PBBUF,00H
STA PB,00H
JMP T0RET
SCANCOM01: ;扫描 COM1 前半周期
LDI COMCR,0100B ;COM0 输入,COM1 输出
LDI COM,0000B ;COM1 输出低电平
LDI PABUF,0FH
LDA SEG0,00H ; 输出 SEG0.1 到 PA0
BA1 $+2
ANDIM PABUF,1110B
LDA SEG1,00H ; 输出 SEG1.1 到 PA1
BA1 $+2
ANDIM PABUF,1101B
LDA SEG2,00H ; 输出 SEG2.1 到 PA2
BA1 $+2
ANDIM PABUF,1011B
LDA SEG3,00H ; 输出 SEG3.1 到 PA3
BA1 $+2
ANDIM PABUF,0111B
LDA PABUF,00H
STA PA,00H
LDI PBBUF,0FH
LDA SEG4,00H ; 输出 SEG4.1 到 PB0
BA1 $+2
ANDIM PBBUF,1110B
LDA SEG5,00H ; 输出 SEG5.1 到 PB1
BA1 $+2
ANDIM PBBUF,1101B
LDA SEG6,00H ; 输出 SEG6.1 到 PB2
BA1 $+2
ANDIM PBBUF,1011B
LDA SEG7,00H ; 输出 SEG7.1 到 PB3
BA1 $+2
ANDIM PBBUF,0111B
LDA PBBUF,00H
STA PB,00H
JMP T0RET
SCANCOM11: ;扫描 COM1 后半周期
LDI COMCR,0100B ;COM0 输入,COM1 输出
LDI COM,0100B ;COM1 输出高电平
LDI PABUF,0H0
LDA SEG0,00H ; 输出 SEG0.1 到 PA0
BA1 $+2
ORIM PABUF,0001B
LDA SEG1,00H ; 输出 SEG1.1 到 PA1
BA1 $+2
ORIM PABUF,0010B
LDA SEG2,00H ; 输出 SEG2.1 到 PA2
BA1 $+2
ORIM PABUF,0100B
LDA SEG3,00H ; 输出 SEG3.1 到 PA3
BA1 $+2
ORIM PABUF,1000B
LDA PABUF,00H
STA PA,00H
LDI PBBUF,00H
LDA SEG4,00H ; 输出 SEG4.1
BA1 $+2
ORIM PBBUF,0001B
LDA SEG5,00H ; 输出 SEG5.1
BA1 $+2
ORIM PBBUF,0010B
LDA SEG6,00H ; 输出 SEG6.1
BA1 $+2
ORIM PBBUF,0100B
LDA SEG7,00H ; 输出 SEG7.1
BA1 $+2
ORIM PBBUF,1000B
LDA PBBUF,00H
STA PB,00H
JMP T0RET
T0RET:
LDA SCANFLAG,00H ;检测是否是后半周期
BA1 $+2
JMP $+2
EORIM SCANFLAG,COMP ;如果是后半周期的话就切换 COM 端口
LDI IRQ,00H ;清除中断请求标志
LDI IE,IET0 ;允许定时器 T0 中断
LDA ACCBK,00H ;恢复 ACC 的值
RTNI
RESET:
NOP ;上电稳定空跑 4条指令
NOP
NOP
NOP
LDI WDT,08H ;清除 watchdog 计数
LDI IRQ,00H ;清除中断请求标志
LDI IE,00H ;不允许中断
LDI TEMPH,0FH ;上电延时
LDI TEMPL,0FH
SBIM TEMPL,01H
BC $-1
LDI WDT,08H
SBIM TEMPH,01H
BC $-4
LDI REM,00H ;关闭红外输出
LDI PACR,0FH ;PA 设置为输出
LDI PBCR,0FH ;PB 设置为输出
LDI PCCR,0FH ;PC 设置为输出
LDI PDCR,06H ;PD1,PD2 设置为输出,PD0 为输入
LDI PECR,0FH ;PE 设置为输出
LDI PA,00H ;PA 输出低电平
LDI PD,00H ;PD 输出低电平
LDI PE,00H ;PE 输出低电平
LDI PB,00H ;PB 输出低电平
LDI PC,00H ;PC 输出低电平
LDI PMOD,0101B ;不允许内部上下拉电阻
CLEARRAM: ;清 0 RAM 020H-4FH 区
LDI DPL,00H
LDI DPM,02H
LDI DPH,00H
?CLRINX:
LDI INX,00H
ADIM DPL,01H
BNC ?CLRINX
ADIM DPM,01H
ANDIM DPM,07H
SBI DPM,05H
BNC ?CLRINX
LDI T0M,SCALE8 ;设置定时器 T0 预分频为 8分频
LDI T0L,06H ;设置定时期初值为 6
LDI T0H,00H
LDI IE,IET0 ;允许定时器中断
LDI SEG0,03H ;设置显示的“Po”显示区数据
LDI SEG1,03H
LDI SEG2,02H
LDI SEG3,00H
LDI SEG4,00H
LDI SEG5,02H
LDI SEG6,03H
LDI SEG7,02H
TOHALT:
LDI WDT,08H ;清除 watchdog 计数
LDI IRQ,00H ;清除中断请求标志
LDI IE,IET0 ;允许定时器 T0 中断
NOP
HALT ;halt
NOP
NOP
NOP
JMP TOHALT
END