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

📄 time_m8.asm

📁 AVR开发板例子源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;********************************************************************************
;*                                                                              *
;*    File       : time_m8.asm                                                  *
;*    Function   : 实时时钟DS1302应用练习                                       *
;*    Date       : 2006-06-22                                                   *
;*    Version    : 1.0                                                          *
;*                                                                              *
;*    Author     : 开关电源              hongtusy@163.com                       *
;*    Company    : 电子信息技术咨询网    http://www.itsn.cn                     *
;*                                                                              *
;****************************描述与记事******************************************
;实验板的AVR程序,实时时钟DS1302的读写并用138驱动LED显示实验练习。
;接线定义:PC0-CLK时钟(SW5-1)  PC1-I/O数据入/出(SW5-2)  PC2-RET复位(SW5-3)
;PD是138的输入端(SW2-1~3)。使用口资源:PB/PC/PD口
;记事:本程序旨在对实验板杜邦线的使用介绍以及DS1302驱动的理解与演示,程序适合初学者使用。
;提示:第一次使用时需要打通写保护位,就是秒寄存器的最高位。然后可以修改或读取各个计数值。
;     对各个寄存器的操作可以是单字节操作,也可以多(必须是8)字节操作。
;具体电路可参照使用指南里的说明。
;使用器件:ATmega8   使用默认的片内RC振荡器,1MHz。
;开关位置:SW2-1~4,6合上为138的输入和数码管的电源。SW3-7,8为系统复位端。
;杜邦线:需要8+3=11根杜邦线。数码管数据端PB口,用8根杜邦线将PB口和SW1次端的插针连接(注意PB口的次序)
;        1302引脚端,用杜邦线将PC0,1,2口和SW5-0,1,2分别相连。
;功能:使用8数码管交替显示当前的时间-时,分,秒和日期-年,月,日。
;注意事项:第一次使用本程序需要首先给1302写时间初始值,即选中
;下面的“rcall   wrcr   ;写入时钟需要的值”句,以后在运行中就不需要选中了。
;并且主电源断开时时间有电池供电,以后如果不重新烧写数据的程序,读出的将是实时时间。
;********************************************************************************
.include "m8def.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        ddrb,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        ddrc,1           ;PC1暂时为输出
            nop
            cbi        portc,2           ;ret=0
            nop
            cbi        portc,0           ;clk=0
			nop
            sbi        portc,2           ;ret=1
			nop

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

            cbi        portc,2           ;ret=0
            cbi        portc,0           ;clk=0
            sbi        portc,2           ;ret=1

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

            cbi        portc,2           ;ret=0
            cbi        portc,0           ;clk=0
            sbi        portc,2           ;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        portc,2           ;ret=0
			ret
;---------------------多字节模式读出各个寄存器数据程序---------------------
rdcr:       cbi        portc,2           ;ret=0
            nop
            cbi        portc,0           ;clk=0
			nop
            sbi        portc,2           ;ret=1
			sbi        ddrc,1           ;PC1暂时为输出

			ldi        r18,0xbf         ;多字节读命令
			rcall      wbyte            ;写入命令
	        cbi        ddrc,1           ;PC1暂时为输入

			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        portc,2           ;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        portc,1           ;I/Oout=0,输出0
            rjmp       wb1              ;转移
b1:         sbi        portc,1           ;I/Oout=1,输出1       
            nop
wb1:    	sbi        portc,0           ;clk=1
			nop
			nop
            cbi        portc,0           ;clk=0
			dec        r16              ;寄存器减1
            cpi        r16,0            ;与立即数0比较
			brne       wb0              ;不为0,继续发送下一位。
			ret
;----------8位读出数据程序,读出的数据放在r18中----------------------
rbyte:      ldi        r16,0x08         ;一字节8位。
rb0:        in         r17,pinc         ;读取端口PIND的数据
            sbrc       r17,1            ;指定位为0跳行
            rjmp       d1               ;否则肯定为1
d0:         clc                         ;c=0
            ror        r18              ;带C循环右移,r18将放读出的数据

⌨️ 快捷键说明

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