⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 实验板time.asm

📁 单片机实时时钟控制 汇编语言编写 源程序。
💻 ASM
字号:
;********************************************************************************
;*                                                                              *
;*    File       : 实验板time.asm                                               *
;*    Function   : 实时时钟DS1302应用练习                                       *
;*    Date       : 2006-06-22                                                    *
;*    Version    : 1.0                                                          *
;*                                                                              *
;*    Author     : 开关电源              hongtusy@itsn.cn                       *
;*    Company    : 电子信息技术咨询网    http://www.itsn.cn                     *
;*                                                                              *
;****************************描述与记事******************************************
;实验板的AVR程序,实时时钟DS1302的读写并用138驱动LED显示实验练习。
;接线定义:PA3-CLK时钟(SW5-1)  PA4-I/O数据入/出(SW5-2)  PA5-RET复位(SW5-3)
;数码管部分,PC为数据端(SW1-1~8),PD是138的输入端(SW2-1,2,3,6),SW3-8为系统复位端。
;记事:本程序旨在对DS1302驱动的理解与演示,程序适合初学者使用。
;提示:第一次使用时需要打通写保护位,就是秒寄存器的最高位。然后可以修改或读取各个计数值。
;     对各个寄存器的操作可以是单字节操作,也可以多(必须是8)字节操作。本示例是多字节操作。
;具体电路可参照使用指南里的说明。
;使用器件:ATMEGA8535,可更换。          使用默认的片内RC振荡器,1MHz。
;注意事项:第一次使用本程序需要首先给1302写时间初始值,即选中
;下面的“rcall   wrcr   ;写入时钟需要的值”句,以后在运行中就不需要选中了。
;并且主电源断开时时间有电池供电,以后如果不重新烧写数据的程序,读出的将是实时时间。
;********************************************************************************
.include "m8535def.inc"                      ;定义头文件。
.org        0x0000                          ;指定开始地址。
            rjmp       reset                ;转移到“RESET”句。
.org        0x10


reset:      ldi        r16,0x02            ;设置堆栈指针0x025f
            out        sph,r16
			ldi        r16,0x5f
			out        spl,r16
     ;---------------------------
			ldi        r16,0xff            ;加载立即数,把立即数0XFF放到定义过的Temp中,作数据方向参数。
			out        ddrc,r16            ;PC口为输出,数码管的段码端
            out        ddra,r16            ;PA口为输出,PA5接时钟芯片的复位端,PA3/4是时钟和数据端
			out        ddrd,r16            ;PD口为输入/出,145的输入控制部分使用末4位
            rcall      datin               ;装入初始数据

            rcall      wrcr                ;写入时钟需要的值


;------------------年月日和时分秒交替显示-----------------------
star:       ldi        r19,0xf0
star1:      rcall      rdcr                ;读数据
            rcall      moin1               ;数据分开,装入显存,时,分,秒
            rcall      display             ;动态显示
			rcall      display
			rcall      display
			dec        r19                 ;减1
            cpi        r19,0
			brne       star1
            ldi        r19,0x60
star2:      rcall      rdcr                ;读数据
            rcall      moin2               ;数据分开,装入显存,年,月,日
            rcall      display             ;动态显示
			rcall      display
			rcall      display
			dec        r19                 ;减1
            cpi        r19,0
			brne       star2
			rjmp       star
 
