数字钟实验
一 实验目的与要求
进一步熟悉I∧2C总线,掌握时钟芯片的使用;掌握使用液晶显示器显示时间
二 实验内容
⒈PGF8563:
⑴实时时钟芯片,可记时时间1900-2099年,不具有周调整功能。 ⑵数据传输采用I∧2C总线,固定片选地址;闹铃中断功能,可编程频率输出
⒉实验过程
读写PGF8563中的时间程序;在12864J液晶显示器显示时间 星期、日期
三 实验步骤
1、 主机连线说明:
E4区:SDA----A3区:P1.0
E4区:SCL----A3区:P1.1
A1区:CS、RW、RS、CS1/2----A3区:CS1、A0、A1、A2
2、 初始化PCF8563,设置初始化时间(2005-07-01 Fri 12:30:00),读取时间数据;
调整读取的时间数据,转换为可以再图形液晶显示器上显示的数据,显示时间(年、月、日、星期、小时、分、秒
三 实验原理图
四 程序流程图
五 程序清单
PCF8563时钟实验说明
;实验目的: 1.掌握时钟芯片的使用
; 2.掌握使用液晶显示器显示时间
;实验内容: 1.读写PCF8563中的时间数据
; 2.将时间显示在12864J液晶显示器上
;连线说明:
;PCF8563: E4区-->A3区
; SDA-->P1.0,数据线
; SCL-->P1.1,时钟
;液晶12864J: A1区-->A3区
; CS-->CS1(0F000H),片选
; RW-->A0,读/写控制端
; RS-->A1,数据/指令控制端
; CS1/2-->A2,左右半屏使能端
;*******************************************************
SEC EQU 30H ;保存秒数据,用于检测秒变化
TEMP EQU 31H ;时间显示缓冲区
XSET EQU 33H ;时间起始显示行设置
YSET EQU 34H ;时间起始显示列设置
Time11 EQU 35H ;数据缓冲区
WR_COM_AD_L XDATA 0F004H ;写左半屏指令地址
WR_COM_AD_R XDATA 0F000H ;写右半屏指令地址
WR_DATA_AD_L XDATA 0F006H ;写左半屏数据地址
WR_DATA_AD_R XDATA 0F002H ;写右半屏数据地址
RD_BUSY_AD XDATA 0F001H ;查忙地址
RD_DATA_AD XDATA 0F003H ;读数据地址
X EQU 0B8H ;起始显示行基址
Y EQU 040H ;起始显示列基址
FirstLine EQU 0C0H ;起始显示行
SDA BIT P1.0 ;数据传输口
SCL BIT P1.1 ;时钟
INT BIT P3.2 ;闹钟/定时中断输出
;内部寄存器地址
CS1 EQU 00H ;控制/状态寄存器1
CS2 EQU 01H ;控制/状态寄存器2
Second EQU 02H ;秒寄存器
Minute EQU 03H ;分寄存器
Hour EQU 04H ;时寄存器
Day EQU 05H ;天寄存器
Weekday EQU 06H ;周寄存器
Mouth EQU 07H ;月寄存器
Year EQU 08H ;年寄存器
MinuteA EQU 09H ;分闹铃寄存器
HourA EQU 0AH ;时闹铃寄存器
DayA EQU 0BH ;天闹铃寄存器
WeekdayA EQU 0CH ;周闹铃寄存器
CO EQU 0DH ;时钟输出控制寄存器
TimerCtrl EQU 0EH ;定时控制寄存器
Timer EQU 0FH ;定时设置寄存器
;PCF8563的片选地址:001H
PCF8563_WRITE EQU 0A2H ;写指令
PCF8563_READ EQU 0A3H ;读指令
ORG 0
LCALL MainINIT ;主程序初始化
MAIN: LCALL Sec_Change ;检测秒变化,给出判断标志位CY,1-有变化 JNC MAIN
LCALL Time_Read ;读取时间
MOV SEC,TIME11 ;保存秒数据,用于检测秒变化
LCALL Time_Display ;显示时间
JMP MAIN ;循环进行实验内容介绍与PCF8563测试
;主程序初始化
MainINIT: LCALL LCD_INIT ;初始化液晶显示
LCALL PCF8563_INIT ;PCF8563初始化
LCALL BackGround ;显示背景,即显示不会变化的部分
LCALL Time_Read ;读取时间,读取的时间数据存放在TIME中 MOV SEC,TIME11 ;保存秒数据,用于检测秒变化
LCALL Time_Display ;显示时间
CLR F0 ;清秒变化标志
RET
;显示时间背景
BackGround: MOV DPTR,#PIC2 ;显示"2"
MOV A,#2
MOV B,#0
LCALL ByteDisL ;显示1个字节子程序,左单屏
MOV DPTR,#PIC0 ;显示"0"
MOV A,#2
MOV B,#8
LCALL ByteDisL
MOV DPTR,#BG1 ;第1行背景"-"
MOV A,#2 ;起始显示行:第2行
MOV B,#32 ;起始显示列:第16列
LCALL ByteDisL
MOV DPTR,#BG1
MOV A,#2
MOV B,#56
LCALL ByteDisL
MOV DPTR,#BG2 ;第2行背景":"
MOV A,#4
MOV B,#48
LCALL ByteDisL ;显示1个字节子程序,左半屏
MOV DPTR,#BG2
MOV A,#4
MOV B,#8
LCALL ByteDisR ;显示1个字节子程序,右半屏
RET
BG1: ;"-"
DB
000H,000H,000H,000H,000H,000H,000H,000H,001H,001H,001H,001H,001H,001H,001H,001H BG2: ;":"
DB
000H,000H,000H,0C0H,0C0H,000H,000H,000H,000H,000H,000H,030H,030H,000H,000H,000H
;********************************
;时间显示
;********************************
;检测秒变化,给出判断标志F0,1-秒有变化;0-秒无变化
Sec_Change: LCALL Sec_Read ;读取秒
CJNE A,SEC,Sec_Change_1 ;与前一次读取的秒比较,判断秒是否有变化 CLR C
RET
Sec_Change_1: SETB C
RET
;时间显示,时间数据在TIME缓冲区中
Time_Display: MOV A,TIME11 ;显示秒
ANL A,#0F0H
SWAP A
ACALL TEMPChange
MOV A,#4
MOV B,#16
LCALL ByteDisR
MOV A,TIME11
ANL A,#0FH
LCALL TEMPChange
MOV A,#4
MOV B,#24
LCALL ByteDisR
MOV A,TIME11+1
ANL A,#0F0H
SWAP A
LCALL TEMPChange
MOV A,#4
MOV B,#56
LCALL ByteDisL
MOV A,TIME11+1
ANL A,#0FH
LCALL TEMPChange
MOV A,#4
MOV B,#0
LCALL ByteDisR
MOV A,TIME11+2
ANL A,#0F0H
SWAP A
LCALL TEMPChange
MOV A,#4
MOV B,#32
LCALL ByteDisL
MOV A,TIME11+2 起始显示行在第4行(从第0行开始算) 起始显示列在第16列(从第0列开始算) ;显示秒,右半屏 显示分 ;时间数据转换为图形显示数据 起始显示行在第4行(从第0行开始算) 起始显示列在第56列(从第0列开始算) ;显示分,左半屏 显示小时 ;时间数据转换为图形显示数据 起始显示行在第4行(从第0行开始算) 起始显示列在第32列(从第0列开始算) ;显示小时,左半屏 ;; ; ;; ; ;;
ANL A,#0FH
LCALL TEMPChange
MOV A,#4
MOV B,#40
LCALL ByteDisL
;显示日
MOV A,TIME11+3
ANL A,#0F0H
SWAP A
LCALL TEMPChange ;时间数据转换为图形显示数据
MOV A,#2 ;起始显示行在第2行(从第0行开始算)
MOV B,#0 ;起始显示列在第0列(从第0列开始算)
LCALL ByteDisR ;显示日,右半屏
MOV A,TIME11+3
ANL A,#0FH
LCALL TEMPChange
MOV A,#2
MOV B,#8
LCALL ByteDisR
;显示周
MOV A,TIME11+4
LCALL WeekChange ;周数据转换为图形显示数据
MOV A,#2 ;起始显示行在第2行(从第0行开始算)
MOV B,#40 ;起始显示列在第32列(从第0列开始算)
LCALL WeekDisplay ;显示周,右半屏
;显示月
MOV A,TIME11+5
ANL A,#0F0H
SWAP A
LCALL TEMPChange ;时间数据转换为图形显示数据
MOV A,#2 ;起始显示行在第2行(从第0行开始算)
MOV B,#40 ;起始显示列在第40列(从第0列开始算)
LCALL ByteDisL ;显示月,左半屏
MOV A,TIME11+5
ANL A,#0FH
LCALL TEMPChange
MOV A,#2
MOV B,#48
LCALL ByteDisL
;显示年
MOV A,TIME11+6
ANL A,#0F0H
SWAP A
LCALL TEMPChange ;时间数据转换为图形显示数据
MOV A,#2 ;起始显示行在第2行(从第0行开始算)
MOV B,#16 ;起始显示列在第16列(从第0列开始算) LCALL ByteDisL ;显示年,左半屏
MOV A,TIME11+6
ANL A,#0FH
LCALL TEMPChange
MOV A,#2
MOV B,#24
LCALL ByteDisL
RET
;时间数据转换为图形显示数据的起始地址
TEMPChange: RL A
MOV B,A
MOV DPTR,#Time_Tab
MOVC A,@A+DPTR
XCH A,B
INC A
MOVC A,@A+DPTR
MOV DPL,A
MOV DPH,B
RET
Time_Tab: DW PIC0, PIC1, PIC2, PIC3, PIC4, PIC5, PIC6, PIC7, PIC8, PIC9 PIC0:
;-- 文字: 0 --
DB
000H,0E0H,010H,008H,008H,010H,0E0H,000H,000H,00FH,010H,020H,020H,010H,00FH,000H PIC1:
;-- 文字: 1 --
DB
000H,010H,010H,0F8H,000H,000H,000H,000H,000H,020H,020H,03FH,020H,020H,000H,000H PIC2:
;-- 文字: 2 --
DB
000H,070H,008H,008H,008H,088H,070H,000H,000H,030H,028H,024H,022H,021H,030H,000H PIC3:
;-- 文字: 3 --
DB
000H,030H,008H,088H,088H,048H,030H,000H,000H,018H,020H,020H,020H,011H,00EH,000H PIC4:
;-- 文字: 4 --
DB
000H,000H,0C0H,020H,010H,0F8H,000H,000H,000H,007H,004H,024H,024H,03FH,024H,000H
;-- 文字: 5 --
DB
000H,0F8H,008H,088H,088H,008H,008H,000H,000H,019H,021H,020H,020H,011H,00EH,000H PIC6:
;-- 文字: 6 --
DB
000H,0E0H,010H,088H,088H,018H,000H,000H,000H,00FH,011H,020H,020H,011H,00EH,000H PIC7:
;-- 文字: 7 --
DB
000H,038H,008H,008H,0C8H,038H,008H,000H,000H,000H,000H,03FH,000H,000H,000H,000H PIC8:
;-- 文字: 8 --
DB
000H,070H,088H,008H,008H,088H,070H,000H,000H,01CH,022H,021H,021H,022H,01CH,000H PIC9:
;-- 文字: 9 --
DB
000H,0E0H,010H,008H,008H,010H,0E0H,000H,000H,000H,031H,022H,022H,011H,00FH,000H
;周数据转换为图形显示数据的起始地址,存在TEMPDis中
WeekChange: RL A
MOV B,A
MOV DPTR,#Week_Tab
MOVC A,@A+DPTR
XCH A,B
INC A
MOVC A,@A+DPTR
MOV DPL,A
MOV DPH,B
RET
Week_Tab: DW Week0, Week1, Week2, Week3, Week4, Week5, Week6
Week0: ;"Sun"
DB
000H,070H,088H,008H,008H,008H,038H,000H,000H,038H,020H,021H,021H,022H,01CH,000H DB
080H,080H,000H,000H,000H,080H,080H,000H,000H,01FH,020H,020H,020H,010H,03FH,020H DB
080H,080H,000H,080H,080H,080H,000H,000H,020H,03FH,021H,000H,000H,020H,03FH,020H Week1: ;"Mon"
DB
008H,0F8H,0F8H,000H,0F8H,0F8H,008H,000H,020H,03FH,000H,03FH,000H,03FH,020H,000H
000H,000H,080H,080H,080H,080H,000H,000H,000H,01FH,020H,020H,020H,020H,01FH,000H DB
080H,080H,000H,080H,080H,080H,000H,000H,020H,03FH,021H,000H,000H,020H,03FH,020H Week2: ;"Tue"
DB
018H,008H,008H,0F8H,008H,008H,018H,000H,000H,000H,020H,03FH,020H,000H,000H,000H DB
080H,080H,000H,000H,000H,080H,080H,000H,000H,01FH,020H,020H,020H,010H,03FH,020H DB
000H,000H,080H,080H,080H,080H,000H,000H,000H,01FH,022H,022H,022H,022H,013H,000H Week3: ;"Wed"
DB
0F8H,008H,000H,0F8H,000H,008H,0F8H,000H,003H,03CH,007H,000H,007H,03CH,003H,000H DB
000H,000H,080H,080H,080H,080H,000H,000H,000H,01FH,022H,022H,022H,022H,013H,000H DB
000H,000H,000H,080H,080H,088H,0F8H,000H,000H,00EH,011H,020H,020H,010H,03FH,020H Week4: ;"Thu"
DB
018H,008H,008H,0F8H,008H,008H,018H,000H,000H,000H,020H,03FH,020H,000H,000H,000H DB
008H,0F8H,000H,080H,080H,080H,000H,000H,020H,03FH,021H,000H,000H,020H,03FH,020H DB
080H,080H,000H,000H,000H,080H,080H,000H,000H,01FH,020H,020H,020H,010H,03FH,020H Week5: ;"Fri"
DB
008H,0F8H,088H,088H,0E8H,008H,010H,000H,020H,03FH,020H,000H,003H,000H,000H,000H DB
080H,080H,080H,000H,080H,080H,080H,000H,020H,020H,03FH,021H,020H,000H,001H,000H DB
000H,080H,098H,098H,000H,000H,000H,000H,000H,020H,020H,03FH,020H,020H,000H,000H Week6: ;"Sat"
DB
000H,070H,088H,008H,008H,008H,038H,000H,000H,038H,020H,021H,021H,022H,01CH,000H DB
000H,000H,080H,080H,080H,080H,000H,000H,000H,019H,024H,022H,022H,022H,03FH,020H DB
000H,080H,080H,0E0H,080H,080H,000H,000H,000H,000H,000H,01FH,020H,020H,000H,000H
;显示周
WeekDisplay: PUSH ACC ;A,B--X行,Y列序数
PUSH B
LCALL ByteDisR ;右半屏显示一个字节子程序
POP ACC
ADD A,#8
MOV B,A
POP ACC
PUSH ACC
PUSH B
LCALL ByteDisR ;显示第2个字母
POP ACC
ADD A,#8
MOV B,A
POP ACC
LCALL ByteDisR ;显示第3个字母
RET
;液晶初始化
LCD_INIT: MOV A,#3EH ;初始化左半屏,关显示
LCALL WRComL ;写指令子程序
MOV A,#FirstLine ;设置起始显示行,第0行
LCALL WRComL
MOV A,#3EH ;初始化右半屏,关显示
LCALL WRComR ;写指令子程序
MOV A,#FirstLine ;设置起始显示行,第0行
LCALL WRComR
LCALL LCDClear ;清屏
MOV A,#3FH ;开显示
LCALL WRComL
MOV A,#3FH ;开显示
LCALL WRComR
RET
;清屏
LCDClear: ;清左半屏
MOV A,#0 ;起始行,第0行
MOV B,#0 ;起始列,第0列
LCDClearL1: PUSH ACC
MOV R7,#64
LCALL SETXYL ;设置起始显示行列地址
LCDClearL2: CLR A
LCALL WRDATAL
DJNZ R7,LCDClearL2
POP ACC
INC A
CJNE A,#8,LCDClearL1 ;共8行
;清右半屏
MOV A,#0 ;起始行,第0行
MOV B,#0 ;起始列,第0列
LCDClearR1: PUSH ACC
MOV R7,#64
LCALL SETXYR ;设置起始显示行列地址
LCDClearR2: CLR A
LCALL WRDATAR
DJNZ R7,LCDClearR2
POP ACC
INC A
CJNE A,#8,LCDClearR1 ;共8行
RET
;***************************************
;显示字体,显示一个数据要占用X行两行位置
;***************************************
;左半屏显示一个字节/字:A-起始显示行序数X(0-7);B-起始显示列序数Y(0-63);DPTR-显示字数据首地址
ByteDisL: MOV R7,#8 ;显示8个字节数据,用于显示一个英文/符号 JMP DispL
WordDisL: MOV R7,#16 ;显示16字节数据,用于显示一个汉字
DispL: PUSH ACC
PUSH 07H
LCALL SETXYL ;设置起始显示行列地址
LCALL DisplayL ;显示上半行数据
POP 07H ;DPTR指向下半部分字体数据区
POP ACC
INC A
LCALL SETXYL ;设置起始显示行列地址
LCALL DisplayL ;显示下半行数据
RET
;右半屏显示一个字节/字:A-起始显示行序数X(0-7);B-起始显示列序数Y(0-63);DPTR-显示字数据首地址
ByteDisR: MOV R7,#8 ;显示8个字节数据,用于显示一个英文/符号 SJMP DispR
WordDisR: MOV R7,#16 ;显示16字节数据,用于显示一个汉字
DispR: PUSH ACC
PUSH 07H
LCALL SETXYR ;设置起始显示行列地址
LCALL DisplayR ;显示上半行数据
POP 07H ;DPTR指向下半部分字体数据区
POP ACC
INC A
LCALL SETXYR ;设置起始显示行列地址
LCALL DisplayR ;显示下半行数据
RET
;***************************************
;显示图形
;***************************************
;显示左半屏一行图形,A-X起始行序数(0-7),B-Y起始列地址序数(0-63)
LineDisL: MOV R7,#64
LCALL SETXYL ;设置起始显示行列
LCALL DisplayL ;显示数据
RET
;显示右半屏一行图形,A-X起始行地址序数(0-7),B-Y起始列地址序数(0-63)
LineDisR: MOV R7,#64
LCALL SETXYR ;设置起始显示行列
LCALL DisplayR ;显示数据
RET
;***************************************
;基本控制
;***************************************
;显示左半屏数据,R7-显示数据个数
DisplayL: CLR A
MOVC A,@A+DPTR
LCALL WRDataL ;写左半屏数据
INC DPTR
DJNZ R7,DisplayL
RET
;显示右半屏数据,R7-显示数据个数
DisplayR: CLR A
MOVC A,@A+DPTR
LCALL WRDataR ;写左半屏数据
INC DPTR
DJNZ R7,DisplayR
RET
;设置左半屏起始显示行列地址,A-X起始行序数(0-7),B-Y起始列序数(0-63)
SETXYL: ORL A,#X ;行地址=行序数+行基址
LCALL WRComL
MOV A,B
ORL A,#Y ;列地址=列序数+列基址
LCALL WRComL
RET
;设置右半屏起始显示行列地址,A-X起始行序数(0-7),B-Y起始列序数(0-63)
SETXYR: ORL A,#X ;行地址=行序数+行基址
LCALL WRComR
MOV A,B
ORL A,#Y ;列地址=列序数+列基址
LCALL WRComR
RET
;写左半屏控制指令,A-写入指令
WRComL: PUSH DPL
PUSH DPH
MOV DPTR,#WR_COM_AD_L
MOVX @DPTR,A
WRComL1: MOV DPTR,#RD_BUSY_AD
MOVX A,@DPTR
JB ACC.7,WRComL1 ;检查液晶显示是否处于忙状态
POP DPH
POP DPL
RET
;写右半屏控制指令,A-写入指令
WRComR: PUSH DPL
PUSH DPH
MOV DPTR,#WR_COM_AD_R
MOVX @DPTR,A
WRComR1: MOV DPTR,#RD_BUSY_AD
MOVX A,@DPTR
JB ACC.7,WRComR1 ;检查液晶显示是否处于忙状态
POP DPH
POP DPL
RET
;写左半屏数据,A-写入数据
WRDataL: PUSH DPL
PUSH DPH
MOV DPTR,#WR_DATA_AD_L
MOVX @DPTR,A
WRDataL1: MOV DPTR,#RD_BUSY_AD
MOVX A,@DPTR
JB ACC.7,WRDataL1 ;检查液晶显示是否处于忙状态
POP DPH
POP DPL
RET
;写右半屏数据,A-写入数据
WRDataR: PUSH DPL
PUSH DPH
MOV DPTR,#WR_DATA_AD_R
MOVX @DPTR,A
WRDataR1: MOV DPTR,#RD_BUSY_AD
MOVX A,@DPTR
JB ACC.7,WRDataR1 ;检查液晶显示是否处于忙状态
POP DPH
POP DPL
RET
;初始化
PCF8563_INIT: LCALL Delay8ms ;IIC总线从通电到开始操作要求8ms延时 LCALL Register_INIT ;寄存器初始化
LCALL Time_INIT ;时间初始化
INIT_1: RET
;寄存器初始化
Register_INIT: LCALL CS1_Set ;设置控制/状态寄存器1
LCALL CS2_Set ;设置控制/状态寄存器2
LCALL DayA_Set ;设置天闹铃寄存器
LCALL WeekdayA_Set ;设置周闹铃寄存器
LCALL CO_Set ;设置时钟输出寄存器
RET
CS1_Set: MOV A,#CS1 ;A-寄存器地址,B-寄存器设置值
MOV B,#00H ;全设为正常模式
LCALL Write ;数据写入子程序
RET
CS2_Set: MOV A,#CS2
MOV B,#02H ;开闹铃中断,关定时器中断
LCALL Write
RET
DayA_Set: MOV A,#DayA
MOV B,#00H ;关天闹铃
LCALL Write
RET
WeekdayA_Set: MOV A,#WeekdayA
MOV B,#00H ;关周闹铃
LCALL Write
RET
CO_Set: MOV A,#CO
MOV B,#00H ;关时钟输出
LCALL Write
RET
;时间初始化,05年7月1日 12:30:00,压缩BCD码格式(1个字节包含2个BCD码) Time_INIT: MOV A,#Year ;A-寄存器地址;B-设置参数
MOV B,#05H
LCALL Write ;写入一个字节数据子程序
MOV A,#Mouth
MOV B,#07H ;最高位表示世纪:0-20XX,1-19XX
LCALL Write
MOV A,#Weekday ;周是不会自动调整的,需要自已核对
MOV B,#05H
LCALL Write
MOV A,#Day
MOV B,#1H
LCALL Write
MOV A,#Hour
MOV B,#12H
LCALL Write
MOV A,#Minute
MOV B,#30H
LCALL Write
MOV A,#Second
MOV B,#00H
LCALL Write
RET
;读秒,返回A-秒数据
Sec_Read: MOV A,#Second
LCALL Read
ANL A,#7FH
RET
;读取时间,TIME-时间数据缓冲区
Time_Read: MOV A,#Second ;起始读取地址,从秒开始
MOV R7,#7 ;连续读取数据个数:秒,分,时,天,周,月,年 MOV R0,#TIME11 ;时间数据缓冲区
LCALL Read_Sequence ;连续读取子程序
LCALL Time_Adjust
RET
;时间写入,将秒,分,时,日,周,月,年写入;TIME-欲写入时间数据缓冲区 Time_Write: MOV R0,#TIME11 ;时间数据缓冲区首地址
MOV A,#Second ;秒数据地址为起始写入地址
Time_Write_1: PUSH ACC
MOV B,@R0 ;B-时间数据
LCALL Write
POP ACC
INC A
INC R0
CJNE R0,#TIME11+7,Time_Write_1
RET
;闹钟时间读取,只开启了时,分闹铃
Alarm_Read: MOV A,#MinuteA ;起始读取地址,从分钟闹铃开始
MOV R7,#2 ;读取数据个数:分,时
LCALL Read_Sequence ;连续读取子程序
RET
;时间调整,去除不必要的位数据
Time_Adjust: MOV R0,#TIME11
MOV A,@R0
ANL A,#7FH ;调整秒
XCH A,@R0
INC R0
MOV A,@R0
ANL A,#7FH ;调整分钟
XCH A,@R0
INC R0
MOV A,@R0
ANL A,#3FH ;调整小时
XCH A,@R0
INC R0
MOV A,@R0
ANL A,#3FH ;调整日
XCH A,@R0
INC R0
MOV A,@R0
ANL A,#07H ;调整周
XCH A,@R0
INC R0
MOV A,@R0
ANL A,#1FH ;调整月,年不用调整
XCH A,@R0
RET
;停止闹铃
Alarm_Stop: MOV A,#CS2 ;控制/状态2寄存器地址
LCALL Read ;读出当前控制/状态2寄存器值,在A中
ANL A,#0F7H ;清AF闹铃标志,AF在CS2第3位
MOV B,A ;欲写入数据放B中
MOV A,#CS2
LCALL Write
RET
;写入1个字节数据,A-寄存器地址,B-数据
Write: PUSH ACC ;寄存器地址压栈
LCALL Start ;开始信号
MOV A,#PCF8563_WRITE ;写操作指令
LCALL Write_8bits ;写入8位数据
LCALL Acknowledge ;查询接收端应答信号
POP ACC ;写入寄存器地址
LCALL Write_8bits
LCALL Acknowledge
MOV A,B ;写入设置值
LCALL Write_8bits
LCALL Acknowledge
LCALL Stop ;停止信号
RET
;读取数据,分为两种模式:字节读取和连续读取
;字节读取,一次读取一个字节的数据,A-读取地址及存放读出的数据
Read: PUSH ACC ;寄存器地址压栈
LCALL Start ;开始信号
MOV A,#PCF8563_WRITE ;写操作指令
LCALL Write_8bits ;写入8位数据
LCALL Acknowledge ;查询接收端应答信号
POP ACC ;写入寄存器地址
LCALL Write_8bits
LCALL Acknowledge
LCALL Start
MOV A,#PCF8563_Read ;读操作指令
LCALL Write_8bits
LCALL Acknowledge
LCALL Read_8bits ;读取数据
LCALL Stop ;停止信号
RET
;连续读取n个数据,n≤16;A-寄存器首地址,R7-读取数据个数,RO-读取数据存放首地址 Read_Sequence: PUSH ACC ;寄存器地址压栈
LCALL Start ;开始信号
MOV A,#PCF8563_WRITE ;写操作指令
LCALL Write_8bits ;写入8位数据
LCALL Acknowledge ;查询接收端应答信号
POP ACC ;写入寄存器地址
LCALL Write_8bits
LCALL Acknowledge
LCALL Start
MOV A,#PCF8563_Read ;读操作指令
LCALL Write_8bits
LCALL Acknowledge
SJMP Read_Sequence_1
Read_Sequence_2:LCALL MasterACK
Read_Sequence_1:LCALL Read_8bits ;读取数据
MOV @R0,A
INC R0
DJNZ R7,Read_Sequence_2
LCALL Stop
RET
Delay_tHD_DAT MACRO
NOP
ENDM
Delay_tSU_DAT MACRO
NOP
ENDM
Delay_tHIGH MACRO
NOP
NOP
ENDM
Delay_tLOW MACRO
NOP
ENDM
Delay_tHD_STA MACRO
NOP
ENDM
Delay_tSU_STO MACRO
NOP
ENDM
Delay_tBUF MACRO
NOP
NOP
ENDM
;写入8位数据
Write_8bits: PUSH 07H
MOV R7,#8
Write_8bits_1: CLR SCL
Delay_tHD_DAT
RLC A
MOV SDA,C ;在SCL为低时,将数据送上SDA
Delay_tSU_DAT
SETB SCL
Delay_tHIGH
DJNZ R7,Write_8bits_1
CLR SCL
POP 07H
RET
;读取8位数据
Read_8bits: PUSH 07H
MOV R7,#8
Read_8bits_1: CLR SCL
Delay_tLOW
SETB SCL ;SCL高电平时,读取SDA数据
Delay_tHIGH
MOV C,SDA
RLC A
DJNZ R7,Read_8bits_1
CLR SCL
POP 07H
RET
;开始信号
Start: SETB SDA ;I2C总线操作开始信号:SCL为高时,SDA由高-->低 SETB SCL
Delay_tBUF
CLR SDA
Delay_tHD_STA
CLR SCL
RET
;结束信号
Stop: Delay_tHD_DAT
CLR SDA ;I2C总线操作结束信号:SCL为高时,SDA由低-->高 SETB SCL
Delay_tSU_STO
SETB SDA ;操作结束后,确保I2C总线处于释放状态
RET
;从机应答查询
Acknowledge: Delay_tLOW
SETB SDA ;查询接收端应答信号,要先释放总线
SETB SCL
Delay_tHIGH
JB SDA,$ ;接收端应答标志:将SDA置低 CLR SCL RET
;主机应答
MasterACK: Delay_tHD_DAT
CLR SDA ;数据线SDA置0应答 Delay_tSU_DAT SETB SCL Delay_tHIGH CLR SCL
SETB SDA ;置高数据,必须 RET ;延时8ms
Delay8ms: PUSH 07H PUSH 06H MOV R7,#36
Delay8ms_1: MOV R6,#100 DJNZ R6,$
DJNZ R7,Delay8ms_1 POP 06H POP 07H RET
END
六 实验设备
A1区:12864液晶显示模块电路
12864J液晶:CS:片选信号,低电平有效;CS1/2:左右半屏使能选择,H:左半屏,L:右半屏;RS:选择读写的是指令或数据,L:指令,H:为数据。RW:读写控制端,L:写操作,H:读操作。
12864M液晶:JP6的16脚是空脚,JP6的15脚是PSB:PSB接高电平,单片机与液晶使用并行接口连接,连接方法与12864J完全相同;PSB接低电平,单片机与液晶使用串行接口连接,此时,RS、RW、E与单片机的I/O管脚相连(STAR ES59PA才有该功能)。 STAR ES59PA: 如果使用液晶,请使用9个短路块短接JP111;如果不使用液晶,不要短接JP111,液晶的所有信号线不与STAR ES59PA连接。
A3
JP48、JP50:CPU的D0..D7,它只能作地址/数据总线使用,不能做I/O口使用;
JP32、JP94:CPU的P0口; JP51、JP55:CPU的P1口;
JP59、JP95:CPU的P2,它可作I/O、地址线A8..A15使用; JP61、JP64:CPU的P3口,P3.7、P3.6作读、写信号线用; JP31:如果P0作地址/数据总线使用,请不要短接JP31;否则,请短接JP31。
片选区 E4
学习态度上,这次课设是对我的学习态度的一次检验。对于这次单片机综合课程实习,我的第一大心得体会就是作为一名工程技术人员,要求具备的首要素质绝对应该是严谨。我们这次实习所遇到的多半问题多数都是由于我们不够严谨。第三,在做人上,我认识到,无论做什么事情,只要你足够坚强,有足够的毅力与决心,有足够的挑战困难的勇气,就没有什么办不到的。通过这次单片机实习,我不仅加深了对单片机理论的理解,将理论很好地应用到实际当中去,而且我还学会了如何去培养我们的创新精神,从而不断地战胜自己,超越自己。创新可以是在原有的基础上进行改进,使之功能不断完善,成为真己的东西。设计结果能够符合题意,成功完成了此次实习要求,我们不只在乎这一结果,更加在乎的,是这个过程。这个过程中,我们花费了大量的时间和精力,更重要的是,我们在学会创新的基础上,同时还懂得合作精神的重要性,学会了与他人合作。
数字钟实验
一 实验目的与要求
进一步熟悉I∧2C总线,掌握时钟芯片的使用;掌握使用液晶显示器显示时间
二 实验内容
⒈PGF8563:
⑴实时时钟芯片,可记时时间1900-2099年,不具有周调整功能。 ⑵数据传输采用I∧2C总线,固定片选地址;闹铃中断功能,可编程频率输出
⒉实验过程
读写PGF8563中的时间程序;在12864J液晶显示器显示时间 星期、日期
三 实验步骤
1、 主机连线说明:
E4区:SDA----A3区:P1.0
E4区:SCL----A3区:P1.1
A1区:CS、RW、RS、CS1/2----A3区:CS1、A0、A1、A2
2、 初始化PCF8563,设置初始化时间(2005-07-01 Fri 12:30:00),读取时间数据;
调整读取的时间数据,转换为可以再图形液晶显示器上显示的数据,显示时间(年、月、日、星期、小时、分、秒
三 实验原理图
四 程序流程图
五 程序清单
PCF8563时钟实验说明
;实验目的: 1.掌握时钟芯片的使用
; 2.掌握使用液晶显示器显示时间
;实验内容: 1.读写PCF8563中的时间数据
; 2.将时间显示在12864J液晶显示器上
;连线说明:
;PCF8563: E4区-->A3区
; SDA-->P1.0,数据线
; SCL-->P1.1,时钟
;液晶12864J: A1区-->A3区
; CS-->CS1(0F000H),片选
; RW-->A0,读/写控制端
; RS-->A1,数据/指令控制端
; CS1/2-->A2,左右半屏使能端
;*******************************************************
SEC EQU 30H ;保存秒数据,用于检测秒变化
TEMP EQU 31H ;时间显示缓冲区
XSET EQU 33H ;时间起始显示行设置
YSET EQU 34H ;时间起始显示列设置
Time11 EQU 35H ;数据缓冲区
WR_COM_AD_L XDATA 0F004H ;写左半屏指令地址
WR_COM_AD_R XDATA 0F000H ;写右半屏指令地址
WR_DATA_AD_L XDATA 0F006H ;写左半屏数据地址
WR_DATA_AD_R XDATA 0F002H ;写右半屏数据地址
RD_BUSY_AD XDATA 0F001H ;查忙地址
RD_DATA_AD XDATA 0F003H ;读数据地址
X EQU 0B8H ;起始显示行基址
Y EQU 040H ;起始显示列基址
FirstLine EQU 0C0H ;起始显示行
SDA BIT P1.0 ;数据传输口
SCL BIT P1.1 ;时钟
INT BIT P3.2 ;闹钟/定时中断输出
;内部寄存器地址
CS1 EQU 00H ;控制/状态寄存器1
CS2 EQU 01H ;控制/状态寄存器2
Second EQU 02H ;秒寄存器
Minute EQU 03H ;分寄存器
Hour EQU 04H ;时寄存器
Day EQU 05H ;天寄存器
Weekday EQU 06H ;周寄存器
Mouth EQU 07H ;月寄存器
Year EQU 08H ;年寄存器
MinuteA EQU 09H ;分闹铃寄存器
HourA EQU 0AH ;时闹铃寄存器
DayA EQU 0BH ;天闹铃寄存器
WeekdayA EQU 0CH ;周闹铃寄存器
CO EQU 0DH ;时钟输出控制寄存器
TimerCtrl EQU 0EH ;定时控制寄存器
Timer EQU 0FH ;定时设置寄存器
;PCF8563的片选地址:001H
PCF8563_WRITE EQU 0A2H ;写指令
PCF8563_READ EQU 0A3H ;读指令
ORG 0
LCALL MainINIT ;主程序初始化
MAIN: LCALL Sec_Change ;检测秒变化,给出判断标志位CY,1-有变化 JNC MAIN
LCALL Time_Read ;读取时间
MOV SEC,TIME11 ;保存秒数据,用于检测秒变化
LCALL Time_Display ;显示时间
JMP MAIN ;循环进行实验内容介绍与PCF8563测试
;主程序初始化
MainINIT: LCALL LCD_INIT ;初始化液晶显示
LCALL PCF8563_INIT ;PCF8563初始化
LCALL BackGround ;显示背景,即显示不会变化的部分
LCALL Time_Read ;读取时间,读取的时间数据存放在TIME中 MOV SEC,TIME11 ;保存秒数据,用于检测秒变化
LCALL Time_Display ;显示时间
CLR F0 ;清秒变化标志
RET
;显示时间背景
BackGround: MOV DPTR,#PIC2 ;显示"2"
MOV A,#2
MOV B,#0
LCALL ByteDisL ;显示1个字节子程序,左单屏
MOV DPTR,#PIC0 ;显示"0"
MOV A,#2
MOV B,#8
LCALL ByteDisL
MOV DPTR,#BG1 ;第1行背景"-"
MOV A,#2 ;起始显示行:第2行
MOV B,#32 ;起始显示列:第16列
LCALL ByteDisL
MOV DPTR,#BG1
MOV A,#2
MOV B,#56
LCALL ByteDisL
MOV DPTR,#BG2 ;第2行背景":"
MOV A,#4
MOV B,#48
LCALL ByteDisL ;显示1个字节子程序,左半屏
MOV DPTR,#BG2
MOV A,#4
MOV B,#8
LCALL ByteDisR ;显示1个字节子程序,右半屏
RET
BG1: ;"-"
DB
000H,000H,000H,000H,000H,000H,000H,000H,001H,001H,001H,001H,001H,001H,001H,001H BG2: ;":"
DB
000H,000H,000H,0C0H,0C0H,000H,000H,000H,000H,000H,000H,030H,030H,000H,000H,000H
;********************************
;时间显示
;********************************
;检测秒变化,给出判断标志F0,1-秒有变化;0-秒无变化
Sec_Change: LCALL Sec_Read ;读取秒
CJNE A,SEC,Sec_Change_1 ;与前一次读取的秒比较,判断秒是否有变化 CLR C
RET
Sec_Change_1: SETB C
RET
;时间显示,时间数据在TIME缓冲区中
Time_Display: MOV A,TIME11 ;显示秒
ANL A,#0F0H
SWAP A
ACALL TEMPChange
MOV A,#4
MOV B,#16
LCALL ByteDisR
MOV A,TIME11
ANL A,#0FH
LCALL TEMPChange
MOV A,#4
MOV B,#24
LCALL ByteDisR
MOV A,TIME11+1
ANL A,#0F0H
SWAP A
LCALL TEMPChange
MOV A,#4
MOV B,#56
LCALL ByteDisL
MOV A,TIME11+1
ANL A,#0FH
LCALL TEMPChange
MOV A,#4
MOV B,#0
LCALL ByteDisR
MOV A,TIME11+2
ANL A,#0F0H
SWAP A
LCALL TEMPChange
MOV A,#4
MOV B,#32
LCALL ByteDisL
MOV A,TIME11+2 起始显示行在第4行(从第0行开始算) 起始显示列在第16列(从第0列开始算) ;显示秒,右半屏 显示分 ;时间数据转换为图形显示数据 起始显示行在第4行(从第0行开始算) 起始显示列在第56列(从第0列开始算) ;显示分,左半屏 显示小时 ;时间数据转换为图形显示数据 起始显示行在第4行(从第0行开始算) 起始显示列在第32列(从第0列开始算) ;显示小时,左半屏 ;; ; ;; ; ;;
ANL A,#0FH
LCALL TEMPChange
MOV A,#4
MOV B,#40
LCALL ByteDisL
;显示日
MOV A,TIME11+3
ANL A,#0F0H
SWAP A
LCALL TEMPChange ;时间数据转换为图形显示数据
MOV A,#2 ;起始显示行在第2行(从第0行开始算)
MOV B,#0 ;起始显示列在第0列(从第0列开始算)
LCALL ByteDisR ;显示日,右半屏
MOV A,TIME11+3
ANL A,#0FH
LCALL TEMPChange
MOV A,#2
MOV B,#8
LCALL ByteDisR
;显示周
MOV A,TIME11+4
LCALL WeekChange ;周数据转换为图形显示数据
MOV A,#2 ;起始显示行在第2行(从第0行开始算)
MOV B,#40 ;起始显示列在第32列(从第0列开始算)
LCALL WeekDisplay ;显示周,右半屏
;显示月
MOV A,TIME11+5
ANL A,#0F0H
SWAP A
LCALL TEMPChange ;时间数据转换为图形显示数据
MOV A,#2 ;起始显示行在第2行(从第0行开始算)
MOV B,#40 ;起始显示列在第40列(从第0列开始算)
LCALL ByteDisL ;显示月,左半屏
MOV A,TIME11+5
ANL A,#0FH
LCALL TEMPChange
MOV A,#2
MOV B,#48
LCALL ByteDisL
;显示年
MOV A,TIME11+6
ANL A,#0F0H
SWAP A
LCALL TEMPChange ;时间数据转换为图形显示数据
MOV A,#2 ;起始显示行在第2行(从第0行开始算)
MOV B,#16 ;起始显示列在第16列(从第0列开始算) LCALL ByteDisL ;显示年,左半屏
MOV A,TIME11+6
ANL A,#0FH
LCALL TEMPChange
MOV A,#2
MOV B,#24
LCALL ByteDisL
RET
;时间数据转换为图形显示数据的起始地址
TEMPChange: RL A
MOV B,A
MOV DPTR,#Time_Tab
MOVC A,@A+DPTR
XCH A,B
INC A
MOVC A,@A+DPTR
MOV DPL,A
MOV DPH,B
RET
Time_Tab: DW PIC0, PIC1, PIC2, PIC3, PIC4, PIC5, PIC6, PIC7, PIC8, PIC9 PIC0:
;-- 文字: 0 --
DB
000H,0E0H,010H,008H,008H,010H,0E0H,000H,000H,00FH,010H,020H,020H,010H,00FH,000H PIC1:
;-- 文字: 1 --
DB
000H,010H,010H,0F8H,000H,000H,000H,000H,000H,020H,020H,03FH,020H,020H,000H,000H PIC2:
;-- 文字: 2 --
DB
000H,070H,008H,008H,008H,088H,070H,000H,000H,030H,028H,024H,022H,021H,030H,000H PIC3:
;-- 文字: 3 --
DB
000H,030H,008H,088H,088H,048H,030H,000H,000H,018H,020H,020H,020H,011H,00EH,000H PIC4:
;-- 文字: 4 --
DB
000H,000H,0C0H,020H,010H,0F8H,000H,000H,000H,007H,004H,024H,024H,03FH,024H,000H
;-- 文字: 5 --
DB
000H,0F8H,008H,088H,088H,008H,008H,000H,000H,019H,021H,020H,020H,011H,00EH,000H PIC6:
;-- 文字: 6 --
DB
000H,0E0H,010H,088H,088H,018H,000H,000H,000H,00FH,011H,020H,020H,011H,00EH,000H PIC7:
;-- 文字: 7 --
DB
000H,038H,008H,008H,0C8H,038H,008H,000H,000H,000H,000H,03FH,000H,000H,000H,000H PIC8:
;-- 文字: 8 --
DB
000H,070H,088H,008H,008H,088H,070H,000H,000H,01CH,022H,021H,021H,022H,01CH,000H PIC9:
;-- 文字: 9 --
DB
000H,0E0H,010H,008H,008H,010H,0E0H,000H,000H,000H,031H,022H,022H,011H,00FH,000H
;周数据转换为图形显示数据的起始地址,存在TEMPDis中
WeekChange: RL A
MOV B,A
MOV DPTR,#Week_Tab
MOVC A,@A+DPTR
XCH A,B
INC A
MOVC A,@A+DPTR
MOV DPL,A
MOV DPH,B
RET
Week_Tab: DW Week0, Week1, Week2, Week3, Week4, Week5, Week6
Week0: ;"Sun"
DB
000H,070H,088H,008H,008H,008H,038H,000H,000H,038H,020H,021H,021H,022H,01CH,000H DB
080H,080H,000H,000H,000H,080H,080H,000H,000H,01FH,020H,020H,020H,010H,03FH,020H DB
080H,080H,000H,080H,080H,080H,000H,000H,020H,03FH,021H,000H,000H,020H,03FH,020H Week1: ;"Mon"
DB
008H,0F8H,0F8H,000H,0F8H,0F8H,008H,000H,020H,03FH,000H,03FH,000H,03FH,020H,000H
000H,000H,080H,080H,080H,080H,000H,000H,000H,01FH,020H,020H,020H,020H,01FH,000H DB
080H,080H,000H,080H,080H,080H,000H,000H,020H,03FH,021H,000H,000H,020H,03FH,020H Week2: ;"Tue"
DB
018H,008H,008H,0F8H,008H,008H,018H,000H,000H,000H,020H,03FH,020H,000H,000H,000H DB
080H,080H,000H,000H,000H,080H,080H,000H,000H,01FH,020H,020H,020H,010H,03FH,020H DB
000H,000H,080H,080H,080H,080H,000H,000H,000H,01FH,022H,022H,022H,022H,013H,000H Week3: ;"Wed"
DB
0F8H,008H,000H,0F8H,000H,008H,0F8H,000H,003H,03CH,007H,000H,007H,03CH,003H,000H DB
000H,000H,080H,080H,080H,080H,000H,000H,000H,01FH,022H,022H,022H,022H,013H,000H DB
000H,000H,000H,080H,080H,088H,0F8H,000H,000H,00EH,011H,020H,020H,010H,03FH,020H Week4: ;"Thu"
DB
018H,008H,008H,0F8H,008H,008H,018H,000H,000H,000H,020H,03FH,020H,000H,000H,000H DB
008H,0F8H,000H,080H,080H,080H,000H,000H,020H,03FH,021H,000H,000H,020H,03FH,020H DB
080H,080H,000H,000H,000H,080H,080H,000H,000H,01FH,020H,020H,020H,010H,03FH,020H Week5: ;"Fri"
DB
008H,0F8H,088H,088H,0E8H,008H,010H,000H,020H,03FH,020H,000H,003H,000H,000H,000H DB
080H,080H,080H,000H,080H,080H,080H,000H,020H,020H,03FH,021H,020H,000H,001H,000H DB
000H,080H,098H,098H,000H,000H,000H,000H,000H,020H,020H,03FH,020H,020H,000H,000H Week6: ;"Sat"
DB
000H,070H,088H,008H,008H,008H,038H,000H,000H,038H,020H,021H,021H,022H,01CH,000H DB
000H,000H,080H,080H,080H,080H,000H,000H,000H,019H,024H,022H,022H,022H,03FH,020H DB
000H,080H,080H,0E0H,080H,080H,000H,000H,000H,000H,000H,01FH,020H,020H,000H,000H
;显示周
WeekDisplay: PUSH ACC ;A,B--X行,Y列序数
PUSH B
LCALL ByteDisR ;右半屏显示一个字节子程序
POP ACC
ADD A,#8
MOV B,A
POP ACC
PUSH ACC
PUSH B
LCALL ByteDisR ;显示第2个字母
POP ACC
ADD A,#8
MOV B,A
POP ACC
LCALL ByteDisR ;显示第3个字母
RET
;液晶初始化
LCD_INIT: MOV A,#3EH ;初始化左半屏,关显示
LCALL WRComL ;写指令子程序
MOV A,#FirstLine ;设置起始显示行,第0行
LCALL WRComL
MOV A,#3EH ;初始化右半屏,关显示
LCALL WRComR ;写指令子程序
MOV A,#FirstLine ;设置起始显示行,第0行
LCALL WRComR
LCALL LCDClear ;清屏
MOV A,#3FH ;开显示
LCALL WRComL
MOV A,#3FH ;开显示
LCALL WRComR
RET
;清屏
LCDClear: ;清左半屏
MOV A,#0 ;起始行,第0行
MOV B,#0 ;起始列,第0列
LCDClearL1: PUSH ACC
MOV R7,#64
LCALL SETXYL ;设置起始显示行列地址
LCDClearL2: CLR A
LCALL WRDATAL
DJNZ R7,LCDClearL2
POP ACC
INC A
CJNE A,#8,LCDClearL1 ;共8行
;清右半屏
MOV A,#0 ;起始行,第0行
MOV B,#0 ;起始列,第0列
LCDClearR1: PUSH ACC
MOV R7,#64
LCALL SETXYR ;设置起始显示行列地址
LCDClearR2: CLR A
LCALL WRDATAR
DJNZ R7,LCDClearR2
POP ACC
INC A
CJNE A,#8,LCDClearR1 ;共8行
RET
;***************************************
;显示字体,显示一个数据要占用X行两行位置
;***************************************
;左半屏显示一个字节/字:A-起始显示行序数X(0-7);B-起始显示列序数Y(0-63);DPTR-显示字数据首地址
ByteDisL: MOV R7,#8 ;显示8个字节数据,用于显示一个英文/符号 JMP DispL
WordDisL: MOV R7,#16 ;显示16字节数据,用于显示一个汉字
DispL: PUSH ACC
PUSH 07H
LCALL SETXYL ;设置起始显示行列地址
LCALL DisplayL ;显示上半行数据
POP 07H ;DPTR指向下半部分字体数据区
POP ACC
INC A
LCALL SETXYL ;设置起始显示行列地址
LCALL DisplayL ;显示下半行数据
RET
;右半屏显示一个字节/字:A-起始显示行序数X(0-7);B-起始显示列序数Y(0-63);DPTR-显示字数据首地址
ByteDisR: MOV R7,#8 ;显示8个字节数据,用于显示一个英文/符号 SJMP DispR
WordDisR: MOV R7,#16 ;显示16字节数据,用于显示一个汉字
DispR: PUSH ACC
PUSH 07H
LCALL SETXYR ;设置起始显示行列地址
LCALL DisplayR ;显示上半行数据
POP 07H ;DPTR指向下半部分字体数据区
POP ACC
INC A
LCALL SETXYR ;设置起始显示行列地址
LCALL DisplayR ;显示下半行数据
RET
;***************************************
;显示图形
;***************************************
;显示左半屏一行图形,A-X起始行序数(0-7),B-Y起始列地址序数(0-63)
LineDisL: MOV R7,#64
LCALL SETXYL ;设置起始显示行列
LCALL DisplayL ;显示数据
RET
;显示右半屏一行图形,A-X起始行地址序数(0-7),B-Y起始列地址序数(0-63)
LineDisR: MOV R7,#64
LCALL SETXYR ;设置起始显示行列
LCALL DisplayR ;显示数据
RET
;***************************************
;基本控制
;***************************************
;显示左半屏数据,R7-显示数据个数
DisplayL: CLR A
MOVC A,@A+DPTR
LCALL WRDataL ;写左半屏数据
INC DPTR
DJNZ R7,DisplayL
RET
;显示右半屏数据,R7-显示数据个数
DisplayR: CLR A
MOVC A,@A+DPTR
LCALL WRDataR ;写左半屏数据
INC DPTR
DJNZ R7,DisplayR
RET
;设置左半屏起始显示行列地址,A-X起始行序数(0-7),B-Y起始列序数(0-63)
SETXYL: ORL A,#X ;行地址=行序数+行基址
LCALL WRComL
MOV A,B
ORL A,#Y ;列地址=列序数+列基址
LCALL WRComL
RET
;设置右半屏起始显示行列地址,A-X起始行序数(0-7),B-Y起始列序数(0-63)
SETXYR: ORL A,#X ;行地址=行序数+行基址
LCALL WRComR
MOV A,B
ORL A,#Y ;列地址=列序数+列基址
LCALL WRComR
RET
;写左半屏控制指令,A-写入指令
WRComL: PUSH DPL
PUSH DPH
MOV DPTR,#WR_COM_AD_L
MOVX @DPTR,A
WRComL1: MOV DPTR,#RD_BUSY_AD
MOVX A,@DPTR
JB ACC.7,WRComL1 ;检查液晶显示是否处于忙状态
POP DPH
POP DPL
RET
;写右半屏控制指令,A-写入指令
WRComR: PUSH DPL
PUSH DPH
MOV DPTR,#WR_COM_AD_R
MOVX @DPTR,A
WRComR1: MOV DPTR,#RD_BUSY_AD
MOVX A,@DPTR
JB ACC.7,WRComR1 ;检查液晶显示是否处于忙状态
POP DPH
POP DPL
RET
;写左半屏数据,A-写入数据
WRDataL: PUSH DPL
PUSH DPH
MOV DPTR,#WR_DATA_AD_L
MOVX @DPTR,A
WRDataL1: MOV DPTR,#RD_BUSY_AD
MOVX A,@DPTR
JB ACC.7,WRDataL1 ;检查液晶显示是否处于忙状态
POP DPH
POP DPL
RET
;写右半屏数据,A-写入数据
WRDataR: PUSH DPL
PUSH DPH
MOV DPTR,#WR_DATA_AD_R
MOVX @DPTR,A
WRDataR1: MOV DPTR,#RD_BUSY_AD
MOVX A,@DPTR
JB ACC.7,WRDataR1 ;检查液晶显示是否处于忙状态
POP DPH
POP DPL
RET
;初始化
PCF8563_INIT: LCALL Delay8ms ;IIC总线从通电到开始操作要求8ms延时 LCALL Register_INIT ;寄存器初始化
LCALL Time_INIT ;时间初始化
INIT_1: RET
;寄存器初始化
Register_INIT: LCALL CS1_Set ;设置控制/状态寄存器1
LCALL CS2_Set ;设置控制/状态寄存器2
LCALL DayA_Set ;设置天闹铃寄存器
LCALL WeekdayA_Set ;设置周闹铃寄存器
LCALL CO_Set ;设置时钟输出寄存器
RET
CS1_Set: MOV A,#CS1 ;A-寄存器地址,B-寄存器设置值
MOV B,#00H ;全设为正常模式
LCALL Write ;数据写入子程序
RET
CS2_Set: MOV A,#CS2
MOV B,#02H ;开闹铃中断,关定时器中断
LCALL Write
RET
DayA_Set: MOV A,#DayA
MOV B,#00H ;关天闹铃
LCALL Write
RET
WeekdayA_Set: MOV A,#WeekdayA
MOV B,#00H ;关周闹铃
LCALL Write
RET
CO_Set: MOV A,#CO
MOV B,#00H ;关时钟输出
LCALL Write
RET
;时间初始化,05年7月1日 12:30:00,压缩BCD码格式(1个字节包含2个BCD码) Time_INIT: MOV A,#Year ;A-寄存器地址;B-设置参数
MOV B,#05H
LCALL Write ;写入一个字节数据子程序
MOV A,#Mouth
MOV B,#07H ;最高位表示世纪:0-20XX,1-19XX
LCALL Write
MOV A,#Weekday ;周是不会自动调整的,需要自已核对
MOV B,#05H
LCALL Write
MOV A,#Day
MOV B,#1H
LCALL Write
MOV A,#Hour
MOV B,#12H
LCALL Write
MOV A,#Minute
MOV B,#30H
LCALL Write
MOV A,#Second
MOV B,#00H
LCALL Write
RET
;读秒,返回A-秒数据
Sec_Read: MOV A,#Second
LCALL Read
ANL A,#7FH
RET
;读取时间,TIME-时间数据缓冲区
Time_Read: MOV A,#Second ;起始读取地址,从秒开始
MOV R7,#7 ;连续读取数据个数:秒,分,时,天,周,月,年 MOV R0,#TIME11 ;时间数据缓冲区
LCALL Read_Sequence ;连续读取子程序
LCALL Time_Adjust
RET
;时间写入,将秒,分,时,日,周,月,年写入;TIME-欲写入时间数据缓冲区 Time_Write: MOV R0,#TIME11 ;时间数据缓冲区首地址
MOV A,#Second ;秒数据地址为起始写入地址
Time_Write_1: PUSH ACC
MOV B,@R0 ;B-时间数据
LCALL Write
POP ACC
INC A
INC R0
CJNE R0,#TIME11+7,Time_Write_1
RET
;闹钟时间读取,只开启了时,分闹铃
Alarm_Read: MOV A,#MinuteA ;起始读取地址,从分钟闹铃开始
MOV R7,#2 ;读取数据个数:分,时
LCALL Read_Sequence ;连续读取子程序
RET
;时间调整,去除不必要的位数据
Time_Adjust: MOV R0,#TIME11
MOV A,@R0
ANL A,#7FH ;调整秒
XCH A,@R0
INC R0
MOV A,@R0
ANL A,#7FH ;调整分钟
XCH A,@R0
INC R0
MOV A,@R0
ANL A,#3FH ;调整小时
XCH A,@R0
INC R0
MOV A,@R0
ANL A,#3FH ;调整日
XCH A,@R0
INC R0
MOV A,@R0
ANL A,#07H ;调整周
XCH A,@R0
INC R0
MOV A,@R0
ANL A,#1FH ;调整月,年不用调整
XCH A,@R0
RET
;停止闹铃
Alarm_Stop: MOV A,#CS2 ;控制/状态2寄存器地址
LCALL Read ;读出当前控制/状态2寄存器值,在A中
ANL A,#0F7H ;清AF闹铃标志,AF在CS2第3位
MOV B,A ;欲写入数据放B中
MOV A,#CS2
LCALL Write
RET
;写入1个字节数据,A-寄存器地址,B-数据
Write: PUSH ACC ;寄存器地址压栈
LCALL Start ;开始信号
MOV A,#PCF8563_WRITE ;写操作指令
LCALL Write_8bits ;写入8位数据
LCALL Acknowledge ;查询接收端应答信号
POP ACC ;写入寄存器地址
LCALL Write_8bits
LCALL Acknowledge
MOV A,B ;写入设置值
LCALL Write_8bits
LCALL Acknowledge
LCALL Stop ;停止信号
RET
;读取数据,分为两种模式:字节读取和连续读取
;字节读取,一次读取一个字节的数据,A-读取地址及存放读出的数据
Read: PUSH ACC ;寄存器地址压栈
LCALL Start ;开始信号
MOV A,#PCF8563_WRITE ;写操作指令
LCALL Write_8bits ;写入8位数据
LCALL Acknowledge ;查询接收端应答信号
POP ACC ;写入寄存器地址
LCALL Write_8bits
LCALL Acknowledge
LCALL Start
MOV A,#PCF8563_Read ;读操作指令
LCALL Write_8bits
LCALL Acknowledge
LCALL Read_8bits ;读取数据
LCALL Stop ;停止信号
RET
;连续读取n个数据,n≤16;A-寄存器首地址,R7-读取数据个数,RO-读取数据存放首地址 Read_Sequence: PUSH ACC ;寄存器地址压栈
LCALL Start ;开始信号
MOV A,#PCF8563_WRITE ;写操作指令
LCALL Write_8bits ;写入8位数据
LCALL Acknowledge ;查询接收端应答信号
POP ACC ;写入寄存器地址
LCALL Write_8bits
LCALL Acknowledge
LCALL Start
MOV A,#PCF8563_Read ;读操作指令
LCALL Write_8bits
LCALL Acknowledge
SJMP Read_Sequence_1
Read_Sequence_2:LCALL MasterACK
Read_Sequence_1:LCALL Read_8bits ;读取数据
MOV @R0,A
INC R0
DJNZ R7,Read_Sequence_2
LCALL Stop
RET
Delay_tHD_DAT MACRO
NOP
ENDM
Delay_tSU_DAT MACRO
NOP
ENDM
Delay_tHIGH MACRO
NOP
NOP
ENDM
Delay_tLOW MACRO
NOP
ENDM
Delay_tHD_STA MACRO
NOP
ENDM
Delay_tSU_STO MACRO
NOP
ENDM
Delay_tBUF MACRO
NOP
NOP
ENDM
;写入8位数据
Write_8bits: PUSH 07H
MOV R7,#8
Write_8bits_1: CLR SCL
Delay_tHD_DAT
RLC A
MOV SDA,C ;在SCL为低时,将数据送上SDA
Delay_tSU_DAT
SETB SCL
Delay_tHIGH
DJNZ R7,Write_8bits_1
CLR SCL
POP 07H
RET
;读取8位数据
Read_8bits: PUSH 07H
MOV R7,#8
Read_8bits_1: CLR SCL
Delay_tLOW
SETB SCL ;SCL高电平时,读取SDA数据
Delay_tHIGH
MOV C,SDA
RLC A
DJNZ R7,Read_8bits_1
CLR SCL
POP 07H
RET
;开始信号
Start: SETB SDA ;I2C总线操作开始信号:SCL为高时,SDA由高-->低 SETB SCL
Delay_tBUF
CLR SDA
Delay_tHD_STA
CLR SCL
RET
;结束信号
Stop: Delay_tHD_DAT
CLR SDA ;I2C总线操作结束信号:SCL为高时,SDA由低-->高 SETB SCL
Delay_tSU_STO
SETB SDA ;操作结束后,确保I2C总线处于释放状态
RET
;从机应答查询
Acknowledge: Delay_tLOW
SETB SDA ;查询接收端应答信号,要先释放总线
SETB SCL
Delay_tHIGH
JB SDA,$ ;接收端应答标志:将SDA置低 CLR SCL RET
;主机应答
MasterACK: Delay_tHD_DAT
CLR SDA ;数据线SDA置0应答 Delay_tSU_DAT SETB SCL Delay_tHIGH CLR SCL
SETB SDA ;置高数据,必须 RET ;延时8ms
Delay8ms: PUSH 07H PUSH 06H MOV R7,#36
Delay8ms_1: MOV R6,#100 DJNZ R6,$
DJNZ R7,Delay8ms_1 POP 06H POP 07H RET
END
六 实验设备
A1区:12864液晶显示模块电路
12864J液晶:CS:片选信号,低电平有效;CS1/2:左右半屏使能选择,H:左半屏,L:右半屏;RS:选择读写的是指令或数据,L:指令,H:为数据。RW:读写控制端,L:写操作,H:读操作。
12864M液晶:JP6的16脚是空脚,JP6的15脚是PSB:PSB接高电平,单片机与液晶使用并行接口连接,连接方法与12864J完全相同;PSB接低电平,单片机与液晶使用串行接口连接,此时,RS、RW、E与单片机的I/O管脚相连(STAR ES59PA才有该功能)。 STAR ES59PA: 如果使用液晶,请使用9个短路块短接JP111;如果不使用液晶,不要短接JP111,液晶的所有信号线不与STAR ES59PA连接。
A3
JP48、JP50:CPU的D0..D7,它只能作地址/数据总线使用,不能做I/O口使用;
JP32、JP94:CPU的P0口; JP51、JP55:CPU的P1口;
JP59、JP95:CPU的P2,它可作I/O、地址线A8..A15使用; JP61、JP64:CPU的P3口,P3.7、P3.6作读、写信号线用; JP31:如果P0作地址/数据总线使用,请不要短接JP31;否则,请短接JP31。
片选区 E4
学习态度上,这次课设是对我的学习态度的一次检验。对于这次单片机综合课程实习,我的第一大心得体会就是作为一名工程技术人员,要求具备的首要素质绝对应该是严谨。我们这次实习所遇到的多半问题多数都是由于我们不够严谨。第三,在做人上,我认识到,无论做什么事情,只要你足够坚强,有足够的毅力与决心,有足够的挑战困难的勇气,就没有什么办不到的。通过这次单片机实习,我不仅加深了对单片机理论的理解,将理论很好地应用到实际当中去,而且我还学会了如何去培养我们的创新精神,从而不断地战胜自己,超越自己。创新可以是在原有的基础上进行改进,使之功能不断完善,成为真己的东西。设计结果能够符合题意,成功完成了此次实习要求,我们不只在乎这一结果,更加在乎的,是这个过程。这个过程中,我们花费了大量的时间和精力,更重要的是,我们在学会创新的基础上,同时还懂得合作精神的重要性,学会了与他人合作。