简易电子琴设计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1 设计任务描述
1.1设计题目:
简易电子琴设计
1.2设计内容
利用微机原理试验箱,设计简易电子琴,要求至少可以弹出7个音阶。
1.2.1设计目的
通过本学期对微机原理的学习,掌握的知识还停留在理论的上。但是这是一门实践性较强的课程,让学生在学完该课程之后,进行一次课程设计,使学生将课堂所学的知识和实践有机结合起来,初步掌握计算机应用系统设计的步骤和接口设计的方法,提高分析和解决实际问题的能力。
通过设计实践,培养学生查阅专业资料,工具书或参考书,了解有关工业标准,掌握现代设计手段和软件工具,并能以图纸和说明书表达设计思想和结果的能力。
通过设计,不但要培养和提高学生解决工程具体问题,动脑动手的技术工作能力,而且还要逐步建立科学正确的设计和科研思想,培养良好的设计习惯,牢固树立实事求是和严肃认真的工作态度。
1.2.2基本要求
1.可以弹出7个音阶。
2.弹奏简短音乐。
3.通过改变键盘输入来改变8254输出频率,实现扬声器发音
2 设计思路
通过8255和8254来实现电子琴模拟, 主要由两部分组成:第一部分为键盘扫描,用来确定按键位置,并给计数器赋初值。第二部分为发声部分,由计数器1#的输出端产生一定频率的方波驱动扬声器发声。
其中8254和课本中学的8253在原理上是一样的,它为可编程定时器/计数器。利用计数器0,并使它工作在方式3---输出对称方波,通过改变频率来实现不同的发声高低,再调用延时子程序来实现发音的长短,把输出方波送到扬声器,至此实现不同的音符发声。
过程中主要用到了8255芯片的PB
0—PB
4
,PA
—PA
4
它们分别与键盘单元的
X 1—X
4
,Y
1
—Y
4
相连,其中B口低4位为输出端,B口低4位1为输入端。由它们对
键盘单元进行扫描,并确定键值工作过程为:先给所有列线输入低电平,然后读取行线,检测行线是否为低电平,如果有某条行线输出低电平,则说明该键盘有按键被按下,否则,说明无按键被按下.采用这种方法可以快速判断键盘是否有键按下。在检查到有键按下后,再通过行扫描法判断按下的位置,从而确定按下的是什么键,经过计算得出计数器1#的初值。
3 设计原理流程图
4 实际硬件接线图
5 源程序清单及注释
MY8255_A EQU 0600H
MY8255_B EQU 0602H
MY8255_C EQU 0604H
MY8255_MODE EQU 0606H
MY8254_MODE EQU 06C6H
MY8254_A EQU 06C0H ;进行宏定义
DATA SEGMENT
FREQ_LIST DW 441D,495D,556D,589D,661D,742D,833D,882D
DW 262D,294D,330D,373D,402D,450D,494D,-1D
DATA ENDS ;建立数据段
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DS,AX ;实现段寄存器DS的初始化
MOV DX,MY8255_MODE
MOV AL,81H
OUT DX,AL ;写8255芯片的控制字实
现工作在方式0,A端口
和B端口输出,C端口
输入
MOV DX,MY8254_MODE
MOV AL,36H
OUT DX,AL ;使8254工作在方式3,
A口输入,运用计数器
0,二进制方式
BEGIN: CALL CCSCAN ;扫描
JNZ INK1 ;有键按下时跳到INK1
JMP BEGIN ;没键按下时循环执行
BEGIN
确定按下键的位置
INK1: CALL CCSCAN
JNZ INK2 ;有键按下时跳到INK2
JMP BEGIN ;没键按下时循环执行BEGIN INK2: MOV CH,0FEH ;确定按下键在第一列MOV CL,00H ;将CL清零
COLUM: MOV AL,CH
MOV DX,MY8255_A ;将8255的A口地址赋给DX
OUT DX,AL ;将CPU中的AL值送到8255
的A口中,即送到x1、x2、
x3、x4中
MOV DX,MY8255_C ; 将8255的C口地址赋给DX
IN AL,DX ;将C口的值送到AL中
L1: TEST AL,01H ;检验按下键是否在L1 JNZ L2 ;不是L1则跳到L2
MOV AL,00H ;为了后面用来与FREQ_LIST
数据段中数对应
JMP KCODE ;强制跳转到KCODE
L2: TEST AL,02H ;检验按下键是否在L2 JNZ L3 ;不是L2则跳到L3
MOV AL,04H ;为了后面用来与FREQ_LIST
数据段中数对应。
JMP KCODE ;强制跳转到KCODE
L3: TEST AL,04H ;检验按下键是否在L3 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 CALL DALLY
CALL DALLY