5.3.4. 液晶LCD显示驱动程序
1.LCD驱动器1621
HT1621为128(32×4)段LCD驱动器。它可设置为1/2或1/3偏置且通过S/W配置设置为2,3或4个共用的LCD驱动器。这使得HT1621适于多LCD应用。LCD驱动时钟

图5.6 HT1621功能框图
从系统时钟内产生,一般为256KHZ。图5.6为HT1621功能框图
2.EM78X56与HT1621接口
EM78X56与HT1621接口只须四条线。CS线用以初始化串行接口电路且终止EM78X56与HT1621的通信。若CS=1,EM78X56及HT1621间发送的命令首先被禁止即而进行初始化。在模式命令或模式转换发出前,需要一高电平脉冲以初始化HT1621的串行接口,数据的读/写及命令的写人必须通过数据线。RD为输入,RAM内的数据在RD信号的下降沿同步送出至数据线上。这使EM78X56可以在RD信号的升沿及下一个下降沿到来期间读人正确的数据。WR为写输入,数据线上的数据、地址及命令将在WR信号上升写入HT1621。一条可选择的IRQ线也可用作EM78X56及HT1621间的接口。
1.
读/写命令时序控制及命令集
读/写命令时序控制及命令集


|
|
Command Code |
D/C |
Function |
|
READ |
110
a5 a4 a3 a2 a1 a0 d0 d1 d2 d3 |
D |
Read data in the RAM |
|
WRITE |
101
a5 a4 a3 a2 a1 a0 d0 d1 d2 d3 |
D |
Write data to the RAM |
|
READ
MODIFY
WRITE |
101
a5 a4 a3 a2 a1 a0 d0 d1 d2 d3 |
D |
READ and WRITE to RAM |
|
SYS DIS |
100000000000X |
C |
Turn off bth system oscillator
And LCD blas generator |
|
SYS EN |
100000000001X |
C |
Turn on system oscillator |
|
LCD OFF |
100000000010X |
C |
Turn off LCD blas generator |
|
LCD ON |
100000000011X |
C |
Turn on LCD bias generator |
|
XTAL 32K |
1000000101XXX |
C |
System clock source,crystal
oscillator |
|
BIAS 1/2 |
1000010abX0X |
C |
LCD 1/2 bias sption
ab=00:2 commons option
ab=01:3 commons option
ab=10:4 commons option |
|
BIAS 1/3 |
1000010abX1X |
C |
LCD 1/2 bias sption
ab=00:2 commons option
ab=01:3 commons option
ab=10:4 commons option |
4. 应用电路

图 5.7 HT1621应用框图
5. 编程示例
R1 EQU 0X01
R2 EQU 0X02
R3 EQU 0X03
IOC5 EQU 0X05
IOC6 EQU 0X06
PORT5 EQU 0X05
PORT6 EQU 0X06
IOCB EQU 0X0B
IOCC EQU 0X0C
IOCD EQU 0X0D
IOCE EQU 0X0E
IOCF EQU 0X0F
S1 EQU 0X10
S2 EQU 0X11
S3 EQU 0X12
S4 EQU 0X13
S5 EQU 0X14
S6 EQU 0X15
S7 EQU 0X16
S8 EQU 0X17
S8S7 EQU 0X18
S9 EQU 0X19
S10 EQU 0X1A
COMMAND EQU 0X1B
R_LOOP EQU 0X1C
S_LOOP EQU 0X1D
SEG0 EQU 0X1E
SEG1 EQU 0X1F
SEG2 EQU 0X20
SEG3 EQU 0X21
SEG4 EQU 0X22
SEG5 EQU 0X23
SEG6 EQU 0X24
SEG7 EQU 0X25
SEG8 EQU 0X26
SEG9 EQU 0X27
SEG10 EQU 0X28
LCD_MAP EQU 0X29
LCDRAM EQU 0X2A
KEY2 EQU 0X2B
KEY7 EQU 0X2C
KEY_SX EQU 0X2D
LP_CNT0 EQU 0X2E
LP_CNT1 EQU 0X2F
ORG 0X000
JMP MAIN
NOP
MAIN: CLRA ;P50-P53 SET TO OUTPUT
IOW IOC5
IOW IOCE
MOV A,@0B11110000 ;P60-P63 SET TO OUTPUT
IOW IOC6 ;P64-P67 SET TO INPUT
MOV A,@0X0F
MOV PORT5,A ;P50-P53 RESET TO 1
CLR PORT6 ;P60-P63 RESET TO 0
BC PORT5,0 ;RESET 1621 INTERFACE
BS PORT5,0
BC PORT5,0
BS PORT5,0 ;P50 SET TO 1,/CS=1
MOV A,@0B11100011 ;COMMAND TNORMAL
MOV COMMAND,A
CALL C_WRITE
MOV A,@0B10000000 ;COMMAND /IRQ DIS
MOV COMMAND,A
CALL C_WRITE
MOV A,@0B00010100 ;COMMAND XTAL32K
MOV COMMAND,A
CALL C_WRITE
MOV A,@0B00101001 ;COMMAND BIAS1/3,4 COM
MOV COMMAND,A
CALL C_WRITE
MOV A,@0B00001000 ;COMMAND TONE OFF
MOV COMMAND,A
CALL C_WRITE
MOV A,@0B00000101 ;COMMAND WDT DIS
MOV COMMAND,A
CALL C_WRITE
MOV A,@0B00000100 ;COMMAND TIMER DIS
MOV COMMAND,A
CALL C_WRITE
MOV A,@0B00000001 ;COMMAND SYS_EN
MOV COMMAND,A
CALL C_WRITE
MOV A,@0B00000011 ;COMMAND LCD_ON
MOV COMMAND,A
CALL C_WRITE
MOV A,@0X0FF ;LCD MAP SET TO 1
MOV SEG0,A
MOV SEG2,A
MOV SEG3,A
MOV SEG4,A
MOV SEG5,A
MOV SEG6,A
MOV SEG7,A
MOV SEG8,A
MOV SEG9,A
MOV SEG10,A
CLR LCD_MAP ;FIRST MAP ADD IS 0
CALL LCD_WRITE ;DISPLAY ALL SEGS
(BREAK):
LCD_OFF: CLR COMMAND ;TURN OFF LCD SYSTEM
CALL C_WRITE
C_WRITE: MOV A,@0X08
MOV R_LOOP,A
BS PORT5,2 ;/WR=1
BC PORT5,0 ;/CS=0
BC PORT5,2 ;/WR=0
BS PORT5,3 ;DATA=1
BS PORT5,2 ;/WR=1
BC PORT5,2 ;/WR=0
BC PORT5,3 ;DATA=0
BS PORT5,2 ;/WR=1
BC PORT5,2 ;/WR=0
BC PORT5,3 ;DATA=0
BS PORT5,2 ;/WR=1
BC PORT5,2 ;/WR=0
C8_C1_WRITE: JBC COMMAND,7 ;COMMAND,7=0
JMP SET_DATA_1
BC PORT5,3 ;DATA=0
JMP NEXT_1
SET_DATA_1: BS PORT5,3 ;DATA=1
NEXT_1: RLC COMMAND
BS PORT5,2 ;/WR=1
BC PORT5,2 ;/WR=0
DJZ R_LOOP
JMP C8_C1_WRITE
BC PORT5,3 ;DATA=0
BS PORT5,2 ;/WR=1
BS PORT5,0 ;/CS=1
RET
LCD_WRITE: BS PORT5,2 ;/WR=1
BC PORT5,0 ;/CS=0
BC PORT5,2 ;/WR=0
BS PORT5,3 ;DATA=1
BS PORT5,2 ;/WR=1
BC PORT5,2 ;/WR=0
BC PORT5,3 ;DATA=0
BS PORT5,2 ;/WR=1
BC PORT5,2 ;/WR=0
BS PORT5,3 ;DATA=1
BS PORT5,2 ;/WR=1
BC PORT5,2 ;/WR=0
;WRITE THE LCD MEMORY ADD 00
BC PORT5,3 ;DATA=0, 1
BS PORT5,2 ;/WR=1
BC PORT5,2 ;/WR=0
;DATA=0, 2
BS PORT5,2 ;/WR=1
BC PORT5,2 ;/WR=0
;DATA=0, 3
BS PORT5,2 ;/WR=1
BC PORT5,2 ;/WR=0
;DATA=0, 4
BS PORT5,2 ;/WR=1
BC PORT5,2 ;/WR=0
;DATA=0, 5
BS PORT5,2 ;/WR=1
BC PORT5,2 ;/WR=0
;DATA=0, 6
BS PORT5,2 ;/WR=1
MOV A,SEG0
MOV LCDRAM,A ;SEG0
CALL LCDDATA_W
MOV A,SEG1
MOV LCDRAM,A ;SEG1
CALL LCDDATA_W
MOV A,SEG2
MOV LCDRAM,A ;SEG2
CALL LCDDATA_W
MOV A,SEG3
MOV LCDRAM,A ;SEG3
CALL LCDDATA_W
MOV A,SEG4
MOV LCDRAM,A ;SEG4
CALL LCDDATA_W
MOV A,SEG5
MOV LCDRAM,A ;SEG5
CALL LCDDATA_W
MOV A,SEG6
MOV LCDRAM,A ;SEG6
CALL LCDDATA_W
MOV A,SEG7
MOV LCDRAM,A ;SEG7
CALL LCDDATA_W
MOV A,SEG8
MOV LCDRAM,A ;SEG8
CALL LCDDATA_W
MOV A,SEG9
MOV LCDRAM,A ;SEG9
CALL LCDDATA_W
MOV A,SEG10
MOV LCDRAM,A ;SEG10
CALL LCDDATA_W
BS PORT5,0 ;/CS=1
RET
LCDDATA_W: MOV A,@0X04 ;RAM DATA WRITE
MOV R_LOOP,A
DATA_W JBC LCDRAM,0
JMP RAM_SET
BC PORT5,3 ;DATA=0
JMP NEXT_3
RAM_SET: BS PORT5,3 ;DATA=1
NEXT_3: RRC LCDRAM
BS PORT5,2 ;/WR=1
BC PORT5,2 ;/WR=0
DJZ R_LOOP
JMP DATA_W
RET
EOP
5.3.5. 异步串行通信
在EM78系列单片机内部没有异步串行口,所以必须用软件来完成这个工作。在很多实际应用中,我们已经采用了软件实现RS232标准的异步串行通信,结果证明工作非常稳定可靠。用软件完成串行通信,降低了芯片的硬件成本。
下面给出RS232的发送和接收的程序和流程,供读者参考。

图5.8 RS232的发送和接收流程
程序清单如下:
;定义
STATUS EQU 3
P5 EQU 5
P6 EQU 0X06
BUFFER EQU 0X11
COUNT EQU 0X12
BITNUM EQU 8 ;每字节数据为8位
ORG 0
JMP MAIN
;主程序
MAIN: MOV A,@0X40 ;置P6.5为输出口,P6.6为输入口
IOW P6
CLR BYTE
MOV A,@BITNUM
MOV COUNT,A ;传送数据为每字节8位
;以下为接收
TEST: JBC P6,6 ;检测是否收到起始位
JMP TEST ;未测到
CALL DELAY ;测到起始位,下面准备接收
CALL DELAY ;延时
START: JBC P6,6
BS BYTE,7 ;收到高电平
JBS P6,6
BC BYTE,7 ;收到低电平
DJZ COUNT
JMP L1 ;一个字节未收完,继续收下一位
CALL DELAY
JMP TRANSMIT ;一个字节收完,准备发送
L1: RRC BYTE
CALL DELAY
JMP START
;以下为发送
TRANSMIT:
MOV A,@BITNUM
MOV COUNT,A
BEGIN: BC P6,5 ;发送起始位
CALL DELAY1 ;延时
L2: RRC BYTE ;发送一位数据
JBC STATUS,C
BS P6,5
JBS STATUS,C
BC P6,5
CALL DELAY1 ;延时
DJZ COUNT ;一个字节发送完否?
JMP L2 ;否,继续发送下一位
BS P6,5 ;是
CALL DELAY1
JMP TEST ;继续循环
;延时子程序
DELAY: MOV A,@23
MOV BUFFER,A
LOOP: DJZ BUFFER
JMP LOOP
RET
DELAY1: MOV A,@30
MOV BUFFER,A
LOOP1: DJZ BUFFER
JMP LOOP1
RET
5.3.6. I2C串行总线的控制
I2C串行总线具有占用I/O口少,控制方式简单,信号传输速度快,配套功能芯片种类多的优点,非常适用于单片机系统设计中,I2C串行总线由两根线构成:数据线(SDA),时钟线(SCL),其数据传输过程在很多书中都有介绍,这里不做专门说明。下面以24CXX系列SEEPROM为例介绍EM78系列单片机如何设计I2C总线接口。
1.电路设计电路连接如图5.9所示:
图 5.9 EM78XX单片机与24CXX电路连接
2.程序流程图
程序流程图如图5.10所示。
SEEPROM 写入数据传送格式如下:
|
START |
从地址 |
0 |
A |
地址字节 |
A |
数据字节1 |
A |
… |
数据字节N |
A |
STOP |
A为从设备的确认位。
SEEPROM 读出数据传送格式如下:(A为确认位。)
|
START |
从地址 |
0 |
A |
地址字节 |
A |
START |
从地址 |
1 |
A |
数据字节 |
A |
。。。 |
最后字节 |
STOP |
图 5.10 程序流程图
3.参考例程
;*****************************************************************************
;** EM78单片机与24Cxx / 85Cxx 串行CMOS EEPROM接口I2C总线读/写的程序
;** (所有时隙均基于2MHZ晶体震荡器频率)
;*****************************************************************************
; 存储器定义
PC EQU 2 ; Program counter
STAT EQU 3 ; EM78 status byte
FSR EQU 4 ; RAM 选择寄存器
P5 EQU 5 ; Port A use to select device address
P6 EQU 6 ; P6.7 = SDA, P6.6 = SCL
;
STATUS EQU 08 ; Status register
FLAG EQU 09 ; Common flag bits register
EEPROM EQU 0A ; Bit buffer
ERCODE EQU 0B ; Error code (to indicate bus status)
ADDR EQU 10 &, nbsp; ; Address register
DATAI EQU 11 ; Stored data input register
DATAO EQU 12 ; Stored data output register
SLAVE EQU 13 ; Device address (1010xxx0)
TXBUF EQU 14 ; TX buffer
RXBUF EQU 15 ; RX buffer
COUNT EQU 16 , ; Bit counter
TIMER0 EQU 18 ; Delay timer0
TIMER1 EQU 19 ; Delay timer1
;-----------------------------------------------------------------------------
; 位定义
; Status bits
Z EQU 2
C EQU 0
; FLAG Bits
ERROR EQU 0 ; Error flag
; EEPROM Bits
DI EQU 7 ; EEPROM input
DO EQU 6 ; EEPROM output
; I2C Device Bits
SDA EQU 7 ; P6.7, data in/out
SCL EQU 6 ; P6.6, serial clock
;-----------------------------------------------------------------------------
; 两线I2C - CPU 通信错误状态表和子程序
; input : W-reg = error code
; output : ERCODE = error code
; FLAG(ERROR) = 1
; code error status mode
; ------- ------------------------------------------------------
; 1 : SCL locked low by device (bus is still busy)
; 2 : SDA locked low by device (bus is still busy)
; 3 : No acknowledge from device (no handshake)
; 4 : SDA bus not released for master to generate STOP bit
;-----------------------------------------------------------------------------
org 0x0000
JMP start
;按照错误状态表识别SCL状态和SDA数据子程序
ERR
JBS FLAG,ERROR ; Remain as first error encountered
MOV ERCODE,A ; Save error code
BS FLAG,ERROR ; Set error flag
RET
;-----------------------------------------------------------------------------
; 启动总线通信程序
; input : none
; output : initialize bus communication
;-----------------------------------------------------------------------------
;Generate START bit (SCL is high while SDA goes from high to low transition)
;and check status of the serial clock.
BSTART
MOV A,@B'00111111' ; Put SCL, SDA line in output state
IOW P6
bs P6,SDA ;make sure sda is high
BS P6,SCL ; Set clock high
MOV A,@1 ; Ready error status code 1
JBS P6,SCL ; Locked?
CALL ERR ; SCL locked low by device
BC P6,SDA ; SDA goes low during SCL high
NOP ; Timing adjustment
NOP
NOP
BC P6,SCL ; Start clock train
RET
;-----------------------------------------------------------------------------
; 启动总线通信程序
; Input : None
; Output : Bus communication, STOP condition
;-----------------------------------------------------------------------------
;Generate STOP bit (SDA goes from low to high during SCL high state)
;and check bus conditions.
BSTOP
MOV A,@B'00111111' ; Put SCL, SDA line in output state
IOW P6
BC P6,SDA ; Return SDA to low
BS P6,SCL ; Set SCL high
nop
nop
MOV A,@1 ; Ready error code 1
JBS P6,SCL ; High?
CALL ERR ; No, SCL locked low by device
BS P6,SDA ; SDA goes from low to high during SCL high
MOV A,@4 ; Ready error code 4
JBS P6,SDA ; High?
CALL ERR ; No, SDA bus not release for STOP
RET
END SUB
;-----------------------------------------------------------------------------
; 从EM78 发送数据到串行EEPROM, 一位一位子程序
; Input : None
; Output : To (DI) of serial EEPROM device
;-----------------------------------------------------------------------------
BITIN
MOV A,@B'10111111' ; Force SDA line as input
IOW P6
BS P6,SDA ; Set SDA for input
BC EEPROM,DI
BS P6,SCL ; Clock high
MOV A,@1
JBS P6,SCL ; Skip if SCL is high
JMP BIT1
JBS FLAG,ERROR ; Remain as first error encountered
MOV ERCODE,A ; Save error code
BS FLAG,ERROR ; Set error flag
BIT1
JBC P6,SDA ; Read SDA pin
BS EEPROM,DI ; DI = 1
NOP ; Delay
BC P6,SCL ; Return SCL to low
RET
;-----------------------------------------------------------------------------
; 从串行EEPROM 接收数据, 一位一位子程序
; Input : EEPROM file
; Output : From (DO) of serial EEPROM device to PIC
;-----------------------------------------------------------------------------
BITOUT
MOV A,@B'00111111' ; Set SDA, SCL as outputs
IOW P6
JBS EEPROM,DO
JMP BIT0
BS P6,SDA ; Output bit 0
MOV A,@2
JBC P6,SDA ; Check for error code 2
JMP CLK1
JBS FLAG,ERROR ; Remain as first error encountered
MOV ERCODE,A ; Save error code
BS FLAG,ERROR ; Set error flag
JMP CLK1 ; SDA locked low by device
BIT0
BC P6,SDA ; Output bit 0
NOP ; Delay
NOP
NOP
CLK1: BS P6,SCL
MOV A,@1 ; Error code 1
JBC P6,SCL ; SCL locked low?
JMP BIT2 ; No.
JBS FLAG,ERROR ; Yes.
MOV ERCODE,A ; Save error code
BS FLAG,ERROR ; Set error flag
BIT2: NOP
NOP
BC P6,SCL ; Return SCL to low
RET
;-----------------------------------------------------------------------------
; 接收数据子程序
; Input : None
; Output : RXBUF = Receive 8-bit data
;-----------------------------------------------------------------------------
RX
MOV A,@8 ; 8 bits of data
MOV COUNT,A
CLR RXBUF
RXLP
RLC RXBUF ; Shift data to buffer
JBS R3,0 ;SKPC
BC RXBUF,0 ; carry ---> f(0)
JBC R3,0 ;SKPNC
BS RXBUF,0
CALL BITIN
JBC EEPROM,DI
BS RXBUF,0 ; Input bit =1
DJZ COUNT ; 8 bits?
JMP RXLP
BS EEPROM,DO ; Set acknowledge bit = 1
CALL BITOUT ; to STOP further input
RET
;-----------------------------------------------------------------------------
; 发送数据子程序
; Input : TXBUF
; Output : Data X'mitted to EEPROM device
;-----------------------------------------------------------------------------
TX MOV A,@8
MOV COUNT,A
TXLP BC EEPROM,DO ; Shift data bit out.
JBC TXBUF,7 ; If shifted bit = 0, data bit = 0
BS EEPROM,DO ; Otherwise data bit = 1
CALL BITOUT ; Serial data out
RLC TXBUF ; Rotate TXBUF left
JBS R3,0 ; f(6) ---> f(7)
BC TXBUF,0 ; f(7) ---> carry
JBC R3,0 ; carry ---> f(0)
BS TXBUF,0
DJZ COUNT ; 8 bits done?
JMP TXLP ; No.
CALL BITIN ; Read acknowledge bit
MOV A,@3
JBC EEPROM,DI ; Check for acknowledgement
CALL ERR ; No acknowledge from device
RET
;-----------------------------------------------------------------------------
; 字节写,写一个字节到EEPROM器件
; Input : DATAO= data to be written
; ADDR = destination address
; SLAVE = device address (1010xxx0)
; Output : Data written to EEPROM device
;-----------------------------------------------------------------------------
WRBYTE
MOVF A,SLAVE ; Get SLAVE address
MOV TXBUF,A ; to TX buffer
CALL BSTART ; Generate START bit
CALL TX ; Output SLAVE address
MOV A,ADDR ; Get WORD address
MOV TXBUF,A ; into buffer
CALL TX ; Output WORD address
MOV A,DATAO ; Move DATA
MOV TXBUF,A ; into buffer
CALL TX ; Output DATA and detect acknowledgement
CALL BSTOP ; Generate STOP bit
JMP wrt_end
;-----------------------------------------------------------------------------
; 字节读,从EEPROM器件读一个字节
; Input : ADDR = source address
; SLAVE = device address (1010xxx0)
; Output : DATAI = data read from serial EEPROM
;-----------------------------------------------------------------------------
RDBYTE
MOV A,SLAVE ; Move SLAVE address
MOV TXBUF,A ; into buffer (R/W = 0)
CALL BSTART ; Generate START bit
CALL TX ; Output SLAVE address. Check ACK.
MOV A,ADDR ; Get WORD address
MOV TXBUF,A
CALL TX ; Output WORD address. Check ACK.
CALL BSTART ; START READ (if only one device is
MOVF A,SLAVE ; connected to the I2C bus)
MOV TXBUF,A
BS TXBUF,0 ; Specify READ mode (R/W = 1)
CALL TX ; Output SLAVE address
CALL RX ; READ in data and acknowledge
CALL BSTOP ; Generate STOP bit
MOV A,RXBUF ; Save data from buffer
MOV DATAI,A ; to DATAI file.
JMP rd_end
;随机读写测试,主程序
start: mov A,@0XAE ;set A2=A1=A0=1
mov SLAVE,A ; /
mov A,@2 ;set r/w loc. = 2
mov ADDR,A ; /
mov A,@55 ;write 55 to SEEPROM
mov DATAO,A ; /
JMP WRBYTE ;write a byte
wrt_end:call delay ;wait for write operation (internal)
JMP RDBYTE ;read back data
rd_end
mov A,@55 ;test if read
xor A,DATAI ;correct?
JBS STAT,Z ;yes then skip
wrong JMP wrong
correct JMP correct
;At 2.0Mhz, delay = approx. 3mS.
Delay: clr 0X1F ;clear last location
dly1: nop
nop
nop
DJZ 0X1F ;reduce count
JMP dly1 ;loop
ret
END