找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 806|回复: 3
打印 上一主题 下一主题
收起左侧

我想用4乘4矩阵键盘,LCD1602,蜂鸣器实现单片机电子琴但是中断有问题麻烦大家看看

[复制链接]
跳转到指定楼层
楼主
ID:1027053 发表于 2022-5-17 16:26 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  1.      RS EQU P2^6
  2.          RW EQU P2^5
  3.          E EQU P2^7
  4.          LCD EQU P0
  5.          BF EQU P0^7  
  6.          ORG 0000H
  7.      LJMP INIT
  8.          ORG 000BH
  9.          LJMP MAIN
  10.      ORG 0060H
  11.          ;初始化
  12. INIT:
  13.      CLR P2^7// 使能清0
  14.      MOV R0,#0
  15.          MOV R1,#0
  16.          MOV R0,#38H         //设置16乘2显示,5乘7点阵,8位数据接口
  17.          ACALL WRITE_COM
  18.          MOV R0,#0
  19.          MOV R0,#0CH        //设置开显示,不显示光标
  20.          ACALL WRITE_COM
  21.          MOV R0,#0
  22.          MOV R0,#06H  // 写一个字符后地址指针加1
  23.          ACALL WRITE_COM
  24.          MOV R0,#0
  25.          MOV R0,#01H   //显示清0,数据指针清0
  26.          ACALL WRITE_COM
  27.          RET
  28.          ;写指令函数,调用前先把指令码放到R0中
  29. DELAY:
  30. MOV R6,#5
  31. W2:MOV R7,#239
  32. W1:DJNZ R7,W1
  33.    DJNZ R6,W2
  34.    RET
  35. WRITE_COM:
  36.   CLR P2^6//RS清0
  37.   MOV P0,R0        //R0中放指令代码
  38.   ACALL DELAY
  39.   SETB P2^7//使能置1
  40.   ACALL DELAY
  41.   CLR P2^7
  42.   RET
  43.   ;写数据函数,调用前先把指令放到R1中
  44. WRITE_DATA:
  45.   SETB P2^6
  46.   MOV P0,R1
  47.   ACALL DELAY
  48.   SETB P2^7
  49.   ACALL DELAY
  50.   CLR P2^7
  51.   RET   
  52. MAIN:MOV SP,#70H
  53.      MOV TMOD,#11H //定时器初始化
  54.          SETB EA
  55.          SETB ET0
  56.          MOV  DPTR,#TAB
  57.          CLR A
  58.          ACALL INIT
  59.          MOV R0,#80H//定位到第一行
  60.          ACALL WRITE_COM
  61.          ACALL DELAY
  62.          ACALL KEYSCAN
  63.          JMP $
  64.          ;线反转法找被按下的键
  65. KEYSCAN:
  66.      MOV P1,#0F0H        //给P1赋值,为了读列线
  67.          MOV A,P1                                 //此时按键的状态
  68.          ANL A,#0F0H                  //与
  69.          //  找出被按下的列线
  70.          JNZ DELAY10MS
  71. DELAY10MS:   ;误差 0us
  72.     MOV R7,#01H
  73. DL1:
  74.     MOV R6,#26H
  75. DL0:
  76.     MOV R5,#82H
  77.     DJNZ R5,$
  78.     DJNZ R6,DL0
  79.     DJNZ R7,DL1
  80.     RET          //延时去抖
  81.           MOV A,P1
  82.           ANL A, #0F0H
  83.           MOV R0,A                                             //此时列线状态记录在R0
  84.           JNZ KEYSCAN1                                                                                         
  85.           LJMP KEYSCAN
  86. KEYSCAN1:
  87.       MOV A,#00H                                 //清零
  88.           MOV P1,#0FH                 //置位读行线
  89.           MOV A ,P1                         //此时按键的状态
  90.           ANL A ,#0FH
  91.           MOV R1,A                                //此时行线状态记录在R1
  92.           ANL A ,#0FH
  93.           JNZ NUM
  94.           LJMP KEYSCAN
  95. NUM:
  96.           MOV A ,R0
  97.           MOV B,R1
  98.           ORL A,B//A或上B,数据保存在A
  99.           SJMP DISP0
  100. DISP0:
  101.      CJNE A,#0EEH,DISP1
  102.          MOV A ,#01H
  103.          MOVC A ,@A+DPTR
  104.          MOV P0,A//LCD1602显示屏输出音律
  105.          ACALL WRITE_DATA
  106.          ACALL DELAY
  107.          MOV TL0,#22H
  108.          MOV TH0,#0FEH
  109.          LCALL DELAY1
  110.          LCALL SOUND
  111.          LJMP KEYSCAN
  112. DISP1:
  113.     CJNE A ,#0EDH,DISP2
  114.         MOV A ,#02H
  115.         MOVC A,@A+DPTR
  116.         MOV P0,A
  117.         ACALL WRITE_DATA
  118.         ACALL DELAY
  119.         MOV TL0,#4FH
  120.         MOV TH0,#0FEH
  121.         LCALL DELAY1
  122.         LCALL SOUND
  123.         LJMP KEYSCAN
  124. DISP2:
  125.    CJNE A ,#0EBH,DISP3
  126.    MOV A ,#03H
  127.    MOVC A ,@A+DPTR
  128.    MOV P0,A
  129.    ACALL WRITE_DATA
  130.    ACALL DELAY
  131.    MOV TL0,#85H
  132.    MOV TH0,#0FEH
  133.    LCALL DELAY1
  134.    LCALL SOUND
  135.    LJMP KEYSCAN
  136. DISP3:
  137.    CJNE A,#0E7H,DISP4
  138.    MOV A,#04H
  139.    MOVC A ,@A+DPTR
  140.    MOV P0,A
  141.    ACALL WRITE_DATA
  142.    ACALL DELAY
  143.    MOV        TL0,#9AH
  144.    MOV  TH0,#0FEH
  145.    LCALL DELAY1
  146.    LCALL SOUND
  147.    LJMP KEYSCAN
  148. DISP4:
  149.    CJNE A,#0DEH,DISP5
  150.    MOV A, #05H
  151.    MOVC A ,@A+DPTR
  152.    MOV P0,A
  153.    ACALL WRITE_DATA
  154.         ACALL DELAY
  155.    MOV TL0,#0C1H
  156.    MOV TH0,#0FEH
  157.    LCALL DELAY1
  158.    LCALL SOUND
  159.    LJMP KEYSCAN
  160. DISP5:
  161.    CJNE A,#0DDH,DISP6
  162.    MOV A ,#06H
  163.    MOVC A ,@A+DPTR
  164.    MOV P0,A         
  165.    ACALL WRITE_DATA
  166.         ACALL DELAY
  167.    MOV TL0,#0E4H
  168.    MOV TH0,#0FEH
  169.    LCALL DELAY1
  170.    LCALL SOUND
  171.    LJMP KEYSCAN
  172. DISP6:
  173.    CJNE A,#0DBH,KEY
  174.    MOV A ,#07H
  175.    MOVC A ,@A+DPTR
  176.    MOV P0,A
  177.    ACALL WRITE_DATA
  178.         ACALL DELAY
  179.    MOV TL0,#03H
  180.    MOV TH0,#0FFH
  181.    LCALL DELAY1
  182.    LCALL SOUND
  183.    LJMP KEYSCAN
  184. DELAY1:MOV R2,#0FH
  185. LOOP10:MOV R3,0FAH
  186. LOOP20:DJNZ R3,LOOP20
  187.        DJNZ R2,LOOP10
  188.          RET
  189. SOUND:
  190.      SETB TR0
  191.          SETB P3^0 //输出高电平,开始鸣叫
  192.          MOV R4,#4H
  193. LOOP:MOV R3,#0F9H
  194. LOOP1: DJNZ R3,LOOP1
  195.        DJNZ R4,LOOP
  196.            CLR P3^0        //输出低电平,停止鸣叫
  197.            RETI
  198. KEY:LJMP MAIN

  199.          
  200. TAB:DB 31H,32H,33H,34H,35H,36H,37H
  201.            END
