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

📄 mywork.asm

📁 ATmega16的定时中断汇编程序
💻 ASM
字号:
;By Laoliu
;利用定时中断,每秒钟LED数码管显示数字减1,
;For mega16,未经优化
;定时/计数器实现中断控制


;头文件及变量定义
.include "m16def.inc"
.def temp=r23
.def res=r24
.def T_flag=r25
.def T=r22
.def De=r17
.def  p_temp=r20
.def  position=r19
.def  dis_num1=r18
.def  dis_num=r21
.def  T_coun=r16
;#######################################
;**************中断向量区***************
;#######################################
;如果对应的中断功能没用到,则用reti和nop填充(双字),可提高抗干扰性能
.org		$000
    jmp		RESET			;复位处理

	reti					;IRQ0中断向量
	nop
	reti					;IRQ1中断向量
	nop
	reti					;Timer2 比较中断向量
	nop
	reti					;Timer2 溢出中断向量
	nop
	reti					;Timer1捕捉中断向量
	nop
	reti					;Timer1比较A中断向量
	nop
	reti					;TIMER1比较B中断向量
	nop
	reti					;TIMER1溢出中断向量
	nop
    jmp    Time_process     ;TIMER0溢出中断向量
	
	reti					;SPI传输结束中断向量
	nop
	reti					;USART RX结束中断向量
	nop
	reti					;UDR空中断向量
	nop
	reti					;USART TX结束中断向量
	nop
	reti					;ADC转换结束中断向量
	nop
	reti					;EEPROM就绪中断向量
	nop
	reti					;模拟比较器中断向量
	nop
	reti					;两线串行连接口中断向量
	nop
	reti					;IRQ2中断向量
	nop
	reti					;定时器0比较中断向量
	nop
	reti					;SPM就绪
	nop	





;################################################
;*******************代码区***********************
;################################################
.org		$02a ;代码区起始地址0x002a,0x0000--0x0029是中断向量区


;\\\\\\\\\\\\\\\\\\\\\\
;\\\复位中断服务程序\\\
;\\\\\\\\\\\\\\\\\\\\\\
RESET:
	  ldi	  r16,high(RAMEND)  ;堆栈指针指向ram终端
	  out	  SPH,r16
	  LDI	  r16,low(RAMEND)   ;
	  out	  SPL,r16          

	  clr	  temp    ;初始化I/O端口
	  clr	  res
	  ldi     temp,0x0f
	  ldi     res,0x00
	  out     ddrc,temp
	  out     portc,res
	  ldi     temp,0xff
	  ldi     res,0x00
	  out     ddrd,res
	  out     ddrb,temp
      out     ddra,temp
      out     portb,temp
      out     porta,temp
	  out     portd,temp

	  ldi     temp,0xaa
	  ldi     res,0x7c
	  ldi     dis_num,0xff
	  mov     r15,dis_num
	  mov     r1,res
	  mov     r5,temp
	  
	  ldi     temp,0x00   ;时钟:4MHz,分频系数:64,溢出中断周期:4ms
	  out     tcnt0,temp
	  ldi     temp,0x01    ;禁止输出比较匹配,开T/C0溢出中断
	  out     timsk,temp
	  ldi     temp,0x03    ;普通模式,PB3为普通I/O口,时钟源来自预分频1/64
	  out     tccr0,temp
	  ldi     De,96
	 	 
	  ldi     zl,low(led_7)   ;SRAM首地址低8位
	  ldi     zh,high(led_7)   ;SRAM首地址高八位
	  ldi     temp,0xc0        ;对SRAM中的变量赋值:0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90  (共阳)
	  st      z+,temp
	  ldi     temp,0xf9
	  st      z+,temp
	  ldi     temp,0xa4
	  st      z+,temp
	  ldi     temp,0xb0
	  st	  z+,temp
	  ldi     temp,0x99
	  st      z+,temp
	  ldi     temp,0x92
	  st      z+,temp
	  ldi     temp,0x82
	  st      z+,temp
	  ldi     temp,0xf8
	  st      z+,temp
	  ldi     temp,0x80
	  st      z+,temp
	  ldi     temp,0x90
	  st      z+,temp
	  ldi     temp,0x05   ;dis_n
	  st      z+,temp
	  ldi     temp,0x00
	  st      z+,temp
	  ldi     temp,0x00
	  st      z+,temp
	  ldi     temp,0x00
	  st      z+,temp
	  ldi     temp,0x05   ;Time
	  ldi     res,0x00
	  ldi     dis_num,0x00
	  ldi     dis_num1,0x00

	  ldi     p_temp,0x08
	  ldi     position,0x00
	  ldi     zl,low(led_7)
	  ldi     zh,high(led_7)
	  
	  
	  sei

;\\\\\\\\\\\\\\\\\\\\\\\\\\\
;主函数,注意死循环的实现\\\\
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
main_0:
      cpi    T_flag,0xff
	  brne   main_0
	  clr    T_flag
      rcall  display
	  
