📄 ds1302.asm
字号:
;实验目的:熟悉时钟芯片DS1302的使用
;先设置时间和日期为:秒(08),分(58),时(05),日(13),月(01),年(55)
;六位数码观显示时间和日期,默认显示的是时间,通过小数点区分时与分、分与秒
;按下RB1键不放,显示切换到日期显示。
;硬件要求:拨码开关S9全部置ON
; 拨码开关S5、S6全部置ON
; 拨码开关S1第7位置ON,其他位置OFF
; 其他拨码开关置OFF
#INCLUDE<p16f877a.inc> ;包含头文件
__CONFIG _DEBUG_OFF&_CP_ALL&_WRT_HALF&_CPD_ON&_LVP_OFF&_BODEN_OFF&_PWRTE_ON&_WDT_OFF&_HS_OSC
;**********************引脚定义****************************
#DEFINE I_O PORTB,4 ;1302I_O
#DEFINE SCLK PORTB,0 ;1302时钟
#DEFINE RST PORTB,5 ;1302使能位
;*********************寄存器定义***************************
TIME_TX_ADD EQU 20H ;连续发送8个数据起始地址
TIME_RX_ADD EQU 20H ;连续接收7个数据起始地址
ERRORLEVEL -302
CBLOCK 20H
SEC ;秒
MIN ;分
HOU ;小时
DATE ;日期
MON ;月
DAY ;日
YERR ;年
TIME_TX ;1302发送寄存器
TIME_RX ;1302接收寄存器
COUNT1 ;循环次数计数器
COUNT2 ;
ENDC
;*******************宏定义*********************************
BANK1 MACRO ;体1
BSF STATUS,RP0
ENDM
BANK0 MACRO ;体0
BCF STATUS,RP0
ENDM
ORG 000H ;复位入口地址
NOP ;ICD所需要的空指令
GOTO MAIN ;跳转到主程序
;********************查表程序*****************************
TABLE
ADDWF PCL,1
RETLW 0C0H ;0的编码(公阳极数码管)
RETLW 0F9H ;1的编码
RETLW 0A4H ;2的编码
RETLW 0B0H ;3的编码
RETLW 99H ;4的编码
RETLW 92H ;5的编码
RETLW 082H ;6
RETLW 0F8H ;7
RETLW 080H ;8
RETLW 090H ;9
;**********************主程序*****************************
MAIN
CALL PORT_INI ;端口定义
CALL DS1302_INI ;1302初始化程序
CALL SET_TIME ;一次写入7个时间数据
CALL GET_TIME ;一次读回7个时间数据
CALL DISPLAY ;调用显示程序
GOTO $-2 ;循环读取时间
;**********************DS1302初始化程序******************
; DS1302_INI
; 作用:初始化1302,写使能寄存器
;********************************************************
;入口参数:无
;出口参数:TIME_TX
DS1302_INI
BCF SCLK
BCF RST ;先禁止
MOVLW B'10001110' ;写使能寄存器
MOVWF TIME_TX
BSF RST ;允许1302工作
CALL TIME_WRITE_1 ;调用写一个数据程序
MOVLW 0H ;允许写使能
MOVWF TIME_TX
CALL TIME_WRITE_1 ;发送一个字节的数据
BCF RST
RETURN
;***********************写时间程序*************************
; SET_TIME
; 作用:一次输入7个数据来一次性的设定时间,同时使能写寄存器
; 突发模式写入,必须写入8个数据,不是7个
; INPUT:要设定的8个数据已经写入到TIME_TX_ADD开始的8个字节里面
;********************************************************
;入口参数:20H--27H的8个RAM单元
SET_TIME
MOVLW B'10111110' ;多字节写方式
MOVWF TIME_TX
BSF RST
CALL TIME_WRITE_1
MOVLW TIME_TX_ADD ;发送数据的起始地址
MOVWF FSR
MOVLW D'8' ;一起发送8个数据
MOVWF COUNT2
TW1
MOVF INDF,W
MOVWF TIME_TX
CALL TIME_WRITE_1
INCF FSR,F
DECFSZ COUNT2,F
GOTO TW1
BCF RST
RETURN
;**********************读时间程序*************************
; GET_TIME
; 作用:一次接受7个字节的时间数据,突发模式读取
; INPUT:NONE
; OUTPUT:把7个时间数据保存在TIME_RX_ADD开始的7个寄存器里面
;*********************************************************
;入口参数:无
;出口参数:20H--26H的7个RAM单元
GET_TIME
MOVLW B'10111111' ;多字接读取方式
MOVWF TIME_TX
BSF RST
CALL TIME_WRITE_1
MOVLW TIME_RX_ADD ;保存数据的起始地址
MOVWF FSR
MOVLW D'7' ;连续读取7个数据
MOVWF COUNT2
TR2
CALL TIME_READ_1
MOVF TIME_RX,W
MOVWF INDF
INCF FSR,F
DECFSZ COUNT2,F
GOTO TR2
BCF RST
RETURN
;**********************写一个字节程序*****************
; TIME_WRITE_1
; 作用:一次发送一个字节的数据,用于发送1302的
; 控制字或者发送一个数据
;************************************************
;入口参数:TIME_TX
;出口参数:无
TIME_WRITE_1
MOVLW D'8' ;8位
MOVWF COUNT1
TLOP
BCF I_O ;初始值是低电平
BCF SCLK
BTFSC TIME_TX,0
BSF I_O
RRF TIME_TX,F
BSF SCLK ;上升沿发送数据
DECFSZ COUNT1,F
GOTO TLOP
BCF SCLK ;恢复
RETURN
;******************读取一字节程序*********************
; TIME_READ_1
; 作用:读取1302一个字节的数据
; 原理:在SCLK下降沿接收数据,低字节在前,根据I_O的
; 的电平的高低,采取带进位和不带进位右移.
;***********************************************
;入口参数:无
;出口参数:TIME_RX
TIME_READ_1
BANK1
BSF TRISB,4 ; I_O 设置为输入
BANK0
MOVLW D'8'
MOVWF COUNT1 ;读取8位
TR1
BCF SCLK ;下降沿读取
BCF STATUS,C
BTFSC I_O
BSF STATUS,C
RRF TIME_RX,F
BSF SCLK ;恢复高电平
DECFSZ COUNT1,F
GOTO TR1
BANK1
BCF TRISB,4 ;I_O恢复为输出
BANK0
BCF SCLK
RETURN
NOP
;******************端口/寄存器设置********************
PORT_INI
BANK1
MOVLW B'00000000'
MOVWF TRISA ;A口输出
MOVWF TRISD ;D口输出
MOVLW 06H
MOVWF ADCON1 ;A口配置为普通数字I/O
MOVLW B'00000010'
MOVWF TRISB ;RB1口为输入,其他口为输出
CLRF OPTION_REG ;开启B口的弱上拉
BANK0
MOVLW 0FFH
MOVWF PORTA
MOVWF PORTD ;熄灭所有显示
MOVLW 08H
MOVWF 20H ;秒,允许晶振起振
MOVLW 58H ;分
MOVWF 21H
MOVLW 05H ;时
MOVWF 22H
MOVLW 13H ;日
MOVWF 23H
MOVLW 10H ;月
MOVWF 24H
MOVLW 06H ;星期
MOVWF 25H
MOVLW 55H ;年
MOVWF 26H
RETURN
;******************************显示程序*************************
DISPLAY
BTFSS PORTB,1 ;是否有按键按下
GOTO DISPLAY_DATE ;按键按下,显示日期,否则显示时间
MOVFW 20H
MOVWF 30H
MOVFW 21H
MOVWF 31H
MOVFW 22H
MOVWF 32H ;将20H--22H的数据复制到30H--32H(秒、分、时)
GOTO DISPLAY1 ;送显示
DISPLAY_DATE ;显示日期
MOVFW 23H
MOVWF 30H
MOVFW 24H
MOVWF 31H
MOVFW 26H
MOVWF 32H ;将23H、24H,26H的数据复制到30H--32H(日、月、年)
DISPLAY1
SWAPF 32H,0 ;显示时/年的高位
ANDLW 0FH
CALL TABLE
MOVWF PORTD
BCF PORTA,0
CALL DELAY
BSF PORTA,0
MOVFW 32H ;显示时/年的低位
ANDLW 0FH
CALL TABLE
MOVWF PORTD
BCF PORTD,7 ;点亮数码管上的小点,做为两位之间的分隔
BCF PORTA,1
CALL DELAY
BSF PORTA,1
SWAPF 31H,0 ;显示分/月的高位
ANDLW 0FH
CALL TABLE
MOVWF PORTD
BCF PORTA,2
CALL DELAY
BSF PORTA,2
MOVFW 31H ;显示分/月的低位
ANDLW 0FH
CALL TABLE
MOVWF PORTD
BCF PORTD,7
BCF PORTA,3
CALL DELAY
BSF PORTA,3
SWAPF 30H,0 ;显示秒/日的高位
ANDLW 0FH
CALL TABLE
MOVWF PORTD
BCF PORTA,4
CALL DELAY
BSF PORTA,4
MOVFW 30H ;显示秒/日的低位
ANDLW 0FH
CALL TABLE
MOVWF PORTD
BCF PORTA,5
CALL DELAY
BSF PORTA,5
;*************************延时程序*****************************
DELAY
MOVLW 3FH
MOVWF 40H
DECFSZ 40H,1
GOTO $-1
RETURN
;**************************************************************
END ;程序结束
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -