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

📄 pinglvji.asm

📁 采用1602显示的频率计,测量很准确.下载就可以用
💻 ASM
字号:
;频率计的程序
 ;包含:外部中断设置,中断服务程序,定时程序,定时服务程序
 ;以及数据处理,显示,包括 三位十进制数转化为四位BCD码,
 ;
 ;------------------------------------------------------------
        ;BEEP    BIT  P3.7
        LCD_RS  BIT  P3.7
        LCD_RW  BIT  P3.6
        LCD_EN  BIT  P2.0
        LCD_X   EQU  3FH         ;LCD 地址变量

        TIMER_H   EQU   30H     ;定时器高位字节单元
        TIMER_L   EQU   31H     ;定时器低位字节单元
        TIMCOUNT  EQU   32H     ;时间中断数


        INT_G     EQU   35H     ;中断计数缓冲单元高地址
      INT_H     EQU   34H     ;中断计数缓冲单元中地址
      INT_L     EQU   33H     ;中断计数缓冲单元低地址


        T_S       EQU   36H     ;数据显示低位
        T_M       EQU   37H     ;数据显示中位
        T_H       EQU   38H     ;数据显示高位
        T_G       EQU   39H     ;数据显示最高位

 ;----------------------------------------------------------
              ORG 0000H
              JMP MAIN             ;主程序开始
              ORG 000BH
              JMP TIMER_INT         ;定时器T0中断服务程序
              ORG  001BH            ;定时器T1中断服务程序
              JMP  TIMER1
              ORG  0030H
 ;----------------------------------------------------------
   MAIN:
            MOV  SP,#60H           ;设置SP指针
            LCALL PRO_SET          ;初始化
            CALL  SET_LCD
            LCALL TIM_T0
 ;-----------------------------------------------------------
 ;LCD1602是慢速显示器件,故100MS显示一次。
 ;-----------------------------------------------------------
MAIN1:
            MOV  R5,40
MAIN2:
            ACALL  DELAY1     ;3ms
            DJNZ  R5,MAIN2
            ACALL  SBIN_SBCD
            CALL  CONV
            JMP MAIN1
 ;------------------------------------------------------------
 ;T1计数器中断服务子程序
 ;计T1计数器溢出次数
 ;------------------------------------------------------------
TIMER1:
            INC  2AH
            RETI
 ;------------------------------------------------------------
 ;初始化程序
 ;------------------------------------------------------------
PRO_SET:  MOV A,#00H
          MOV B,#00H
          MOV  2AH,A
          MOV P0,#0FFH
          MOV P1,#0FFH
          MOV P2,#0FFH
          MOV INT_H,#00H
          MOV INT_L,#00H
          MOV  INT_G,#00H
          MOV  T_S,#00H
          MOV  T_H,#00H
          MOV  T_M,#00H
          MOV  T_G,#00H
          MOV TIMCOUNT,#00H
          MOV TIMER_H,#04CH       ;定时 50 MS
          MOV TIMER_L,#10H        ;
          ;CLR BEEP
          SETB  P3.5             ;P3.5端口置输入状态
          RET                    ;T1(TIMER1的外部输入脚)
 ;-----------------------------------------------------
 ;LCD 初始化设置
 ;-----------------------------------------------------
SET_LCD:
          CLR  LCD_EN
          CALL  INIT_LCD      ;初始化 LCD
          CALL  DELAY1
          MOV  DPTR,#INFO1    ;指针指到显示信息1
          MOV  A,#1           ;显示在第一行
          CALL  LCD_SHOW
          MOV  DPTR,#INFO2    ;指针指到显示信息2
          MOV  A,#2           ;显示在第二行
          CALL  LCD_SHOW
          RET
 ;-----------------------------------------------------
INFO1:  DB  "   PINGLVJI    ",0   ;LCD 第一行显示信息
INFO2:  DB  "FREQ:        HZ ",0   ;LCD 第二行显示信息
 ;-----------------------------------------------------
 ;LCD 接口初始化
 ;8位I/O控制
 ;-----------------------------------------------------
INIT_LCD:
          MOV  A,#38H      ;双列显示,字形5*7点阵
          CALL  WCOM
          CALL  DELAY1
          MOV  A,#38H      ;双列显示,字形5*7点阵
          CALL  WCOM
          CALL  DELAY1
          MOV  A,#38H      ;双列显示,字形5*7点阵
          CALL  WCOM
          CALL  DELAY1
          MOV  A,#0CH      ;开显示,关光标,
          CALL  WCOM
          CALL  DELAY1
          MOV  A,#01H      ;清除 LCD 显示屏
          CALL  WCOM
          CALL  DELAY1
          RET
 ;----------------------------------------------------
LCD_SHOW:        ;在LCD的第一行或第二行显示信息字符

          CJNE  A,#1,LINE2   ;判断是否为第一行
  LINE1:  MOV  A,#80H        ;设置 LCD 的第一行地址
          CALL  WCOM         ;写入命令
          CALL  CLR_LINE     ;清除该行字符数据
          MOV  A,#80H        ;设置 LCD 的第一行地址
          CALL  WCOM         ;写入命令
          JMP  FILL
  LINE2:  MOV  A,#0C0H       ;设置 LCD 的第二行地址
          CALL  WCOM         ;写入命令
          CALL  CLR_LINE     ;清除该行字符数据
          MOV  A,#0C0H       ;设置 LCD 的第二行地址
          CALL  WCOM
  FILL:   CLR  A             ;填入字符
          MOVC  A,@A+DPTR    ;由消息区取出字符
          CJNE  A,#0,LC1     ;判断是否为结束码
          RET
  LC1:    CALL  WDATA        ;写入数据
          INC  DPTR          ;指针加1
          JMP  FILL          ;继续填入字符
          RET
 ;---------------------------------------------------
CLR_LINE:                   ;清除该行 LCD 的字符
          MOV  R0,#24
   CL1:   MOV  A,#' '
          CALL  WDATA
          DJNZ  R0,CL1
          RET
 ;-----------------------------------------------------
 ; 写指令、数据使能子程序
 ;-----------------------------------------------------
ENABLE:                     ;写指令使能
          CLR LCD_RS            ;RS=L,LCD_RW=L,D0-D7=指令码,E=高脉冲
          CLR LCD_RW
          SETB LCD_EN
          CALL  DELAY0
          CLR LCD_EN
          RET
ENABLE1:                   ;写数据使能
          SETB  LCD_RS         ;RS=H,RW=L,D0-D7=数据,E=高脉冲
          CLR   LCD_RW
          SETB  LCD_EN
          CALL  DELAY0
          CLR   LCD_EN
          RET

DELAY0:   MOV  R7,#250       ;延时500微秒
          DJNZ  R7,$
          RET
 ;----------------------------------------------------
 ;写入命令子程序
 ;----------------------------------------------------
WCOM:                      ;以8位控制方式将命令写至LCD
          MOV  P1,A        ;写入命令
          CALL  ENABLE
          RET
 ;----------------------------------------------------
 ;写入数据子程序
 ;----------------------------------------------------
WDATA:                     ;以8位控制方式将数据写至LCD
          MOV  P1,A        ;写入数据
          CALL  ENABLE1
          RET
 ;---------------------------------------------------
 ;在 LCD 第二行显示字符
 ;A=ASC DATA, B=LINE X POS
 ;---------------------------------------------------
LCDP2:                     ;在LCD的第二行显示字符
          PUSH  ACC         ;
          MOV  A,B          ;设置显示地址
          ADD  A,#0C0H      ;设置LCD的第二行地址
          CALL  WCOM        ;写入命令
          POP  ACC          ;由堆栈取出A
          CALL  WDATA       ;写入数据
          RET
 ;-------------------------------------------------------
 ;ASCII 转换并在第二行显示数字子程序
 ;-------------------------------------------------------
