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

📄 file13.asm

📁 单片机学习系统附的实验源代码
💻 ASM
字号:
;这是频率计的例子程序,包含:外部中断设置,中断服务程序,定时程序,定时服务程序
;以及数据处理,显示,包括 两位十进制数转化为三位BCD码,
;这里是一个高精度频率计的设计程序
;现象:数码管led1不断闪烁,同时,数码管显示当前计数的频率值!
;只要我们把p1.0(假想的信号源)和p3.2(外部中断0)直接相连,就可以在数码管看到频率值

        beep   bit  p3.7


		segdata equ p0      ;数据 输出
		sege    equ p2.7    ;显示 选中
		segb    equ p2.6    ;位 选
		segd    equ p2.5    ;段 选
	
        timer_h   equ   46h    ;定时器高位字节单元
        timer_l   equ   47h    ;定时器低位字节单元
        timcount  equ   48h    ;时间中断数
        count_h   equ   49h    ;计数值高位
        count_l   equ   4ah    ;计数值低位

		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    ;显示单元首地址
        flag      equ   71h    ;显示结果

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

    org 1bh
    jmp timer_int              ;定时器T1中断服务程序
	
	org 030h

   main:mov sp,#30h             ; 设置sp指针
	    lcall pro_set           ; 初始化
        lcall pro_int0          ; 外部中断0工作初始化
        lcall tim_t1            ; 定时器T1工作方式设定

    mlp:lcall ex_pro            ; 外部中断数据转换
        lcall ex_display        ; 外部中断数据显示
        cpl p1.0                ; 取反 p1.0 获得外部脉冲
                                ; 我们利用它来进行中断计数操作
        jmp mlp

pro_set:mov a,#00h               ;初始化程序
		mov b,#00h
		mov p1,0ffh              ;p1 = 255 (十进制,写成十六进制 0FFH )   
        mov int_h,#00h
        mov int_l,#00h
        mov t_s,#00h
        mov t_h,#00h
        mov t_m,#00h
        mov timcount,#20
        mov timer_h,#3ch           ;定时 50 ms
        mov timer_l,#0c1h    
        mov count_l,#0
        mov count_h,#0      ;

        clr beep
     ret
;  **************  定时器设置   ************************
tim_t1: mov tmod,#10h           ;设置定时器,定时1s
        setb et1                ;允许定时中断
        mov th1,timer_h         ;设置定时初值高位
        mov tl1 ,timer_l        ;设置定时初值低位
        setb tr1                ;定时器开始工作
        ret
;  ***********  定时器中断服务程序  *******************
   
 timer_int:  
             clr tr1            ;定时器中断服务,关闭定时器
             mov tl1,timer_l    ;重新赋初值
             mov th1,timer_h
             mov r0,timcount                
             djnz r0,t_end
             mov timcount,#20   ;到1s
             mov int_l,count_l  ;刷新显示部分
             mov int_h,count_h 
             mov count_l,#0
             mov count_h,#0            ;
       t_end:mov timcount,r0 
             setb tr1           ;重新开始定时操作
         reti
;  *****************  外部中断服务程序  ****************
ex_int0:
        inc  count_l            ;将中断缓冲区低地址加1
        mov a,count_l           ;判断是否有进位
        jnz int_end             ;没有则返回
        inc count_h             ;否则,将高地址加1
     int_end:  reti             ;中断返回
;***********************************
;*******   设置中断  ****************
pro_int0:
        clr c                   ;清进位标志
	    setb  it0               ;设置中断触发方式:脉冲触发
	    setb ea                 ;总的中断允许
	    setb ex0                ;允许外部中断EX0中断
	    clr ex1                 ;禁止外部中断EX1中断
       ret                      ;返回
; **********************************
ex_display:
           mov r0,#disstart     ;获得显示单元首地址
           mov r1,#01h          ;从第一个数码管开始
           mov r2,#06h          ;共显示6位数码管
           clr sege
     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        ; 重复显示下一个
           
           mov segdata,#0       ;不显示
           setb segb
           nop
           clr segb
           
           
         ret                    ;显示完成,返回

;ex_pro   数据处理,主要为 bcd码转换,查表
ex_pro:   clr ea
          setb psw.3            ;准备 寄存器 
          clr psw.4                     ;
          mov r6,int_h          ;得到高位数据
          mov r7,int_l          ;得到低位数据
         
          mov r0,#disstart      ;开始填充显示单元    
                
          mov a,r7              ;获得低3位数据
          mov b,#10             ;变换的原理是如果a=0xff(十六进制)
          div ab                ;那么就相当于255(十进制),每次除以10取余数就可以分开成三个2,5,5 
          mov r5,b              ;保存第一位(个位)
          mov b,#10
          div ab
          mov r4,b              ;十位
          mov r3,a              ;百位
          
          mov a,r5
          mov @r0,a
          
          inc r0          
          mov a,r4
          mov @r0,a
          
          inc r0          
          mov a,r3
          mov @r0,a 
          inc r0
          ;////////////////////////////////////////// 
          mov a,r6              ;获得高3位数据
          mov b,#10
          div ab
          mov r5,b              ;保存第一位(个位)
          mov b,#10
          div ab
          mov r4,b              ;十位
          mov r3,a              ;百位
          
          mov a,r5
          mov @r0,a
          
          inc r0          
          mov a,r4
          mov @r0,a
          
          inc r0          
          mov a,r3
          mov @r0,a           
          
          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          ;继续转换,直到完成
          setb ea
       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,#3
  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 + -