;\\\\\\\\\\\\\\\\\\\\\\
;\\\\时间计数器\\\\\\\\
;\\\\\\\\\\\\\\\\\\\\\\
Time_sec:
      cpi     T_coun,0x7c
	  brne    j    
      com     r5
	  out     portb,r5
	  

      
j:
      cpi     T_coun,0xf9    ;250次中断=1s
	  brne    main_0
	  
	  com     r15
	  out     portb,r15
	  clr     T_coun
	  rcall   Time_dec    ;call与rcall有区别:call将pc+2后的值压入堆栈,而rcall则将pc+1后的值压入堆栈
	  rcall   T_save
	  rjmp    main_0      ;死循环至此

;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
;\\\\\时钟调整\\\\\\\\\\\\\\\\\\\\
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
Time_dec:
         cpi   temp,0x00
		 breq  T_1
		 dec   temp
		 ret
T_1:     
         ldi   temp,0x09
		 cpi   res,0x00
		 breq  T_2
		 dec   res
		 ret
T_2:     
         ldi   res,0x09
		 cpi   dis_num,0x00
		 breq  T_3
		 dec   dis_num
		 ret
T_3:
         ldi   dis_num,0x09
		 cpi   dis_num1,0x00
		 breq  T_cli
		 dec   dis_num1
		 ret


T_cli:  

        clr   temp
        clr   res
		clr   dis_num
		clr   dis_num1
		out   tccr0,temp   ;turn off T_Ovf
		call  light
		ret  
light: 
        ldi   temp,0xaa
		ldi   res,0x55
		ldi   dis_num,0x80
		ldi   dis_num1,0xff
		out   portc,dis_num
		out   portb,temp
		call  delay
		out   portc,dis_num1
		com   temp
		out   portb,temp
		call  delay
		rjmp  light
           
;\\\\\\\\\\\\\\\\\\\\\\\
;\\\\存储时间\\\\\\\\\\\
;\\\\\\\\\\\\\\\\\\\\\\\
T_save:
       ldi    yl,low(dis_n)
	   ldi    yh,high(dis_n)
	   st     y+,temp
	   st     y+,res
	   st     y+,dis_num
	   st     y,dis_num1
	   ret
       
	 
;\\\\\\\\\\\\\\\\\\\\\\\
;定时计数器0溢出中断处理      
;\\\\\\\\\\\\\\\\\\\\\\\
Time_process:
             push    res
			 push    temp
             in      res,sreg
			 push    res
             
			 ldi     temp,0x00
			 out     tcnt0,temp
			 inc     T_coun
			 ldi     T_flag,0xff
            
			 pop     res
			 out     sreg,res
			 pop     temp
             pop     res
			 reti
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
;\\\\\\\\\汇编通用延时子程序\\\\\\\\\
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
Delay:
      push      De

Del1:
      push      De

Del2:
      push      De

Del3:
     dec     De
	 brne    Del3
	 pop     De
	 dec     De
	 brne    Del2
	 pop     De
	 dec     De
	 brne    Del1
	 pop     De
	 ret			

;\\\\\\\\\\\\\\\\\\\
;\\\\动态扫描函数\\\\
;\\\\\\\\\\\\\\\\\\\\\

display:
        clr     r0
		push    temp
		ser     temp
		out     portc,temp      ;turn off led_7
        ldi     yl,low(dis_n)
		ldi     yh,high(dis_n)   ;显示缓存地址
		add     yl,position
		adc     yh,r0
		ld      temp,y        ;取出要显示的数字
         
        clr     r0             ;根据要显示的数字去led_7码表中去数码
        ldi     zl,low(led_7)
		ldi     zh,high(led_7)
		add     zl,temp
		adc     zh,r0
		ld      temp,z        ;要显示的数字的代码送到temp中
        out     porta,temp

		mov     r0,p_temp
        com     r0
		out     portc,r0      ;输出控制位

        inc     position
		lsr     p_temp
		cpi     position,0x04
		brne    dis_exit
		ldi     position,0x00
		ldi     p_temp,0x08
		

dis_exit:
        pop     temp
        ret


;\\\\\\\\\\\\\\\\\\\\\\\\\\\\
;\\\\\\\定义SRAM的变量\\\\\\\
;\\\\\\\\\\\\\\\\\\\\\\\\\\\\
.dseg            ;数据段预留存放数据的空间但不能赋值!!!!只能用.byte定义,.byte只能出现在.dseg 段中
.org  $0060
led_7:      ;七段数码管
	    .byte 1  ;'0'
		.byte 1  ;'1'
		.byte 1  ;'2'
		.byte 1  ;'3'
		.byte 1  ;'4'
		.byte 1  ;'5'
		.byte 1  ;'6'
		.byte 1  ;'7'
		.byte 1  ;'8'
		.byte 1  ;'9'

dis_n:      ;待显示的数字(显示缓存)
	    .byte 1  ;v0
		.byte 1  ;v1
		.byte 1  ;v2
		.byte 1  ;v3


⌨️ 快捷键说明

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