复制代码


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:624769 发表于 2022-5-18 00:07 | 只看该作者

  •          ORG 0000H
  •      LJMP INIT
  •          ORG 000BH
  •          LJMP MAIN

开头看了这4行,我就有不祥的预感……

再往下一核对……,稍微找了一下。
  • MAIN:MOV SP,#70H
  •      MOV TMOD,#11H //定时器初始化
  •          SETB EA
  •          SETB ET0
  •          MOV  DPTR,#TAB
  •          CLR A
  •          ACALL INIT
  •          MOV R0,#80H//定位到第一行
  •          ACALL WRITE_COM
  •          ACALL DELAY
  •          ACALL KEYSCAN
  •          JMP $

看到这里,我确定了,这代码不用看了。 你如果不是疏忽,就不要学汇编了。汇编不适合你。
难怪没人回复,我也不知道怎么回复了,改用 C 吧,或者汇编从最基本的开始重新回炉学吧……
回复

使用道具 举报

板凳
ID:123289 发表于 2022-5-18 17:28 | 只看该作者
1、先画出逻辑框图,走通框图后,再写程序。
2、搞清楚各中断入口地址。
问题1:
程序开始后,直接转入INIT,INIT的未句是 RET,执行RET时,程序就跑飞了。
RET 指令是从SP所指的位置中取运行地址。开机时SP=07,即RET的返回地址在[07H][06H]中,
这时你的[07H][06H]中放的是什么里?没有给出,很随机,所以程序飞了。
即使侥幸放的是0000,返回0000运行,又会执行到RET,而这时SP已于上次RET时-2了,即SP=05,于是又从[05H][06H]中,取地址运行,如此下去必跑飞,死机。
问题2:
不要用DELAY,它占用CPU的时间!在DELAY时CPU不能干其它活。
……
回复

使用道具 举报

地板
ID:73992 发表于 2022-5-20 23:32 来自手机 | 只看该作者
我觉得程序写的很好,写程序是为了达到创意。程序格式是有点问题,不用气馁慢慢修改渐渐就会了。org0000h  ljmp main 意思是程序开始后跳转到主程序 org 000bh ljmp init 意思是如果t0溢出则跳转到init子程序,org 0060h 意思是程序从60h开始写。中断子程序init  返回不用ret
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表