查看: 2774|回复: 1

简易带1/100 秒的24 小时制时钟

[复制链接]
  • TA的每日心情
    难过
    2021-2-27 22:16
  • 签到天数: 1568 天

    连续签到: 1 天

    [LV.Master]伴坛终老

    发表于 2017-12-23 23:05:07 | 显示全部楼层 |阅读模式
    分享到:
    ;********************************************************  
    ;AVR汇编程序实例 简易带1/100秒的24小时制时钟
    ;简易带1/100秒的24小时制时钟
    ;MEGA16 4MHz  
    ;********************************************************

    .include "m16de.inc"      ;引用器件I/O配置文件

    ;定义程序中使用的变量名(在寄存器空间)  
    .def count      =   r18   ;循环计数单元  
    .def position      =   r19   ;LED显示位指针,取值为0-7  
    .def p_temp       =   r20   ;LED显示位选,其值取反由PC口输出  
    .def count_10ms   =   r21      ;10ms计数单元  
    .def flag_2ms      =   r22   ;2ms到标志  
    .def temp         =   r23   ;临时变量  
    .def temp1      =   r24      ;临时变量  
    .def int      =   r25   ;临时变量(中断中使用)
    ;中断向量区定义,flash空间$0000-$0045  
    .org $000
       rjmp reset      ;复位处理  
       nop
       reti         ;INT0 Handler  
       nop  
       reti         ;INT1 Handler  
       nop  
       reti         ;Timer2 Compare Handler  
       nop  
       reti         ;Timer2 Overflow Handler  
       nop  
       reti         ;Timer1 Capture Handler  
       nop  
       reti         ;Timer1 CompareA Handler  
       nop  
       reti         ;Timer1 CompareB Handler  
       nop  
       rjmp time1_ovf ;Timer1 Overflow Handler  
       nop
       reti         ;Timer0 Overflow Handler  
       nop  
       reti         ;SPI Transfer Complete Handler  
       nop  
       reti         ;USART RX Complete Handler  
       nop  
       reti         ;USART UDR Empty Handler  
       nop  
       reti         ;USART TX Complete Handler  
       nop  
       reti         ;ADC Conversion Complete Handler  
       nop  
       reti         ;E2PROM Ready Handler  
       nop  
       reti         ;Analog Comparator Handler  
       nop  
       reti         ;Two-wire Serial Interface Handler  
       nop  
       reti         ;INT2  Handler   
       nop  
       reti         ;Timer0 Comp  Handler   
       nop
       reti         ;SPM Ready Handler  
       nop      
    ;程序开始  
    .org $02A  
    reset:   
       ldi r16,high(RAMEND)      ;设置堆栈指针高位  
       out sph,r16  
       ldi r16,low(RAMEND)      ;设置堆栈指针低位  
       out spl,r16  

       ser temp           
       out ddra,temp            ;设置PORTA为输出,段码输出  
       out ddrc,temp            ;设置PORTC为输出,位码控制  
       out portc,temp         ORTC输出$FF, 无显示
       ldi position,0x00         ;段位初始化为1/100秒低位  
       ldi p_temp,0x01         ;LED第1位亮
    ;初始化时钟时间为11:59:55:00  
       ldi xl,low(time_buff)      ;  
       ldi xh,high(time_buff)      ;X寄存器取得时钟单元首指针  
       ldi temp,0x00  
       st  x+,temp            ;1/100秒 = 00  
       ldi temp,55  
       st  x+,temp            ;秒 = 55  
       ldi temp,59  
       st  x+,temp            ;分 = 59  
       ldi temp,11  
       st  x,temp            ;时 = 11
       ldi temp,0xff           ;T1初始化,每隔2ms中断一次  
       out tcnt1h,temp  
       ldi temp,0x83
       out tcnt1l,temp  
       clr temp  
       out tCCr1a,temp  
       ldi temp,0x03            ;16M,64分频 2ms  
       out tccr1b,temp  
       ldi temp,0x04  
       out timsk,temp         ;允许T1溢出中断  
       sei                  ;全局中断允许
    ;主程序  
    main:  
       cpi flag_2ms,0x01         ;判2ms到否  
       brne main               ;No,转main循环  
       clr flag_2ms            ;到,请2ms标志  
       rcall display            ;调用LED显示时间(动态扫描显示一位)  
    d_10ms_ok:  
       cpi count_10ms,0x05      ;判10ms到否  
       brne main               ;No,转main循环  
       clr count_10ms         ;10ms到,清零10ms计数器  
       rcall time_add         ;调用时间加10ms调整  
       rcall put_t2d            ;将新时间值放入显示缓冲单元  
       rjmp main               ;转main循环
    ;LED动态扫描显示子程序,2ms执行一次,一次点亮一位,8位循环  
    display:  
       clr r0  
       ser temp               ;temp = 0x11111111  
       out portc,temp         ;关显示,去消影和拖尾作用  
       ldi yl,low(display_buff)  
       ldi yh,high(display_buff)   ;Y寄存器取得显示缓冲单元首指针  
       add yl,position         ;加上要显示的位值  
       adc yh,r0               ;加上低位进位  
       ld temp,y               ;temp中为要显示的数字  

       clr r0  
       ldi zl,low(led_7 * 2)  
       ldi zh,high(led_7 * 2)      ;Z寄存器取得7段码组的首指针  
       add zl,temp            ;加上要显示的数字  
       adc zh,r0               ;加上低位进位     
       lpm               ;读对应七段码到R0中  
       out porta,r0            ;LED段码输出
       mov r0,p_temp  
       com r0,  
       out portc,r0         ;输出位控制字,完成LED一位的显示  

       inc position         ;调整到下一次显示位  
       lsl p_temp  
       cpi position,0x08  
       brne display_ret  
       ldi position,0x00  
       ldi p_temp,0x01  
    display_ret:  
       ret
    ;时钟时间调整,加0.01秒  
    time_add:  
          ldi xl,low(time_buff)   ;  
          ldi xh,high(time_buff)   ;X寄存器为时钟单元首指针  
          rcall dhm3         ;ms单元加1调整  
          cpi temp,100      ;  
          brne   time_add_ret   ;未到100ms返回  
          rcall dhm         ;秒单元加1调整  
          cpi temp,60  
          brne   time_add_ret   ;未到60秒返回  
          rcall dhm         ;分单元加1调整  
          cpi temp,60  
          brne time_add_ret      ;未到60分返回  
          rcall dhm         ;时单元加1调整  
          cpi temp,24  
          brne time_add_ret         ;未到24时返回  
          clr temp  
          st x,temp            ;到24时,时单元清另  
    time_add_ret:  
          ret
    ;低段时间清零,高段时间加1  
    dhm:  clr temp         ;当前时段清零  
    dhm1: st  x+,temp         ;当前时段清零,X寄存器指针加一  
    dhm3: ld  temp,x         ;取出新时段数据  
          inc temp             ;加一   
    dhm2: st x,temp         ;并将调整结果送回  
          ret
    ;将时钟单元数据送LED显示缓冲单元中  
    put_t2d:  
       ldi xl,low(time_buff)      ;  
       ldi xh,high(time_buff)      ;X寄存器时钟单元首指针  
       ldi yl,low(display_buff)  
       ldi yh,high(display_buff)   ;Y寄存器显示缓冲单元首指针  
       ldi count,4            ;循环次数 = 4  
    loop:  
       clr temp1
       ld   temp,x+            ;读一个时间单元  
    loop1:
       cpi temp,10
       brlo loop2              ;<10转
       inc temp1
       subi temp,10            
       rjmp loop1
    loop2:
       st y+,temp            ;写入2个显示单元  
       st y+,temp1         ;低位BCD码在前,高位在后  
       dec   count  
       brne   loop         ;4个时间单元->8个显示单元  
       ret
    ;T1时钟溢出中断服务  
    time1_ovf:  
       in int,sreg  
       push int            ;保护状态寄存器  
         
       ldi int,0xff         ;T1初始值设定,2ms中断一次  
       out tcnt1h,int  
       ldi int,0x83  
       out tcnt1l,int  
         
       inc count_10ms         ;10ms计数器加一  
       ldi flag_2ms,0x01         ;置2ms标志到  
         
    pop int  
       out sreg,   int         ;恢复状态寄存器  
       reti                  ;中断返回        
         
    .CSEG               ;LED七段码表,定义在Flash程序空间  
    led_7:               ;7段码表  
    .db 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07  
    .db 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71   
    ;字 PA7 PA6 PA5 PA4 PA3 PA2 PA1 PA0 共阴极 共阳极  
    ;   h   g   f   E   d   c   b   a        
    ;0   0   0   1   1   1   1   1   1   3FH      C0H  
    ;1   0   0   0   0   0   1   1   0   06H      F9H  
    ;2   0   1   0   1   1   0   1   1   5BH      A4H  
    ;3   0   1   0   0   1   1   1   1   4FH      B0H  
    ;4   0   1   1   0   0   1   1   0   66H      99H  
    ;5   0   1   1   0   1   1   0   1   6DH      92H  
    ;6   0   1   1   1   1   1   0   1   7DH      82H  
    ;7   0   0   0   0   0   1   1   1   07H      F8H  
    ;8   0   1   1   1   1   1   1   1   7FH      80H  
    ;9   0   1   1   0   1   1   1   1   6FH      90H  
    ;A   0   1   1   1   0   1   1   1   77H      88H  
    ;b   0   1   1   1   1   1   0   0   7CH      83H  
    ;C   0   0   1   1   1   0   0   1   39H      C6H  
    ;d   0   1   0   1   1   1   1   0   5EH      A1H  
    ;E   0   1   1   1   1   0   0   1   79H      86H  
    ;F   0   1   1   1   0   0   0   1   71H      8EH
    .DSEG            ;定义程序中使用的变量位置(在RAM空间)  
    .ORG     $0100  
    display_buff:         ;LED显示缓冲区,8个字节  
    .BYTE   0x00         ;LED 1 位显示内容  
    .BYTE   0x00         ;LED 2 位显示内容  
    .BYTE   0x00         ;LED 3 位显示内容  
    .BYTE   0x00         ;LED 4 位显示内容  
    .BYTE   0x00         ;LED 5 位显示内容  
    .BYTE   0x00         ;LED 6 位显示内容  
    .BYTE   0x00         ;LED 7 位显示内容  
    .BYTE   0x00         ;LED 8 位显示内容
    .org   $0108  
    time_buff:         ;时钟数据缓冲区,4个字节  
    .BYTE   0x00         ;1/100s单元  
    .BYTE   0x00         ;秒单元  
    .BYTE   0x00         ;分单元  
    .BYTE   0x00         ;时单元  


    回复

    使用道具 举报

  • TA的每日心情
    难过
    2021-2-27 22:16
  • 签到天数: 1568 天

    连续签到: 1 天

    [LV.Master]伴坛终老

     楼主| 发表于 2017-12-23 23:05:39 | 显示全部楼层
    ;时钟时间调整,加0.01秒  
    time_add:  
          ldi xl,low(time_buff)   ;  
          ldi xh,high(time_buff)   ;X寄存器为时钟单元首指针  
          rcall dhm3         ;ms单元加1调整  
          cpi temp,100      ;  
          brne   time_add_ret   ;未到100ms返回  
          rcall dhm         ;秒单元加1调整  
          cpi temp,60  
          brne   time_add_ret   ;未到60秒返回  
          rcall dhm         ;分单元加1调整  
          cpi temp,60  
          brne time_add_ret      ;未到60分返回  
          rcall dhm         ;时单元加1调整  
          cpi temp,24  
          brne time_add_ret         ;未到24时返回  
          clr temp  
          st x,temp            ;到24时,时单元清另  
    time_add_ret:  
          ret
    ;低段时间清零,高段时间加1  
    dhm:  clr temp         ;当前时段清零  
    dhm1: st  x+,temp         ;当前时段清零,X寄存器指针加一  
    dhm3: ld  temp,x         ;取出新时段数据  
          inc temp             ;加一   
    dhm2: st x,temp         ;并将调整结果送回  
          ret
    ;将时钟单元数据送LED显示缓冲单元中  
    put_t2d:  
       ldi xl,low(time_buff)      ;  
       ldi xh,high(time_buff)      ;X寄存器时钟单元首指针  
       ldi yl,low(display_buff)  
       ldi yh,high(display_buff)   ;Y寄存器显示缓冲单元首指针  
       ldi count,4            ;循环次数 = 4  
    loop:  
       clr temp1
       ld   temp,x+            ;读一个时间单元  
    loop1:
       cpi temp,10
       brlo loop2              ;<10转
       inc temp1
       subi temp,10            
       rjmp loop1
    loop2:
       st y+,temp            ;写入2个显示单元  
       st y+,temp1         ;低位BCD码在前,高位在后  
       dec   count  
       brne   loop         ;4个时间单元->8个显示单元  
       ret
    ;T1时钟溢出中断服务  
    time1_ovf:  
       in int,sreg  
       push int            ;保护状态寄存器  
         
       ldi int,0xff         ;T1初始值设定,2ms中断一次  
       out tcnt1h,int  
       ldi int,0x83  
       out tcnt1l,int  
         
       inc count_10ms         ;10ms计数器加一  
       ldi flag_2ms,0x01         ;置2ms标志到  
         
    pop int  
       out sreg,   int         ;恢复状态寄存器  
       reti                  ;中断返回        
         
    .CSEG               ;LED七段码表,定义在Flash程序空间  
    led_7:               ;7段码表  
    .db 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07  
    .db 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71   
    ;字 PA7 PA6 PA5 PA4 PA3 PA2 PA1 PA0 共阴极 共阳极  
    ;   h   g   f   E   d   c   b   a        
    ;0   0   0   1   1   1   1   1   1   3FH      C0H  
    ;1   0   0   0   0   0   1   1   0   06H      F9H  
    ;2   0   1   0   1   1   0   1   1   5BH      A4H  
    ;3   0   1   0   0   1   1   1   1   4FH      B0H  
    ;4   0   1   1   0   0   1   1   0   66H      99H  
    ;5   0   1   1   0   1   1   0   1   6DH      92H  
    ;6   0   1   1   1   1   1   0   1   7DH      82H  
    ;7   0   0   0   0   0   1   1   1   07H      F8H  
    ;8   0   1   1   1   1   1   1   1   7FH      80H  
    ;9   0   1   1   0   1   1   1   1   6FH      90H  
    ;A   0   1   1   1   0   1   1   1   77H      88H  
    ;b   0   1   1   1   1   1   0   0   7CH      83H  
    ;C   0   0   1   1   1   0   0   1   39H      C6H  
    ;d   0   1   0   1   1   1   1   0   5EH      A1H  
    ;E   0   1   1   1   1   0   0   1   79H      86H  
    ;F   0   1   1   1   0   0   0   1   71H      8EH
    .DSEG            ;定义程序中使用的变量位置(在RAM空间)  
    .ORG     $0100  
    display_buff:         ;LED显示缓冲区,8个字节  
    .BYTE   0x00         ;LED 1 位显示内容  
    .BYTE   0x00         ;LED 2 位显示内容  
    .BYTE   0x00         ;LED 3 位显示内容  
    .BYTE   0x00         ;LED 4 位显示内容  
    .BYTE   0x00         ;LED 5 位显示内容  
    .BYTE   0x00         ;LED 6 位显示内容  
    .BYTE   0x00         ;LED 7 位显示内容  
    .BYTE   0x00         ;LED 8 位显示内容
    .org   $0108  
    time_buff:         ;时钟数据缓冲区,4个字节  
    .BYTE   0x00         ;1/100s单元  
    .BYTE   0x00         ;秒单元  
    .BYTE   0x00         ;分单元  
    .BYTE   0x00         ;时单元  
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-4-17 04:07 , Processed in 0.121283 second(s), 16 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.