;--------------------多字节模式写入各个寄存器数据程序------------------------
;-----每次上电后,自动处于写保护状态,必须先解除写保护,然后才能进行写操作。
;-----并且每次重新上电后,自动处于暂停状态,必须使秒寄存器的D7位为0,才能开始计时。
;-----方便起见,这里对年月日时分秒的数据写和读都采用了多字节读写的命令。一次操作8个寄存器。
;-----如果只操作一个的话,就先写相应的地址在读或写相应的数据操作即可。
;--这里的操作顺序是:解除写保护-->复位一次-->单字节对涓流充电的操作-->复位一次-->多字节写命令-->连续8个写入的数据。
;--刚上电时,充电器是被禁止的,我们把TCS改为1010后,启动充电。由于电源是5V,电池是3V,我们选择两个二极管和4k电阻。
wrcr:       sbi        ddra,4           ;PA4(dat)暂时为输出
            nop
            cbi        porta,5           ;ret=0
            nop
            cbi        porta,3           ;clk=0
			nop
            sbi        porta,5           ;ret=1
			nop

			ldi        r18,0x8e         ;写保护命令字节的地址,0b10001110
			rcall      wbyte            ;写指令
			ldi        r18,0x00         ;解除写保护
			rcall      wbyte

            cbi        porta,5           ;ret=0
            cbi        porta,3           ;clk=0
            sbi        porta,5           ;ret=1

			ldi        r18,0b10010000   ;涓流充电寄存器地址
			rcall      wbyte            ;写命令
            ldi        r18,0b10101010   ;充电使能TCS=1010,二极管=10(两个),电阻=10(4kOHM)
			rcall      wbyte            ;写命令

            cbi        porta,5           ;ret=0
            cbi        porta,3           ;clk=0
            sbi        porta,5           ;ret=1

			ldi        r18,0xbe         ;多字节写命令,之后必须连续写8个字节数据,否则无效。
            rcall      wbyte            ;写指令
			ldi        r18,0x00         ;00秒,这样保证了秒寄存器的D7位是0,从而启动计时了。
			rcall      wbyte
			ldi        r18,0x48         ;48分
			rcall      wbyte
			ldi        r18,0x13         ;13时,最高位TP为0,表示24小时制。
			rcall      wbyte
			ldi        r18,0x01         ;01日
			rcall      wbyte
			ldi        r18,0x10         ;10月  ;该位还有问题,月份不能大于等于10,不知道为什么
			rcall      wbyte
			ldi        r18,0x01         ;星期一
			rcall      wbyte
			ldi        r18,0x06         ;06年
			rcall      wbyte
			ldi        r18,0x00         ;写保护内容,允许写操作。
			rcall      wbyte

			cbi        porta,5           ;ret=0
			ret
;---------------------多字节模式读出各个寄存器数据程序---------------------
rdcr:       cbi        porta,5           ;ret=0
            nop
            cbi        porta,3           ;clk=0
			nop
            sbi        porta,5           ;ret=1
			sbi        ddra,4           ;PA4暂时为输出

			ldi        r18,0xbf         ;多字节读命令
			rcall      wbyte            ;写入命令
	        cbi        ddra,4           ;PA4暂时为输入

			rcall      rbyte            ;读数据
			mov        r0,r18           ;秒
			rcall      rbyte
			mov        r1,r18           ;分
			rcall      rbyte
			mov        r2,r18           ;时
			rcall      rbyte
			mov        r3,r18           ;日
			rcall      rbyte
			mov        r4,r18           ;月
			rcall      rbyte
			mov        r5,r18           ;星期
			rcall      rbyte
			mov        r6,r18           ;年
			rcall      rbyte
			mov        r7,r18           ;写保护数据

			cbi        porta,5           ;ret=0
			ret
;----------8位写入指令程序,数据需要事先放在r18中----------------------
wbyte:      ldi        r16,0x08         ;写入命令
wb0:        ror        r18              ;带C循环右移,r18放的是数据。
            brbc       0,b0             ;若C为0跳转,输出0。
			rjmp       b1               ;否则肯定为1,输出1。
b0:         cbi        porta,4           ;I/Oout=0,输出0
            rjmp       wb1              ;转移
b1:         sbi        porta,4           ;I/Oout=1,输出1       
            nop
wb1:    	sbi        porta,3           ;clk=1
			nop
			nop
            cbi        porta,3           ;clk=0
			dec        r16              ;寄存器减1
            cpi        r16,0            ;与立即数0比较
			brne       wb0              ;不为0,继续发送下一位。
			ret
;----------8位读出数据程序,读出的数据放在r18中----------------------
rbyte:      ldi        r16,0x08         ;一字节8位。
rb0:        in         r17,pina         ;读取端口PIND的数据
            sbrc       r17,4            ;指定位为0跳行
            rjmp       d1               ;否则肯定为1
d0:         clc                         ;c=0
            ror        r18              ;带C循环右移,r18将放读出的数据
            rjmp       rb1              ;转移
d1:         sec                         ;c=1
            ror        r18              ;带C循环右移,r18将放读出的数据
            nop
rb1:    	sbi        porta,3           ;clk=1
			nop
			nop
			cbi        porta,3           ;clk=0
			dec        r16              ;寄存器减1
            cpi        r16,0            ;与立即数0比较
			brne       rb0              ;不为0,继续发送下一位。
			ret
;---------------------------------