CONV:     ; MOV  A,T_G
          MOV  LCD_X,#6           ;设置位置
          ; CALL  SHOW_DIG2
          MOV  A,T_H
           ;INC  LCD_X              ;加载小时数据
          CALL  SHOW_DIG2     ;显示数据
          MOV  A,T_M          ;加载分钟数据
          INC  LCD_X              ;设置位置
          CALL  SHOW_DIG2     ;显示数据
          MOV  A,T_S         ;加载秒数数据
          INC  LCD_X              ;设置位置
          CALL  SHOW_DIG2     ;显示数据
          RET
 ;----------------------------------------------------
SHOW_DIG2:
          MOV  B,#16
          DIV  AB
          ADD  A,#30H
          PUSH  B
          MOV  B,LCD_X
          CALL  LCDP2
          POP  B
          MOV  A,B
          ADD  A,#30H
          INC  LCD_X
          MOV  B,LCD_X
          CALL  LCDP2
          RET
 ;-----------------------------------------------------
DELAY1:                     ;延时3MS
         MOV  R6,#15
  D2:    MOV  R7,#100
         DJNZ  R7,$
         DJNZ  R6,D2
         RET
 ; -----------------  定时器设置   ------------------------
 ;设置定时器0工作在定时方式1,定时器1工作在计数方式1
 ;---------------------------------------------------------
TIM_T0:   MOV TMOD,#0D1H
          MOV TH0,TIMER_H         ;设置定时初值高位
          MOV TL0,TIMER_L         ;设置定时初值低位
          MOV  TH1,#00H           ;清T1计数器
          MOV  TL1,#00H
          MOV  IE,#8AH            ;开中断总允许,允许T0溢出中断
          SETB  PT1
          SETB  TR1
          SETB  TR0               ;定时器开始工作
          RET
 ;--------------------------------------------------------
 ;定时器0中断服务程序
 ;--------------------------------------------------------
TIMER_INT:
         CLR TR0              ;关闭定时器
         MOV TL0,TIMER_L      ;重新赋初值
         MOV TH0,TIMER_H                  ;
         INC TIMCOUNT         ;定时1S,时间单位
         MOV A,TIMCOUNT       ;查看数量值
         CPL  P1.4            ;产生自测信号
         CJNE A,#20,T_END     ;如果没有到1S返回

         CLR  TR1             ;关闭计数器T1
         MOV TIMCOUNT,#00H    ;到1S则清零
         MOV INT_L,TL1        ;取出计数值低位
         MOV INT_H,TH1        ;取出计数值高位
         MOV INT_G,2AH        ;取出溢出计数值位
         MOV  TH1,#00H
         MOV  TL1,#00H
         MOV  2AH,#00H
         SETB  TR1
T_END:   SETB TR0             ;重新开始定时操作
         RETI
 ;---------------------------------------------------------------
 ;三字节二进制整数转换成四字节BCD码子程序
 ;二进制数从低位到高位分别存放在INT_L、INT_H、INT_G单元中
 ;BCD码从低位到高位分别存放在T_S、T_M、T_H、T_G 单元中
 ;---------------------------------------------------------------
 SBIN_SBCD:
              PUSH PSW
              SETB PSW.3        ;设置当前寄存器
              CLR PSW.4

              CLR A             ;清累加器
              MOV T_G,A
              MOV T_H,A         ;清除出口单元,准备转换
              MOV T_M,A
              MOV T_S,A

              MOV  R5,INT_G
              MOV  R7,INT_L     ;设置二进制数起始地址
              MOV  R6,INT_H
              MOV  R2,#24
              CLR  C
HH1:
              MOV  A,R7
              RLC  A
              MOV  R7,A

              MOV  A,R6
              RLC  A
              MOV  R6,A

              MOV  A,R5
              RLC  A
              MOV  R5,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        ;累加
              DA  A
              MOV T_H,A         ;保存

              MOV A,T_G         ;得到第四位
              ADDC A,T_G        ;累加
               ;DA  A
              MOV T_G,A

              DJNZ R2,HH1       ;
              POP  PSW
              RET
 ;----------------------------------------------------------------
  END      ;告诉编译器本程序到此结束。
 ;-----------------------------------------------

⌨️ 快捷键说明

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