汇编课设电子琴

来源:互联网 发布:平面图制作软件cad 编辑:程序博客网 时间:2024/04/30 16:10
MY8255_A    EQU  0600HMY8255_B    EQU  0602HMY8255_C    EQU  0604H                                  MY8255_MODE EQU  0606HMY8254_MODE EQU  06C6HMY8254_A    EQU  06C0H   ;进行宏定义DATA  SEGMENTFREQ_LIST DW 441D,495D,556D,589D,661D,742D,833D,882D,262D,294D,330D,373D,402D,450D,494D,-1DDATA  ENDS     ;建立数据段CODE SEGMENT      ASSUME CS:CODE,DS:DATASTART: MOV AX,DATAMOV DS,AX       ;实现段寄存器DS的初始化    MOV DX,MY8255_MODEMOV AL,81HOUT DX,AL    ;写8255芯片的控制字,实现工作在方式0,A端口和B端口输出,C端口输入MOV DX,MY8254_MODEMOV AL,36HOUT DX,AL        ;使8254工作在方式3,A口输入,运用计数器0,二进制方式BEGIN: CALL CCSCAN     ;扫描JNZ INK1         ;有键按下时跳到INK1JMP BEGIN        ;没按下时循环执行BEGIN;确定按下键的位置INK1:   MOV CH,0FEH     ;确定按下键在第一列MOV CL,00H      ;将CL清零COLUM:  MOV AL,CH        MOV DX,MY8255_A ;将8255的A口地址赋给DXOUT DX,AL       ;将CPU中的AL值送到8255的A口中,即送到x1、x2、x3、x4中        MOV DX,MY8255_C ;将8255的C口地址赋给DXIN AL,DX        ;将C口的值送到AL中 L1:     TEST AL,01H     ;检验按下键是否在L1        JNZ L2          ;不是L1则跳到L2        MOV AL,00H      ;为了后面用来与FREQ_LIST数据段中数对应                                                                                     JMP KCODE       ;强制跳转到KCODEL2:     TEST AL,02H     ;检验按下键是否在L2         JNZ L3          ;不是L2则跳到L3        MOV AL,04H              ;为了后面用来与FREQ_LIST数据段中数对应。        JMP KCODE               ;强制跳转到KCODE        L3:     TEST AL,04H     ;检验按下键是否在L23        JNZ L4          ;不是L3则跳到L4        MOV AL,08H              ;为了后面用来与FREQ_LIST数据段中数对应。        JMP KCODE               ;强制跳转到KCODE        L4:     TEST AL,08H     ;检验按下键是否在L4          JNZ NEXT        ;不是L4则跳到NEXT        MOV AL,0CH              ;为了后面用来与FREQ_LIST数据段中数对应。KCODE:  ADD AL,CL       ;实现AL与CL的无进位加法        MOV DL,2D                              MUL DL          ;将AL乘以2结果保存到AX中        PLAY:   MOV SI,OFFSET FREQ_LIST ;使SI指向 FREQ_LIST的首地址        ADD SI,AX               ;通过SI加AX 实现指针SI的移动        MOV DX,0FH                             MOV AX,4240H            ;被除数为0F4240H        DIV WORD PTR[SI]        ;除数为SI所指的数据        MOV DX,MY8254_A         ;将8255的A口地址赋给DX        OUT DX,AL               ;输出商的低4位        MOV AL,AH        OUT DX,AL               ;输出商的高4位        MOV CX,8D               ;输入计数值CX        NEXT3: CALL DALLY              ;调用延时子程序DALLY       LOOP NEXT3                      ;CX不为0重复执行NEXT3          MOV DX,0FH                             MOV AX,4240H            ;被除数为0F4240H        MOV SI ,30D                            DIV WORD PTR[SI]        ;除数为SI=30所指的数据        MOV DX,MY8254_A         ;将8255的A口地址赋给DX        OUT DX,AL                               MOV AL,AH                              OUT DX,AL               ;实现静音,结束一个音符的发音        JMP BEGIN               ;跳转到BEGIN,重复扫描NEXT:   INC CL                  ;使CL加1,为了后面用来与FREQ_LIST数据段中数对应     MOV AL,CH                         TEST AL,08H                       JZ KERR                ;无键按下时跳转到KERR ROL AL,1D              ;向左移位 MOV CH,AL JMP COLUM              ;强制跳转到COLUMKERR:   JMP BEGIN               ;跳到BEGIN重新开始扫描;键盘扫描子程序CCSCAN: MOV AL,00H        MOV DX,MY8255_A   OUT DX,AL              ;使8255芯片A端口输出为0,既使x1、x2、x3、X4为0        MOV DX,MY8255_C         IN  AL,DX               ;将从C端口输入的y1、y2、y3、y4送到AL中NOT AL                  ;将AL取反        AND AL,0FH              ;将AL前4位清零RET;延时子程序DALLY:  PUSH CX                 ;将CX压栈        MOV CX,000FH                          T1:     MOV AX,0009FHT2:     DEC AX                  ;使AX减1JNZ T2                  ;AX不为0重复T2LOOP T1                 ;CX不为0重复T1POP CX                  ;将CX出栈RETCODEENDS                    ;代码段定义结束END START                       ;程序结束

音符

1

2

3

4

5

6

7

1

2

3

4

5

6

7

1

频率

131

147

165

175

196

220

247

262

294

330

349

392

440

494

523


0 0
原创粉丝点击