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

📄 file5.asm

📁 单片机学习系统附的实验源代码
💻 ASM
字号:
;这是外部中断的例子程序,包含:外部中断设置,中断服务程序
;以及数据处理,显示,包括 两位十进制数转化为三位BCD码,
;这里是一个小型频率计的设计程序
;现象:LED1不停闪烁输出信号(为我们实验提供外部中断信号源),我们只需要把
;单片机的P1.0(对应LED1也就是信号源)和P3.2(外部中断0)用短路线相连,我们
;就可以看到,数码管开始计数(外部中断次数),同时,LED指示灯也在不停地从
;左向右移动,如果不直接用P1.0作为信号源,我们可以外接需要计数的脉冲信号
;但是要注意,信号频率范围不能大于100K/幅度不能大于5V。否则,可能造成对
;系统芯片的损伤

        beep   bit  p3.7
                
        led1   bit  p1.0
        led2   bit  p1.1
        led3   bit  p1.2
        led4   bit  p1.3
        led5   bit  p1.4
        led6   bit  p1.5
        led7   bit  p1.6
        led8   bit  p1.7
        
		segdata equ p0      ;数据 输出
		sege    equ p2.7    ;显示 选中
		segb    equ p2.6    ;位 选
		segd    equ p2.5    ;段 选
		
	    int_h   equ  45h    ;中断计数缓冲单元高地址
 	    int_l    equ  44h   ;中断计数缓冲单元低地址
        int_data equ 43h    ;用来刷新LED指示的数据单元
         
        t_h      equ   60h  ;数据显示的高位
        t_s      equ   61h  ;数据显示中位
        t_m      equ   62h  ;数据显示低位
        disstart equ   70h  ;显示单元首地址

	org 00h                 ;代码开始地址
	ajmp main               ;主程序开始 
	
	org 03h                 ;外部中断EX0入口地址
	ajmp ex_int0            ;中断服务程序 
	
	org 030h

   main:mov sp,#30h          ; 设置sp指针
	    lcall pro_set        ;初始化
        lcall pro_int0       ;外部中断1工作设置
    mlp:     
        lcall ex_pro         ;外部中断数据转换
        lcall ex_display     ;外部中断数据显示
        cpl p1.0             ;取反 p1.0 获得外部脉冲
                             ;我们利用它来进行中断计数操作
        ajmp mlp

pro_set:mov a,#00h           ;初始化程序
		mov b,#00h
		mov p0,#0
		mov p1,0ffh          ;p1 = 255 (十进制,写成十六进制 0FFH ) 
		mov p2,#255          ;p2 = 255 (十进制,写成十进制为 255 )   
        mov int_h,#00h
        mov int_l,#00h
        mov t_s,#00h
        mov t_h,#00h
        mov t_m,#00h
        clr beep
        ret

ex_int0:mov p0,#00h              ;禁止数码管显示
        mov a,int_data           ;取得LED显示缓冲数据
	    rl a                     ;移位
        inc a
	    mov int_data,a           ;修改 显示区数据
	    mov p1,a                 ;显示
        inc  int_l               ;将中断缓冲区低地址加1
        mov a,int_l              ;判断是否有进位
        jnz int_end              ;没有则返回
        inc int_h                ;否则,将高地址加1
int_end:  reti                   ;中断返回
;***********************************
;*******   设置中断  ****************
pro_int0:
         mov int_data,#01h       ;LED数据单元为1
         clr c                   ;清进位标志
	     setb  it0               ;设置中断触发方式:脉冲触发
	     setb ea                 ;总的中断允许
	     setb ex0                ;允许外部中断EX0中断
	     clr ex1                 ;禁止外部中断EX1中断
       ret                       ;返回
; **********************************
ex_display:
         clr sege                ;显示选中
         mov r0,#disstart        ;获得显示单元首地址
         mov r1,#01h             ;从第一个数码管开始
         mov r2,#06h             ;共显示6位数码管
   dislp:mov segdata,@r0         ;读取显示单元数据 
         setb segd
         nop
         clr segd 
         inc r0                  ;取下一个单元地址
         mov segdata,r1               ;开始显示当前位
         setb segb
         nop
         clr segb
         mov a,r1                ;准备显示下一位
         rl a                          ;
         mov r1,a                ;下一位
         lcall delay5ms          ;延时 5 ms
         djnz r2,dislp           ; 重复显示下一个
         ret                     ;显示完成,返回