;----数据分开,并分别装入相应的显示存储器中,时,分,秒-------------------
moin1:      mov          r16,r0          ;秒
            cbr          r16,0xf0
			mov          r27,r16
            swap         r0
			mov          r16,r0
			cbr          r16,0xf0
			mov          r26,r16
  
            mov          r16,r1          ;分
			cbr          r16,0xf0
			mov          r24,r16
			swap         r1
			mov          r16,r1
			cbr          r16,0xf0
			mov          r23,r16

			mov          r16,r2          ;时
			cbr          r16,0xf0
			mov          r21,r16
			swap         r2
			mov          r16,r2
			cbr          r16,0xf0
			mov          r20,r16

			ldi          r22,16         ;-
			ldi          r25,16         ;-

			ret
;----数据分开,并分别装入相应的显示存储器中,年,月,日-------------------
moin2:      mov          r16,r3          ;日
            cbr          r16,0xf0
			mov          r27,r16
            swap         r3
			mov          r16,r3
			cbr          r16,0xf0
			mov          r26,r16

            mov          r16,r4          ;月
			cbr          r16,0xf0
			mov          r24,r16
			swap         r5
			mov          r16,r5
			cbr          r16,0xf0
			mov          r23,r16

                                         ;r5存的是星期值。

			mov          r16,r6          ;年
			cbr          r16,0xf0
			mov          r21,r16
			swap         r6
			mov          r16,r6
			cbr          r16,0xf0
			mov          r20,r16

			ldi          r22,17         ;_
			ldi          r25,17         ;_

			ret            



;----------r20-r29单元是显示存储区,只要把数据装入这些寄存器,调动态扫描程序就可以显示了。
datin:      ldi        r20,0            ;0
			ldi        r21,0            ;0
			ldi        r22,16           ;-
			ldi        r23,0            ;0
			ldi        r24,0            ;0
			ldi        r25,16           ;-
			ldi        r26,0            ;0
			ldi        r27,0            ;0
			ret
;################led动态扫描显示子程序,使用前把显示数据装入显示存储器中###使用145############
;可显示的字符包括:0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F、-、_、P、X、
display:	ldi        r16,0B10000000      ;作共阴的公共脚。
			out        portd,r16           ;位号,第1位。
			mov        r16,r20             ;数据1
			rcall      dxaa                ;显示
     ;----------------------------
            ldi        r16,0B10010000
			out        portd,r16           ;位号,第2位。
			mov        r16,r21             ;数据2
			rcall      dxaa                ;显示 
     ;----------------------------
            ldi        r16,0B10100000
			out        portd,r16           ;位号,第3位。
			mov        r16,r22             ;数据3
			rcall      dxaa                ;显示 
     ;----------------------------
            ldi        r16,0B10110000
			out        portd,r16           ;位号,第4位。
			mov        r16,r23             ;数据4
			rcall      dxaa                ;显示 
     ;----------------------------
            ldi        r16,0B11000000
			out        portd,r16           ;位号,第5位。
			mov        r16,r24             ;数据5
			rcall      dxaa                ;显示 
     ;----------------------------
            ldi        r16,0B11010000
			out        portd,r16           ;位号,第6位。
			mov        r16,r25             ;数据6
			rcall      dxaa                ;显示 
    ;----------------------------
            ldi        r16,0B11100000
			out        portd,r16           ;位号,第7位。
			mov        r16,r26             ;数据7
			rcall      dxaa                ;显示 
     ;----------------------------
            ldi        r16,0B11110000
			out        portd,r16           ;位号,第8位。
			mov        r16,r27             ;数据8
			rcall      dxaa                ;显示 
      ;----------------------------
			ret
      ;------取码/延迟/消隐多功能程序---------
dxaa:       ldi        zh, high(Table_1<<1); 初始化Z指针
            ldi        zl, low(Table_1<<1)
            clc                            ;清进位标志
			add        r30,r16             ;r16放的是要显示的数据,处理低字节数据
            clr        r16                 ;r16清0
			adc        r31,r16             ;处理高字节数据
            lpm        r16,z               ;从程序存储器中装入Z指针(r31:r30)指向的常量
			out        portc,r16
			rcall      londel              ;长延时
            ser        r16                 ;消隐
			out        portc,r16
			rcall      del
			ret
        ;------------------------
Table_1:
.db  0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0xBF,0xF7,0x8C,0xFF
;共阳  0   1    2     3   4    5     6    7    8    9   A    b    C    d    E    F    -    _    P    X
;***************************************************************************************************




;#################短延迟程序##################
del:        ldi        r16,0x1f          ;使用内部1MHzRC震荡器
del1:       dec        r16               
            brne       del1            
			nop
			ret
;###################钳套的延迟程序################
londel:     ldi        r17,0x08
del2:       rcall      del
            rcall      del
            dec        r17
			brne       del2
            ret

;##################end###############












⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -