第四章 EM78系列单片机程序设计 ( 2
)
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
在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
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
|