;ex_pro   时间处理,主要为 bcd码转换,查表
ex_pro:  setb psw.3                     ;准备 寄存器 
         clr psw.4                      ;
         mov r6,int_h                   ;得到高位数据
         mov r7,int_l                   ;得到低位数据
         lcall data_pro                 ;开始转换
         lcall bcd                      ;转换完成后,开始进行码型变换
         mov r0,#disstart               ;开始填充显示单元
         mov r2,#06h                    ;共计填充 6 位
    prlp:mov a,@r0                      ;获得当前位地址
         mov dptr,#tab_nu               ;获得表头
         movc a,@a+dptr                 ;获得编码数据
         mov @r0,a                      ;保存编码数据
         inc r0                         ;指向下一个带转换数据
         djnz r2,prlp                   ;继续转换,直到完成
         ret                            ;转换完成,返回

data_pro:                               ;两位 十六进制 转化为 2 位 BCD 码
           PUSH PSW                     ;高位 ->R6 低位 ->R7,转化后 从高到低 t_s,t_m,t_h 
           SETB PSW.3                   ;设置当前寄存器
           CLR PSW.4
           CLR A                        ;清累加器                
           MOV t_h,A                    ;清除出口单元,准备转换
           MOV t_m,A
           MOV t_s,A
           MOV R2,#10H                  ;共计转换 16 位 
  HB3: MOV A,r7                         ;获得低位数据
           RLC A                        ;带位左移,高位数据在CY中
           MOV r7,A                     ;保存数据
           MOV A,r6                     ;取得高位数 
           RLC A                        ;带进位左移
           MOV r6,A                     ;保存数据
           MOV A,t_s                    ;得到低位数据
           ADDC A,t_s                   ;累加 
           DA A                         ;十进制调整
           MOV t_s,A                    ;保存数据
           MOV A,t_m                    ;得到第二位数据
           ADDC A,t_m                   ;累加
           DA A                         ;十进制调整
           MOV t_m,A                    ;保存结果
           MOV A,t_h                    ;得到第三位     
           ADDC A,t_h                   ;累加
           MOV t_h,A                    ;保存
           DJNZ R2,HB3                  ;没有转换完毕,重复转换
           POP PSW                      ;转换完毕,恢复PSW
      RET                               ;返回

;码型变换,将带转换的数据分成,不同的数位,并转换成单位BCD码
bcd:    mov r0,#disstart                ;获得首地址
           mov a,t_s                    ;获得待转化的低位
           mov b,#16                    ;转化进制,如果要进行十进制转换 改为 10
           div ab                       ;计算 A/B
           mov @r0,b                    ;第一位转换完毕,保存低位转化后的数据
           inc r0                       ;自增
           mov @r0,a                    ;保存高位
           inc r0                       ;取第二个数据地址
           mov a,t_m                    ;获得第二个需要转换的数据
           mov b,#16                    ;十六进制
           div ab                       ;计算
           mov @r0,b                    ;存低位
           inc r0                  
           mov @r0,a                    ;存高位
           inc r0                       ;第三位
           mov a,t_h                    ;获得数据
           mov b,#16                    ;十六进制
           div ab                       ;计算
           mov @r0,b                    ;存低位
           inc r0                    
           mov @r0,a                    ;存高位
           ret                          ;完毕,返回
;************  250 ms 延时 ******************8

delay:  push psw               ; 保存原来的寄存器单元
        clr psw.3              ; 设置新的寄存器
		setb psw.4             ; 
		mov r0,#2              ; 延时参数1 
		mov r1,#250            ; 延时参数2
		mov r2,#2              ; 延时参数3
    dl1:djnz r0,dl1            ; 延时循环1
    	mov r0,#250            ; 重新设置循环数据
    dl2:djnz r1,dl1            ; 开始第二道循环 
        mov r0,#240            ;
        mov r1,#248            ; 
    dl3:djnz r2,dl1            ; 第三道循环
		nop                    ; 修正定时精度
		pop psw                ; 恢复原来的寄存器组
        ret                    ; 返回 
;  ***********************************************

;**************  定时 5ms ************
delay5ms:                            ;参见上面说明
	  push psw
	  clr  psw.3
	  setb  psw.4
	  mov r0,#250
	  mov r1,#5
  d20:djnz r0,d20
      mov r0,#250
      djnz r1,d20
      pop psw
      ret

; ****************************************
;这是数字显示表格,其中 带小数点的数字比不带小数点的数字大16
; 比如 0 的显示代码为 0;那么 0.的显示代码为 16;如此类推

tab_nu: db 0c0h,0f9h, 0a4h, 0b0h, 99h , 92h , 82h, 0f8h ; number 0 to 7 no dp..
        db 80h , 90h, 88h , 83h , 0c6h, 0a1h, 86h, 8eh  ; number 8 to f no dp..
        db 40h , 79h, 24h , 30h , 19h , 12h , 02h, 78h  ; number 0 to 7 with dp..
        db 00h , 10h, 08h , 03h , 46h , 21h , 06h, 0eh  ; number 8 to f with dp..

      end ;告诉编译器本程序到此结束,一定需要加上,否则编译通不过。

⌨️ 快捷键说明

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