微机原理课设_微机原理课设大全
微机原理课设由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“微机原理课设大全”。
微机应用系统设计与综合专业班级学生姓名学生学号指导老师实验课程设计
——信号发生器功能程序设计
第一章
设计课题概述
本学期开设的《微型计算机原理与接口技术》理论课程是一门专业基础课程,1.1 课程设计目的它的主要内容包括微型计算机体系结构、8086 微处理器和指令系统、汇编语言设计以及微型计算机各个组成部分介绍等内容。要求学生对微机原理中的基本概念有较深入的了解,能够系统地掌握微型计算机的结构、8086 微处理器和指令系统、汇编语言程序设计方法、微机系统的接口电路设计及编程方法等,并具有综合运用所学知识分析问题和解决问题的能力。
《微机应用系统设计与综合实验(实践)》课程设计,让学生对微机系统有一个较全面的理解,掌握常规的芯片使用方法、掌握简单的微型计算机应用系统软硬件的设计方法,对典型数字接口电路的应用技术有一个较深入的掌握,并对应用系统进行硬件原理和软件编程进行分析、设计和调试,达到基本掌握简单微型计算机应用系统软硬件的设计方法,提高项目开发能力的目的。课程中要求学生根据课程设计指导书来选择课题,并且独立完成课题,写出课程设计说明书,画出电路原理图,说明工作原理,画出电路板图,编写程序以及程序流程图。
针对《信号发生器功能程序设计》这一课题,主要涉及到硬件的连接(主要用到芯片有:8086CPU,DAC0832,8255,74LS273,74LS138,运放等)以及数码管,键盘矩阵硬件,示波器等连接原理图,程序的编写(主要涉及到显示波形,数码管显示以及通过小键盘来对波形进行选择控制)以及各个子程序或程序段的程序流程等,通过课程设计不仅可以锻炼学生在微机应用方面的实际工作能力,将所学转化为所用,更是一个锻炼解决实际问题能力的很好机会。
1.2 课程设计要求
(1)、分别用C语言和汇编语言编程完成硬件接口功能设计;(2)、硬件电路基于80x86微机的接口电路;
(3)、程序功能要求:小键盘给定、数码管(屏幕)显示,并产生对应信号波形(D/A)输出(信号波形包括正弦波、三角波、方波、锯齿波)、输出信号波形幅度、频率可调。(注意:按键数量应尽量少)。
实现技术指标
(1)、完全用小键盘控制各波形间的切换和频率和幅值的调节以及退出。(2)、实现正弦波、三角波、方波和锯齿波信号的产生。(3)、数码管同步显示当前工作波形的频率和幅值。(4)、实现频率的1到5倍可调。(5)、实现幅值的1到5倍可调。
使用说明
(1)、小键盘第一列对应0-3,第二列对应4—7。
(2)、开始选择0—3分别对应方波,三角波,锯齿波,正弦波。同时数码管会显示当前波形的幅值和频率。
(3)、有波形产生以后,再调节幅值和频率。0对应增大频率,1对应减小频率,2对应减小幅值,3对应增大幅值。
(4)、频率和幅值可以实现1到5倍可调,同时数码管会显示当前波形的幅值和频率的倍数(1~5)。
(5)、任何时候4都对应退出,回到最开始的选择波形状态,数码管归零。
第二章 设计思想和实施方案
2.1功能分析
2.1.1波形产生
由于要由数字信号转换为模拟信号来产生波形,因此要由D/A转换芯片DAC0832来完成此项任务。通过汇编语言编写各个波形子程序,由于要显示波形,所以每输出一个值,都要进行一定时间的延时,扫描没有按键按下后再输出下一个值,直到形成一个周期的代码。利用循环,就可产生连续波形代码,再通过8255输出给DAC0832,将数字量转换成模拟量输出,即可得各种波形。具体方案在后面有分析。
2.1.2波形切换
波形的选择和调节由小键盘控制。第一列从上到下编码为0,1,2,3,分别对应方波、三角波、锯齿波、正弦波。第二列第一个键的键值为4,对应退出波形,可以重新选择波形,实现波形切换。当没有输出波形的时候,也就是输出为零,选择0到3就会进入相应的波形子程序。进入波形子程序以后,每一个点输出之前都会调用扫描子程序,判断是否有键按下,有则跳转到相应的程序断去执行,无则继续。由于小键盘扫描在程序总是存在的,因此可随时进行波形间的切换。
2.1.3 数码管显示
数码管同步显示当前波形的幅值和频率。硬件上由8086将数据输出给8255,8255再将输出送给数码管的A~Dp,显示相应字符。软件上定义一个缓冲区存放波形的幅值和频率,显示数码管时,利用缓冲区的数值查找数码管键值表再输出对应数值。循环输出波形时也循环输出缓冲区内容对应的值,就可以同步显示波形的幅值和频率。利用小键盘扫描得到的键值进行判断,对缓冲区内的幅值频率进行相应的改变,使数码管能显示不同的幅值和频率。
2.1.4小键盘控制
使用实验箱上4×4键盘,可以实现切换波形,调频、调幅和退出波形的控制功能。Protues内的键盘矩阵扫描时轮流选通一行,然后从端口处读取列数据,如果有按键则读取的数据肯定有一位为0,经过取反后,尽有一位为1,然后再根据选取的列和读取的行值,确定按的是哪一个键,然后将键值编码保存在一个名为keya的存储单元里。当有键按下时,从keya内取出键值进行判断,就能转入相应的子程序进行控制,并且键盘扫描、获取键值等子程序也能够很好的嵌入在其他程序中,方便调用。
2.1.5有极调频
改变波形子程序中的各个数据输出时间,即延时,就可改变整个波形的频率。延时越短频率越高。定义三个缓冲区来存放延时,其中一个存放初始值3,一个存放当前波形的延时,还有一个作为中间暂存用。产生波形以后,取出延时初值存入中间暂存缓冲区,再扫描键盘:0对应减小延时,1对应增大延时,无键则不改变延时。对暂存区的数值进行相应操作后,将最后的值存入名为tiaopin的缓冲区内作为当前波形的延时。
2.1.6有极调幅
和有级调频类似,有极调幅也是定义三个缓冲区,功能和有极调频类似。幅值缓冲区存放的是输出点的值的放大倍数,调节放大倍数也就使幅值改变了。产生波形以后,取出倍数初值存入中间暂存缓冲区,再扫描键盘:2对应减小倍数,3对应增大倍数,无键则不改变倍数。对暂存区的数值进行相应操作后,将最后的值存入名为tiaofu的缓冲区内作为当前波形的幅值放大倍数。
2.1.6开始结束
用小键盘第二列第一个也就是4来结束波形,无论在什么时候只在小键盘扫描到了4键,它就会无条件跳出程序,返回起始状态,等待选择波形,同时数码管显示零。
2.2所用芯片功能简介
2.2.1 8086功能简介
8086 CPU是由总线接口部件BIU和执行部件EU这两大部分构成。总线接口部件BIU是8086 CPU在存储器和I/O设备之间的接口部件,负责对全部引脚的操作,即8086对存储器和I/O设备的所有操作都是由BIU完成的。所有对外部总线的操作都必须有正确的地址和适当的控制信号,BIU中的各部件主要是围绕这个目标设计的。它提供了16位双向数据总线、20位地址总线和若干条控制总线。
其具体任务是:负责从内存单元中预取指令,并将它们送到指令队列缓冲器暂存。CPU执行指令时,总线接口单元要配合执行单元,从指定的内存单元或I/O端口中取出数据传送给执行单元,或者把执行单元的处理结果传送到指定的内存单元或I/O端口中。
执行单元EU中包含1个16位的运算器ALU、8个16位的寄存器、1个16位标志寄存器FR、1个运算暂存器和执行单元的控制电路。这个单元进行所有指令的解释和执行,同时管理上述有关的寄存器。EU对指令的执行是从取指令操作码开始的,它从总线接口单元的指令队列缓冲器中每次取一个字节。如果指令队列缓冲器中是空的,那么EU就要等待BIU通过外部总线从存储器中取得指令并送到EU,通过译码电路分析,发出相应控制命令,控制ALU数据总线中数据的流向。
管脚图如下:
2.2.2 8255A功能简介
8255A具有24条输入/输出引脚、可编程的通用并行输入/输出接口电路。它是一片使用单一+5V电源的40脚双列直插式大规模集成电路。8255A的通用性强,使用灵活,通过它CPU可直接与外设相连。
8255A在使用前要写入一个方式控制字,选择A、B、C三个端口各自的工作方式,共有三种。方式0 :基本的输入输出方式,即无须联络就可以直接进行的 I/O方式。其中A、B、C口的高四位或低四位可分别设置成输入或输出;方式1 :选通I/O,此时接口和外围设备需联络信号进行协调,只有A口和B口可以工作在方式1,此时C口的某些线被规定为A口或B口与外围设备的联络信号,余下的线只有基本的I/O功能,即只工作在方式0;方式2: 双向I/O方式,只有A口可以工作在这种方式,该I/O线即可输入又可输出,此时C口有5条线被规定为A口和外围设备的双向联络线,C口剩下的三条线可作为B口方式1的联络线,也可以和B口一起方式0的I/O线。
管脚图如下:
2.2.3 DAC0832功能简介
DAC0832是采用CMOS工艺制成的单片电流输出型8位数 / 模转换器。它由倒T型R-2R电阻网络、模拟开关、运算放大器和参考电压VREF四大部分组成。电路有极好的温度跟随性,使用了COMS电流开关和控制逻辑而获得低功耗、低输出的泄漏电流误差。集成电路内有两级输入寄存器,使DAC0832芯片具备双缓冲、单缓冲和直通三种输入方式,以便适于各种电路的需要.DAC0832有8个输入端(其中每个输入端是8位二进制数的一位),有一个模拟输出端。输入可有2的8次方,即256个不同的二进制组态,输出为256个电压之一,即输出电压不是整个电压范围内任意值,而只能是256个可能值。
D/A转换结果采用电流形式输出。若需要相应的模拟电压信号,可通过一个高输入阻抗的线性运算放大器实现。运放的反馈电阻可通过RFB端引用片内固有电阻,也可外接。DAC0832逻辑输入满足TTL电平,可直接与TTL电路或微机电路连接。
DAC0832的管脚图如下:
2.2.4 74LS273功能简介
地址锁存器就是一个暂存器,它根据控制信号的状态,将总线上地址代码暂存起来。8086/8088数据和地址总线采用分时复用操作方法,即用同一总线既传输数据又传输地址。当微处理器与存储器交换信号时,首先由CPU发出存储器地址,同时发出允许锁存信号ALE给锁存器,当锁存器接到该信号后将地址/数据总线上的地址锁存在总线上,随后才能传输数据。
地址锁存器74LS273是带清除端的八D触发器,只有清除端为高电平时才具有锁存功能,锁存控制端为11脚CLK,在上升沿锁存。8086的ALE端输出的锁存控制信号必须经反相器后才能连到74LS273的CLK端,以满足CLK在上升沿锁存的要求。74LS273的引脚1D~8D为数据输入端,1Q~8Q为数据输出端,WR:主清除端,低电平触发,即当为低电平时,芯片被清除,输出全为0。CP(CLK):触发端,上升沿触发,即当CP从低到高电平时,D0~D7的数据通过芯片,为0时将数据锁存,D0~D7的数据不变。由于8086有20位物理地址,所以需要用3片74LS273级联。
74LS273的管脚图如右:
2.3 实施方案
2.3.1系统总体设计方案
该设计包括硬件设计和软件设计两部分。
1.硬件上要求以8086CPU为核心进行电路设计。完全用小键盘对波形进行控制。小键盘作为产生波形、波形切换、调节频率,调节幅值、退出波形的控制端口。8255A芯片完成对小键盘扫描,获取键值编码以及输出到数码管。通过DAC0832将数字量转换成模拟量输出,再由转换电路将电流输出转换为电压输出产生各种波形,通过虚拟示波器显示出波形。由于8255A的A,B,C端口都已使用,所以采用键盘控制进行幅值和频率的有极调节。
2.软件方面要设计方波,三角波,锯齿波,正弦波何时产生,如何产生,何时退出,并且还要设计如何通过对按键的判断,对频率和幅值进行调节。
方波比较简单,先扫描键盘,无键按下时输出零,保持一个延时,再扫描键盘,无键按下时输出20H的倍数,该倍数就是我定义的幅值,再延时,循环该周期就可得到方波。如果有键按下就会转入相应子程序。
三角波分为两段,因它的上升斜坡和下降斜坡都是线性关系,所以只要由数字量的增减来控制就可以了。产生上升斜坡时让输出值从零开始逐渐递增,其上升的最大值是30乘以放大倍数,相反,产生下降斜坡时,让输出值从最大值逐渐递减到零。为简单起见,这里采用的是查表法,在数据段定义了三角波函数表,规律如上。其幅值由放大倍数控制,频率是由输出点之间的延时来控制。
锯齿波截取三角波的上升斜坡部分,到达最大值后就跳回最低值0,方法与三角波相同,也采用查表法。先定义了锯齿波的函数表,输出时只要按着函数表一个一个往下输出,当显示到最大值即一个周期内的最后一个值再将指针指向表的首地址就开始了新的周期。其幅值由放大倍数控制,频率是由输出点之间的延时来控制。
正弦波也是用的查表法。该方法的优点是速度快,但在精度高的情况下要求的存储器容量也要增大,所以此种方法应用在对精度要求不高的场合。本程序中制造了一张正弦数字量表,即查函数表得到的值转换成十进制数填表。一个周期内,采样点越多,精度越高,本实验中采样点为40点/周期。正弦数字量表中的值为参考值,对于不同幅值的正弦波可以通过把表中的每个值乘以相同的倍数得到,其频率由改变输出点之间的延时来实现。
频率和幅值的调节由每个点的延时和幅值的放大倍数决定。在各个波形输出之前,先读取频率和幅值的初值,若要增加(减小)频率,则使延时减(加)1;若要增大(减小)幅值,则使原幅值基础值得放大倍数加(减)1。然后再将改变后的幅值频率送给原波形进行输出,同时,幅值和频率的值作为偏移量查找数码管显示表,然后送给对应的数码管显示。
2.3.2系统设计方框图
第三章 典型程序模块及编程技巧分析
3.1键盘扫描模块
小键盘工作原理:
(1)初始化8255的工作方式:A,B口作为输出,C口低四位作为输入。矩阵的X1~X4接到输出端口PA0-PA3上,用程序控制4条行线的输出。4条列线Y1~Y4连接到输入端口C的PC0-PC3。用读指令读取C口状态时,可读取键盘的列号。
(2)在无键按下的时候,由于接到+5V上的上拉电阻的作用,列线被置成高电平。压下某一个键所在的行线和列线接通。这时,如果向被压下的键所在的行线上输出一个低电平信号,则对应的列线也呈现低电平。当从C口读取列线信号时,便能检测到该列线上的低电平。
(3)扫描键盘时,A口输出全0,读C口,取低四位再取反,若为0则无键输入,若不为零则转获取键值子程序。获取键值时,对X1到X4轮流选中,即轮流输出0。先把第一行赋0,读C口检测是不是第一行,不是再继续第二行,没有的话总共循环4次跳出循环,这样根据选中的行和读入的列状态中低电平的位置,便能确定哪个键被按下了。检测到按键后,对压下的键进行编码,将该键的行列信号转化成16进制码,将键值存入缓冲区,以便以后利用进行判断比较。接着继续扫描按键,等待按键释放。
具体的实现如下:
CCSCAN扫描按键是否有键按下: CCSCAN PROC
NEAR
;扫描是否有按键闭合子程序
MOV
AL,00H
MOV
DX,MY8255_A;将4列全选通,X1~X4置0
OUT
DX,AL
MOV
DX,MY8255_C
IN
AL,DX
;读Y1~Y4
NOT
AL
AND
AL,0FH
;取出Y1~Y4的反值
RET
CCSCAN ENDP
如果有按键,就获取按键码的功能,4×4键盘的编码, 从上到下,从左到右,依次编码为0~F, 如果有按键, 则转入到按键处理子程序模块执行, 如果没有,则返回主程序循环。具体的实现代码如下:
GETKEY1 PROC
NEAR
;获取键值子程序
CALL
DIS
;显示刷新
CALL
DALLY
;延时
CALL
DALLY
;延时
CALL
CLEAR
;清屏
CALL
JNZ
JMP
GETKEY2: MOV
MOV
COLUM: MOV
MOV
OUT
MOV
IN
L1: TEST
JNZ
MOV
JMP
L2: TEST
JNZ
MOV
JMP
L3: TEST
JNZ
MOV
JMP
L4: TEST
JNZ
MOV
KCODE: ADD
CCSCAN
;再次扫描按键
GETKEY2
;有键按下则跳置GETKEY2 BEGIN1
;否则跳回开始继续循环
CH,0FEH
CL,00H
;设置当前检测的是第几列
AL,CH
;选取一列,将X1~X4中一个置0
DX,MY8255_A DX,AL
DX,MY8255_C;读Y1~Y4,用于判断哪一行按键闭合 AL,DX
AL,01H
;是否为第1行 L2
;不是则继续判断
AL,00H
;设置第1行第1列的对应的键值
KCODE
AL,02H
;是否为第2行 L3
;不是则继续判断
AL,04H
;设置第2行第1列的对应的键值
KCODE
AL,04H
;是否为第3行 L4
;不是则继续判断
AL,08H
;设置第3行第1列的对应的键值
KCODE
AL,08H
;是否为第4行 NEXT
;不是则继续判断
AL,0CH
;设置第4行第1列的对应的键值
AL,CL
;将第1列的值加上当前列数,确定按键值
CALL
PUTBUF
;保存按键值
PUSH
AX
KON: CALL
DIS
;显示刷新
CALL
CLEAR
;清屏
CALL
CCSCAN
;扫描按键,判断按键是否弹起
JNZ
KON
;未弹起则继续循环等待弹起
POP
AX
NEXT: INC
CL
;当前检测的列数递增
MOV
AL,CH
TEST
AL,08H
;检测是否扫描到第4列
JZ
KERR
;是则跳回到开始处
ROL
AL,1
;没检测到第4列则准备检测下一列
MOV
CH,AL
JMP
COLUM
KERR: RET
GETKEY1 ENDP PUTBUF PROC
NEAR
;保存键值子程序
MOV
DI,OFFSET KEY
MOV
[DI],AL
CMP
DI,2FFFH
JNZ
GOBACK
MOV
DI,3004H
GOBACK: RET
PUTBUF ENDP
3.2数码管显示模块
4个数码管的X端为选通端,将小键盘的X1~X4对应接到数码管,这样扫描小键盘的时候,也就选中了数码管,当调用getkey1获取键值子程序的时候,数码管轮流选中,也就可以控制哪个数码管显示什么内容。通过对8255写入数据,由B口输出给数码管的A~Dp,当没有波形输入时,数码管显示0数码管;定义两个缓冲区存放幅值和频率,有波形输出时,同步显示该波形的幅值和频率。
先在数据段定义一个缓冲区存放数码管显示0~F的段位值表: DTABLE DB
3FH,06H,5BH,4FH,66H,6DH,7DH,07H DB
7FH,6FH,77H,7CH,39H,5EH,79H,71H 因为要一直显示数码管,所以将显示部分作为子程序,方便经常调用。DIS PROC
NEAR
;显示键值子程序
AGAIN:
PUSH
AX
;以缓冲区存放的键值为键值表偏移找到键值
并显示
MOV
SI,3000H
;缓冲区3000H内存放了当前波形的幅
值,3001H存放了频率。
MOV
DL,0F7H MOV
AL,DL PUSH
DX MOV
DX,MY8255_A OUT
DX,AL
;设置X1~X4,选通一个数码管 MOV
AL,[SI]
;取出缓冲区中存放键值 MOV
BX,OFFSET DTABLE AND
AX,00FFH ADD
BX,AX MOV
AL,[BX]
;将键值作为偏移和键值基地址相加得到
相应的键值
MOV
DX,MY8255_B OUT
DX,AL
;写入数码管A~Dp CALL
DALLY INC
SI
;取下一个键值 POP
DX MOV
AL,DL TEST
AL,01H
;判断是否显示完? JZ
OUT1
;显示完,返回 ROR
AL,1 MOV
DL,AL
JMP
AGAIN
;未显示完,跳回继续
OUT1: POP
AX
RET
DIS ENDP 3.3有级调频调幅判断及控制模块
改变波形产生子程序中的各个数据输出时间,及延时,就可改变整个波形的频率。改变波形产生子程序中的每次输出数值的放大倍数,就可以改变整个波形的幅值。而实现有级变化的初值是在数据段预先定义的数据表。
在选择波形以后,才能调节频率和幅值,频率和幅值的调节由小键盘控制。在3000H和3001H的缓冲区内存放了幅值和频率的初值3,在每个波形输出之前先扫描键盘,键值存在KEY里,对KEY值进行判断后,取出缓冲区的初值做相应改变:0选择增大频率,1选择减小频率,2选择减小幅值,3选择增大幅值,4退出波形,返回开始状态。
具体的实现代码如下:
AMPLFENC PROC
NEAR
;调节幅值频率子程序
CALL
DIS
;刷新
CALL
CCSCAN
;再次扫描按键
JNZ
TRI1
;有键按下则跳置tri1
JMP
TRI5
;没按键按下就跳出该子程序
TRI1: CALL
DIS
;刷新
CALL
GETKEY1
MOV
SI,OFFSET KEY
MOV
AL,[SI]
CMP
AL,4
;第五个键就退出
JZ
TRI10
JZ
TRI5
CMP
AL,0
;第一个键减少周期
JNZ
TRI2
MOV
DI,3001H
;取延时初值
MOV
BL,[DI]
CMP
BL,01H
JE
TRI5
DEC
BL
MOV
[DI],BL
JMP
TRI5
TRI2: CMP
AL,1
;第二个键增加周期
JNZ
MOV
MOV
CMP
JE
INC
MOV
JMP
TRI3: CMP
JNZ
MOV
MOV
CMP
JE
DEC
MOV
JMP
TRI4: CMP
JNZ
MOV
MOV
CMP
JE
INC
MOV
JMP
TRI3
DI,3001H BL,[DI] BL,05H TRI5 BL [DI],BL TRI5
AL,2
TRI4 DI,3000H
BL,[DI]
BL,01H TRI5 BL [DI],BL TRI5
AL,3
TRI5 DI,3000H
BL,[DI]
BL,05H TRI5 BL [DI],BL TRI5
;取延时初值;第三个键减少幅度
;取幅值初值;第四个键增加幅度
;取幅值初值
TRI10: JMP
FAR PTR BEGIN0
TRI5: RET
AMPLFENC ENDP
3.4 波形切换及基本控制模块
这个模块是本次设计的主程序,它控制了波形的输出和切换。它是根据对小键盘的操作来实现的,不同按键对应的编码转入不同模块(0:方波,1:三角波,2:锯齿波,3:正弦波,4:退出波形)。先扫描键盘是否有键按下,若无循环等待,若有则将键值保存再比较,然后实现相应操作。为使程序可循环使用,不至于显示一次波形就退出,在执行完子程序返回时,不退出系统,而是返回到开始等待输入状态,这样就能切换波形。
具体的实现代码如下:
BEGIN0: MOV
SI,3000H
;把数码管清0
MOV
AL,00H
;先初始化键值为0
MOV
[SI],AL
MOV
AL,00H
MOV
[SI+1],AL
MOV
AL,00H
MOV
[SI+2],AL
MOV
AL,00H
MOV
[SI+3],AL
MOV
SI,OFFSET KEY
MOV
AL,00H
MOV
[SI],AL BEGIN1: CALL
DIS
;显示刷新
CALL
CCSCAN
;再次扫描按键
JNZ
LBEGIN0
;有键按下则跳置LBEGIN0
JMP
BEGIN1;不是按下第一或二键就继续等待输入
LBEGIN0: CALL
GETKEY1
;第二个菜单等待输入
CALL
DIS
MOV
SI,OFFSET KEY
MOV
AL,[SI]
CMP
AL,4
;第5个键退出
JZ
BEGIN0
CMP
AL,0
;第1个键到squ(方波)函数
JZ
LBEGIN1
CMP
AL,1
;第2个键到tri(三角波)函数
JZ
LBEGIN2
CMP
AL,2
;第3个键到rec(锯齿)函数
JZ
LBEGIN3
CMP
AL,3
;第4个键到sin(正弦)函数
JZ
LBEGIN4
JMP
BEGIN1
;其他键则跳到继续等待输入
LBEGIN1: CALL
SQUREW
;SQUARE
JMP
BEGIN0
LBEGIN2: CALL
TRIW
;TRIANGLE
JMP
BEGIN0
LBEGIN3: CALL
RCTW
;RECANGLE
JMP
BEGIN0
LBEGIN4: CALL
SINW
;SIN
JMP
BEGIN0
;执行完输出波形之后 回到开始状态
JMP
BEGIN0
3.5波形产生模块 3.5.1方波
方波的产生只要使DAC0832输出一个较大值(此处用20H),并延时一段时间,再输出一个较小值(此处用00F),延时一段相同时间,就是方波的一个周期。但因为实现过程中结合了数码管的显示以及频率幅值的调节所以并不那么简单。先将幅值和频率的初值放入暂存缓冲区,使数码管显示,扫描键盘,无键按下则继续,有键按下则先判断是否为0到3,是则调节频率幅值,是4则退出波形。执行相应操作后刷新数码管,将新的幅值和频率存在TIAOFU和TIAOPIN的缓冲区内,把低电平的值乘以TIAOFU输出,延迟时间乘以TIAOPIN,使该值持续一段时间,输出高电平的过程与低电平相同,循环该周期就得到连续方波。
具体的实现代码如下:
SQUREW PROC
NEAR
;方波发生子程序
MOV
MOV
MOV
MOV
MOV
MOV
MOV
MOV
SQUR1: CALL 调节幅值频率
MOV
MOV
CMP
JZ
CALL
MOV
MOV
MOV
MOV
MOV
MOV
MOV
MOV
TRILOOP1: MOV
MOV
DI,OFFSET FENC
;初始化显示管的值为3
AL,[DI]
SI,3000H
[SI],AL
DI,OFFSET AMPL
AL,[DI]
SI,3001H
[SI],AL
AMPLFENC
;调节幅值频率子程序,有键按下是
SI,OFFSET KEY
;按下第五个键就退出
AL,4
[SI],AL
SQUA
DIS
;刷新数码管
SI,3000H
BL,[SI]
DI,OFFSET TIAOFU
[DI],BL
SI,3001H
AL,[SI]
SI,OFFSET TIAOPIN
[SI],AL
DX,DA0832
;输出低电平
输出方波形
AL,00H
OUT
DX,AL
CALL
DIS
;刷新
PUSH
CX
PUSH
AX
MOV
CL,TIAOPIN
MOV
CH,00H
D11: MOV
D21: DEC
PUSH
PUSH
CALL
CALL
JNZ
POP
POP
JNZ
LOOP
POP
POP
CALL
JNZ
MOV
MOV
MUL
MOV
OUT
CALL
PUSH
PUSH
MOV
MOV
D12: MOV
AX,00FFH AX AX CX DIS
CCSCAN
;再次扫描按键 SQUR1
;有键按下则跳置squr1, CX AX D21 D11 AX CX
CCSCAN
;再次扫描按键
SQUR1;有键按下则跳置squr1,改变幅值频率 BL,TIAOFU AL,20H BL
DX,DA0832
;输出高电平 DX,AL
DIS
;刷新 CX AX CL,TIAOPIN CH,00H AX,00FFH
D22: DEC
AX
PUSH
AX
PUSH
CX
CALL
DIS
CALL
CCSCAN
;再次扫描按键
JNZ
SQUR1
;有键按下则跳置tri1
POP
CX
POP
AX
JNZ
D22
LOOP
D12
POP
AX
POP
CX
JZ
TRILOOP1
;没按键时继续输出波形
SQUA: RET
SQUREW ENDP
3.5.2三角波
三角波理论上有两段,上升和下降,上升时从最低值开始自增,直到最大值,然后再自减至最低。本设计中,因为对波形精度要求不是很高,所以采用按列表输出的方式,即先在数据段定义了一段三角波一个周期内的采样值的数字量表,采样频率为60点/周期。数字量表中的值为参考值,输出三角波时通过把表中的每个值乘以相同的倍数,该倍数为我们设定的幅值。波形输出方式都相同,这里简要说明:先将幅值和频率的初值放入暂存缓冲区,使数码管显示,扫描键盘,执行相应操作后刷新数码管,将新的幅值和频率存在TIAOFU和TIAOPIN的缓冲区内,将第一个数字量乘以TIAOFU输出,延迟时间乘以TIAOPIN,再扫描,输出第二个值,直到指针指完该数字量表再循环该周期就得到连续三角波。
具体的实现代码如下:
TRITAB
DB
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15;三角函数表
DB
16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
DB
30,29,28,27,26,25,24,23,22,21,20,19,18,17,16
DB
15,14,13,12,11,10,9,8,7,6,5,4,3,2,1 TRIW PROC
NEAR
;三角波形子程序
MOV
DI,OFFSET FENC
MOV
AL,[DI]
MOV
SI,3000H
MOV
[SI],AL
TRA1:
TRLOOP1:
TRLOOP2:
MOV
DI,OFFSET AMPL MOV
AL,[DI] MOV
SI,3001H MOV
[SI],AL CALL
AMPLFENC MOV
SI,OFFSET KEY MOV
AL,4 CMP
[SI],AL JZ
TRIA CALL
DIS MOV
SI,3000H MOV
BL,[SI] MOV
DI,OFFSET TIAOFU MOV
[DI],BL MOV
SI,3001H MOV
AL,[SI] MOV
SI,OFFSET TIAOPIN MOV
[SI],AL MOV
SI,OFFSET TRITAB MOV
AL,[SI] MOV
BL,TIAOFU MUL
BL MOV
DX,DA0832
;启动D/A转换 OUT
DX,AL PUSH
AX PUSH
SI
PUSH
CX
MOV
CL,TIAOPIN
MOV
CH,00H
DALLYTRI1: CALL
DIS
CALL
CCSCAN
JNZ
TRA1
LOOP
DALLYTRI1
POP
CX
POP
SI
POP
AX
INC
SI
CMP
SI,OFFSET RCTTAB
JNZ
TRLOOP2
JMP
TRLOOP1
TRIA: RET
TRIW ENDP
3.5.3锯齿波
锯齿波就是截取了三角波的上升部分,由最小值自增到达最大值后下一个值就返回最小值。本设计中锯齿波的产生方式也是对锯齿波采样,采样周期为32点/周期,然后以采样表为基础输出。锯齿波的输出方式与三角波相同,这里不再重复。
具体的实现代码如下:
先在数据段定义一张锯齿波采样后的数字量表: RCTTAB DB
1,2,3,4,5,6,7,8
;锯齿函数表
DB
9,10,11,12,13,14,15,16
DB
17,18,19,20,21,22,23,24
DB
25,26,27,28,29,30,31,32 RCTW PROC
NEAR
;锯齿波形子程序
MOV
DI,OFFSET FENC
MOV
AL,[DI]
MOV
SI,3000H
MOV
[SI],AL
MOV
DI,OFFSET AMPL
MOV
AL,[DI]
MOV
SI,3001H
MOV
[SI],AL
RCT1: CALL
AMPLFENC
MOV
MOV
CMP
JZ
CALL
MOV
MOV
MOV
MOV
MOV
MOV
MOV
MOV
RCLOOP1: MOV
RCLOOP2: MOV
MOV
MUL
MOV
OUT
PUSH
PUSH
PUSH
MOV
MOV
DALLYRCT1: CALL
CALL
SI,OFFSET KEY AL,4 [SI],AL DIS SI,3000H BL,[SI]
DI,OFFSET TIAOFU [DI],BL SI,3001H AL,[SI]
SI,OFFSET TIAOPIN [SI],AL
SI,OFFSET RCTTAB AL,[SI] BL,TIAOFU BL
DX,DA0832
;启动D/A转换 DX,AL AX SI CX CL,TIAOPIN CH,00H
;刷新,扫描,延时CCSCAN
RCTA
DIS
JNZ
RCT1
LOOP
DALLYRCT1
POP
CX
POP
SI
POP
AX
INC
SI
;下一个值
CMP
SI,OFFSET STR1
JNZ
RCLOOP2
JMP
RCLOOP1
RCTA: RET
RCTW ENDP
3.5.4正弦波
正弦波的产生方式有两种,一种是通过调用函数输出,精度较高,第二种为采样查表法。本实验精度要求不高,所以采用第二种。该方法与前面的三角波,锯齿波方法相同,对一个周期内的正弦波采样,采样周期为40点/周期,输出方式与三角波相同,不再重复。
先在数据段定义正弦波的采样数字量表:
SINTAB DB
16,19,21,23,25,27,29,30,31,32,32,32
;正弦函数表
DB
31,30,29,27,25,23,21,19,16,13,11,9
DB
7,5,3,2,1,0,0,0,1,2,3,5,7,9,11,13 SINW PROC
NEAR
;正弦波的子程序
MOV
DI,OFFSET FENC
MOV
AL,[DI]
MOV
SI,3000H
;取幅值初值
MOV
[SI],AL
MOV
DI,OFFSET AMPL
MOV
AL,[DI]
MOV
SI,3001H
;取频率初值
MOV
[SI],AL
SINA1: CALL
AMPLFENC
MOV
SI,OFFSET KEY
MOV
AL,4
CMP
[SI],AL
JZ
SINA
CALL
DIS
MOV
SI,3000H
MOV
BL,[SI]
MOV
MOV
MOV
MOV
MOV
MOV
SINLOOP1: MOV
SINLOOP2: MOV
MOV
MUL
MOV
OUT
PUSH
PUSH
PUSH
MOV
MOV
DALLYSIN1: CALL
CALL
JNZ
LOOP
POP
POP
POP
INC
CMP
DI,OFFSET TIAOFU [DI],BL SI,3001H AL,[SI]
SI,OFFSET TIAOPIN [SI],AL
SI,OFFSET SINTAB AL,[SI] BL,TIAOFU BL
DX,DA0832
;启动D/A转换
DX,AL AX SI CX CL,TIAOPIN CH,00H CCSCAN SINA1 DALLYSIN1 CX SI AX SI
SI,OFFSET TRITAB
;是否结束一个周期
DIS
JNZ
SINLOOP2
JMP
SINLOOP1
SINA: RET
SINW ENDP
第四章 系统调试遇到的问题及解决方法
本次课程设计是对前几次微机原理实验的检验,也是微机原理与接口技术这门课程的综合应用。前几次软件实验,我都积极地实现了拓展题目的要求,所以在选择课题的时候,我第一印象就感觉到信号发生器对软件要求要大于硬件要求,重点是编程,所以,在选择了这个题目以后我就开始思考用何种方式实现。
整体分析后,硬件电路的系统设计比较简单,主程序的设计思路也比较清晰,主要分为波形产生,数码管显示,键盘控制,频率幅值调节四个模块。但是具体每个模块的实现却又遇到了很多的问题,方案上也有些调整。
在此次实验系统调试的过程中,把整个大的程序划分为几个小模块分开调试好,无误后再写主程序将各个子程序整合起来。虽然一开始感觉思路是很好的,但是在实现过程中遇到了很大的麻烦。
1.硬件的连线。硬件连好后,将方波子程序载入8086,最开始示波器连输出都没有,DAC0832的片选端一直没有被选中,我总是以为是地址的问题,可是怎么检查程序也是没有理由出错的,最后发现DAC0832的WR端虚接了,软件画图容易出现虚接的情况,所以连线的时候一定要小心。
2.小键盘控制,这也是整个程序中最核心的部分。这个子程序加在程序的最前面的,如果没有扫描到键值,整个程序就会陷入死循环,不会有任何输出变化。要使键盘扫描得到键值,我参考了实验指导书上的小键盘控制,先把小键盘扫描的程序单独给出来,看能否显示数字,结果并不能正常显示,反复检查调试以后,修改了键值的存储方式以及延时,将其修改后,小键盘方面能正常扫描了。
3.其实最复杂的是将数码管显示和小键盘扫描整合在一起。数码管显示问题一直很复杂,总是不能正常的显示,明明小键盘Y端有变化,表明有键按下,但是数码管就是不能将要显示的数平稳地显示,刚开始只显示零,后来经修改后,会偶尔显示一下幅值或频率但又立马变了,并且显示的数字也不正确,貌似会和之前显示的数字有重双影。查唐都的实验说明得知,数码管只提供了一个8位数据端口,一次只能让一个数码管显示数据,然后显示过程特别地快,基本上看不到想要的结果,并且闪烁得特别厉害。经过反复一直地查找修改,终于发现,有两个数码管显示的内容重叠了,原来是要显示的两个存储单元的地址弄混了,并且延时也有问题。但是数码管的延时又涉及到波形每个输出点的延时,所以将波形产生方面,我改用了采样数字量表,使所有的波形产生都简化了,同时也使延时更短,改为增加循环次数,并且使数码管显示也加入循环里,这样利用视觉暂留,就能看到同时显示幅值和频率。
4.在小键盘实现中还出现了一个很重要的问题,就是在执行到对应的波形时要怎么样跳出然后执行到另外一个波形里面去。原本我想多设置几个按键,4个负责选择波形,4个负责调幅调频,还要加一个退出按键,每输出一个周期就扫描一次,可是这样按键太多了程序显得臃肿,并且没有波形的情况调节频率也是没有意义的,而且一个周期的时间,很有可能使你的按键落空,没有扫描进去。最后决定只用5个键。没有波形时4个按键选择波形,每次执行完一个点后再重新键盘扫描,此时那4个键又代表调幅和调频,而4键从始至终设置为退出键,只要任何时候扫描到此键就返回初始状态,重新进入波形选择,这样就实现了波形的切换,又使按键有效率更高,而且按键数量也很少。
5.方波和三角波的波形产生的程序并不难。锯齿波就是截取三角波的一半,而正弦波,我找到的正弦波采样值序列表都很长,而且值都比较大,所以最后,我用计算器在0~2π内取了40个点的正弦值。最后在调节幅值的时候,当调到最大幅值时,有两种波形失真了,尤其正弦波和三角波形被截顶了。但是我观察到锯齿波却能正常显示,原来锯齿波的采样数字量表的最大值比较小,经放大最大倍数后也没有超出范围。这可能是因为放大后正弦波的最大值已经超出了运放输出的最大电压,所以导致截顶失真。所以我将数字量的值整体缩小了,最后总算达到满意的效果。第五章 课程设计收获与体会
本次课程设计在面临考试的巨大压力和编程难度的双重压力下终于完成了。这让我对于微机原理与接口技术这门课程又有了更深的了解,尤其是汇编语言的运用。这是一次很好的实践的机会,将我们之前几个星期做的微机原理与接口技术实验的软件和硬件部分都结合起来,灵活的运用,锻炼我们学以致用,解决实际问题的能力。我在此次课程设计中受益匪浅,收获良多。
本次设计我是用仿真完成的,因为上学期在模电数电课程设计中也使用到了protues软件,所以这次的设计,对于protues的使用我一点也不陌生。但是,这次的仿真比起以前模电数电仿真要复杂多了。因为这次我选择的信号发生器重点就是汇编语言程序的编写和调试,程序出现的错误比硬件出现的错要难找的多,尤其是逻辑错误,有的时候看都看不出来。但是我还是比较喜欢汇编语言的,可能是对C已经忘得差不多了的缘故吧,脑子里只有汇编。汇编是一门很原始的语言,但是也是一门很有用的语言,通过这么一个比较大的实验,让我对汇编的理解有了进一步的加深。虽然中间过程有苦有煎熬,但是还是很值得回味的,因为我们就是在这样一次又一次煎熬中才熬出了头,才不断成长为更加强大的人。
在这次设计中,一开始想的比较简单和乐观,因为在做微机原理编程实验的时候,我们接触的都是几十行到一百来行的小程序,写完一检查就能比较轻松地查找到错误,但是这次的题目重点就在编程。一开始,我以为这些程序不会错,电路也比较简单。所以当我很快的连好电路,再几个子程序都加载进去的时候,就完全不是我想象的那样输出。而且从整个电路分析,我也找不到问题到底出在哪里。我必须要一步一步地再回头检查错误。这样有可能还检查不出来,最后我只能从一个小模块开始重新连电路,再将该模块对应的程序加载,有问题再改。就这样,一步一步,只有解决了局部的问题,才能为解决整体的问题提供可能。
在小键盘和数码管显示的模块,确实一度陷入瓶颈,不知道问题出在哪里,为什么就是不能显示。我去了几次实验室,想和大家交流一下,但是选择这个题目的人真的很少,最后找到几个同学,但是他们迫于考试压力要么放弃了仿真,要么放弃了小键盘,当时的情绪真是非常抑郁,难道就真的做不出来了吗?怎么可能?就是不相信,感觉就差一点点,就要实现了,因为坚持,因为坚信,因为坚定,哪怕这个茬再难找也会原形毕露的。当看到数码管显示正常,自己的心血终于有了结果,内心的喜悦溢于言表。有句话说得对:失败就是离成功最近的地方,迈过去了就是另一片天。
这次的课程设计,我要十分感谢同学们给予我的帮助,还有李志明老师的指导,让我在短短的几个星期里学到了很多很实用的知识,通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才是真正的知识,才能提高自己的实际动手能力和独立思考的能力。而且在做课程设计的过程中,不仅是考验自己所学的《微机原理》知识,更是要锻炼自己的分析问题的能力和解决实际问题的能力,而在此次课程设计过程中得到了充分的体现。虽然在设计的过程遇到了各种各样的问题,但同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固,通过这次课程设计,把以前所学过的知识重新温习,加以巩固。
这回顾起此次课程设计,我收获颇丰,不仅巩固了《微机原理》的知识,而且锻炼了动手设计,解决实际问题的能力,同时让我坚定了一个信念,学习上,没有攀登不了的山峰,即使山重水复疑无路,只要坚持下去,也会看到柳暗花明又一村。在今后的学习中,我也会将以这样的精神面对所有的困难。
第六章 参考文献
1.《微机原理与接口技术(第4版)》周荷琴等 中国科学技术大学出版社 2.《TD-PIT+实验教程》 3.《TD-PIT+用户手册》
第七章 附录
7.1汇编源程序
IOY0 EQU
0C400H
;片选IOY0对应的端口始地址
IOY1 EQU
0C440H
;片选IOY0对应的端口始地址;*****************************************************************
MY8255_A EQU
IOY0+00H*4;8255的A口地址
MY8255_B EQU
IOY0+01H*4;8255的B口地址
MY8255_C EQU
IOY0+02H*4;8255的C口地址
MY8255_MODE EQU
IOY0+03H*4;8255的控制寄存器地址
DA0832 EQU
IOY1+00H*4;DA0832的端口地址
STACK1 SEGMENT
STACK
DW
256 DUP(?)
STACK1 ENDS
DATA SEGMENT
DTABLE DB
3FH,06H,5BH,4FH,66H,6DH,7DH DB
07H,7FH,6FH,77H,7CH,39H,5EH,79H,71H
;键值表,0~F对应的7段数码管的段位值
SINTAB DB
16,19,21,23,25,27,29,30,31,32,32,32 DB
31,30,29,27,25,23,21,19,16
;正弦函数表
DB
13,11,9,7,5,3,2,1,0,0,0,1,2,3,5,7,9,11,13
TRITAB DB
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15;三角函数表
DB
16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
DB
30,29,28,27,26,25,24,23,22,21,20,19,18,17,16
DB
15,14,13,12,11,10,9,8,7,6,5,4,3,2,1
RCTTAB DB
1,2,3,4,5,6,7,8
;锯齿函数表
DB
9,10,11,12,13,14,15,16
DB
17,18,19,20,21,22,23,24
DB
25,26,27,28,29,30,31,32
STR1 DB
'pre 0~3 to output wave',0AH,0DH
DB
'pre 4to quit ',0AH,0DH,'$'
AMPL DB
FENC DB
TIAOFU DB
?
TIAOPIN DB
?
KEY DB
?
DATA ENDS
CODE SEGMENT
ASSUME
CS:CODE,DS:DATA
START: MOV
AX,DATA
MOV
DS,AX
MOV
DX,MY8255_MODE
;初始化8255工作方式
MOV
AL,81H
;方式0,A口、B口输出,C口低4位输入
OUT
DX,AL
BEGIN0: MOV
SI,3000H
;把数码管清0
MOV
AL,00H
;先初始化键值为0
MOV
[SI],AL
MOV
AL,00H
MOV
[SI+1],AL
MOV
AL,00H
MOV
[SI+2],AL
MOV
AL,00H
MOV
[SI+3],AL
MOV
SI,OFFSET KEY
MOV
AL,00H
MOV
[SI],AL
BEGIN1: CALL
DIS
;显示刷新
CALL
CCSCAN
;再次扫描按键
JNZ
LBEGIN0
;有键按下则跳置LBEGIN0
JMP
BEGIN1
;不是按下第一或二键就继续等待输入
LBEGIN0: CALL
GETKEY1
;第二个菜单等待输入
CALL
DIS
MOV
SI,OFFSET KEY
MOV
AL,[SI]
CMP
AL,4
;第5个键退出
JZ
BEGIN0
CMP
AL,0
;第1个键到squ(方波)函数
JZ
CMP
JZ
CMP
JZ
CMP
JZ
JMP
LBEGIN1: CALL
JMP
LBEGIN2: CALL
JMP
LBEGIN3: CALL
JMP
LBEGIN4: CALL
JMP
JMP
SQUREW PROC
MOV
MOV
MOV
MOV
MOV
MOV
MOV
LBEGIN1
AL,1
;第2个键到tri(三角波)函数 LBEGIN2
AL,2
;第3个键到rec(锯齿)函数 LBEGIN3
AL,3
;第4个键到sin(正弦)函数 LBEGIN4
BEGIN1
;其他键则跳到继续等待输入 SQUREW
;SQUARE BEGIN0
TRIW
;TRIANGLE BEGIN0
RCTW
;RECANGLE BEGIN0
SINW
;SIN
BEGIN0
;执行完输出波形之后 回到开始状态 BEGIN0
;上面是主程序
NEAR
;方波发生子程序
DI,OFFSET FENC
;初始化显示管的值为3 AL,[DI] SI,3000H [SI],AL
DI,OFFSET AMPL AL,[DI] SI,3001H
MOV
[SI],AL
SQUR1: CALL
AMPLFENC
;调节幅值频率子程序,有键按下是调节幅值频率
MOV
SI,OFFSET KEY
;按下第五个键就退出
MOV
AL,4
CMP
[SI],AL
TRILOOP1:
D11:
D21:
JZ
SQUA CALL
DIS MOV
SI,3000H MOV
BL,[SI] MOV
DI,OFFSET TIAOFU MOV
[DI],BL MOV
SI,3001H MOV
AL,[SI] MOV
SI,OFFSET TIAOPIN MOV
[SI],AL
DX,DA0832
;输出低电平
输出方波形 MOV
AL,00H OUT
DX,AL CALL
DIS
;刷新 PUSH
CX PUSH
AX MOV
CL,TIAOPIN MOV
CH,00H MOV
AX,00FFH DEC
AX PUSH
AX PUSH
CX CALL
DIS CALL
CCSCAN
;再次扫描按键 JNZ
SQUR1
;有键按下则跳置squr1, POP
CX
MOV
POP
AX
JNZ
D21
LOOP
D11
POP
AX
POP
CX
CALL
CCSCAN
;再次扫描按键
JNZ
MOV
MOV
MUL
MOV
OUT
CALL
PUSH
PUSH
MOV
MOV
D12: MOV
D22: DEC
PUSH
PUSH
CALL
CALL
JNZ
POP
POP
JNZ
LOOP
POP
POP
JZ
SQUA: RET
SQUR1
;有键按下则跳置squr1,改变幅值频率 BL,TIAOFU AL,20H BL
DX,DA0832
;输出高电平
DX,AL
DIS
;刷新
CX AX CL,TIAOPIN CH,00H AX,00FFH AX AX CX DIS
CCSCAN
;再次扫描按键 SQUR1
;有键按下则跳置tri1 CX AX D22 D12 AX CX
TRILOOP1
;没按键时继续输出波形
SQUREW ENDP
TRIW PROC
NEAR
;三角波形子程序
MOV
DI,OFFSET FENC
MOV
AL,[DI]
MOV
SI,3000H
TRA1:
TRLOOP1:
TRLOOP2:
MOV
[SI],AL MOV
DI,OFFSET AMPL MOV
AL,[DI] MOV
SI,3001H MOV
[SI],AL CALL
AMPLFENC MOV
SI,OFFSET KEY MOV
AL,4 CMP
[SI],AL JZ
TRIA CALL
DIS MOV
SI,3000H MOV
BL,[SI] MOV
DI,OFFSET TIAOFU MOV
[DI],BL MOV
SI,3001H MOV
AL,[SI] MOV
SI,OFFSET TIAOPIN MOV
[SI],AL MOV
SI,OFFSET TRITAB MOV
AL,[SI] MOV
BL,TIAOFU MUL
BL MOV
DX,DA0832
;启动D/A转换 OUT
DX,AL PUSH
AX
PUSH
SI
PUSH
CX
MOV
CL,TIAOPIN
MOV
CH,00H
DALLYTRI1: CALL
DIS
CALL
CCSCAN
JNZ
LOOP
POP
POP
POP
INC
CMP
JNZ
JMP
TRIA: RET
TRIW ENDP
RCTW PROC
MOV
MOV
MOV
MOV
MOV
MOV
MOV
MOV
RCT1: CALL
MOV
MOV
CMP
JZ
CALL
TRA1 DALLYTRI1 CX SI AX SI
SI,OFFSET RCTTAB TRLOOP2 TRLOOP1
NEAR
;锯齿波形子程序 DI,OFFSET FENC AL,[DI] SI,3000H [SI],AL
DI,OFFSET AMPL AL,[DI] SI,3001H [SI],AL AMPLFENC SI,OFFSET KEY AL,4 [SI],AL RCTA DIS
MOV
SI,3000H
MOV
BL,[SI]
MOV
DI,OFFSET TIAOFU
MOV
[DI],BL
MOV
SI,3001H
MOV
AL,[SI]
MOV
MOV
RCLOOP1: MOV
RCLOOP2: MOV
MOV
MUL
MOV
OUT
PUSH
PUSH
PUSH
MOV
MOV
DALLYRCT1: CALL
CALL
JNZ
LOOP
POP
POP
POP
INC
CMP
JNZ
JMP
RCTA: RET
RCTW ENDP
SI,OFFSET TIAOPIN [SI],AL
SI,OFFSET RCTTAB AL,[SI] BL,TIAOFU BL
DX,DA0832
;启动D/A转换 DX,AL AX SI CX CL,TIAOPIN CH,00H CCSCAN RCT1 DALLYRCT1 CX SI AX SI
SI,OFFSET STR1 RCLOOP2 RCLOOP1
DIS
SINW PROC
NEAR
;正弦波的子程序
MOV
DI,OFFSET FENC
MOV
AL,[DI]
MOV
SI,3000H
MOV
[SI],AL
SINA1:
SINLOOP1:
SINLOOP2:
MOV
DI,OFFSET AMPL MOV
AL,[DI] MOV
SI,3001H MOV
[SI],AL CALL
AMPLFENC MOV
SI,OFFSET KEY MOV
AL,4 CMP
[SI],AL JZ
SINA CALL
DIS MOV
SI,3000H MOV
BL,[SI] MOV
DI,OFFSET TIAOFU MOV
[DI],BL MOV
SI,3001H MOV
AL,[SI] MOV
SI,OFFSET TIAOPIN MOV
[SI],AL MOV
SI,OFFSET SINTAB MOV
AL,[SI] MOV
BL,TIAOFU MUL
BL MOV
DX,DA0832
;启动D/A转换 OUT
DX,AL PUSH
AX PUSH
SI
PUSH
CX
MOV
CL,TIAOPIN
MOV
CH,00H
DALLYSIN1: CALL
DIS
CALL
CCSCAN
JNZ
SINA1
LOOP
POP
POP
POP
INC
CMP
JNZ
JMP
SINA: RET
SINW ENDP
AMPLFENC PROC
CALL
CALL
JNZ
JMP
TRI1: CALL
CALL
MOV
MOV
CMP
JZ
JZ
CMP
JNZ
MOV
DALLYSIN1 CX SI AX SI
SI,OFFSET TRITAB SINLOOP2 SINLOOP1
NEAR
;调节幅值频率子程序 DIS
;刷新
CCSCAN
;再次扫描按键 TRI1
;有键按下则跳置tri1 TRI5
;没按键按下就跳出该子程序DIS
;刷新 GETKEY1
SI,OFFSET KEY
AL,[SI]
AL,4
;第五个键就退出 TRI10 TRI5
AL,0
;第一个键减少周期 TRI2
DI,3001H
MOV
BL,[DI]
CMP
BL,01H
JE
TRI5
DEC
BL
MOV
[DI],BL
JMP
TRI5
TRI2: CMP
JNZ
MOV
MOV
CMP
JE
INC
MOV
JMP
TRI3: CMP
JNZ
MOV
MOV
CMP
JE
DEC
MOV
JMP
TRI4: CMP
JNZ
MOV
MOV
CMP
JE
INC
MOV
AL,1
TRI3 DI,3001H BL,[DI] BL,05H TRI5 BL [DI],BL TRI5
AL,2
TRI4 DI,3000H BL,[DI] BL,01H TRI5 BL [DI],BL TRI5
AL,3
TRI5 DI,3000H BL,[DI] BL,05H TRI5 BL [DI],BL
;第二个键增加周期;第三个键减少幅度;第四个键增加幅度
JMP
TRI5
TRI10: JMP
FAR PTR BEGIN0
TRI5: RET
AMPLFENC ENDP
GETKEY1 PROC
NEAR
CALL
CALL
CALL
CALL
CALL
JNZ
JMP
GETKEY2: MOV
MOV
COLUM: MOV
MOV
OUT
MOV
IN
L1: TEST
JNZ
MOV
JMP
L2: TEST
JNZ
MOV
JMP
L3: TEST
JNZ
MOV
JMP
DIS
;显示刷新 DALLY DALLY
CLEAR
;清屏
CCSCAN
;再次扫描按键
GETKEY2
;有键按下则跳置GETKEY2 BEGIN1
;否则跳回开始继续循环
CH,0FEH
CL,00H
;设置当前检测的是第几列
AL,CH
;选取一列,将X1~X4中一个置0
DX,MY8255_A DX,AL
DX,MY8255_C;读Y1~Y4,用于判断是哪一行按键闭合AL,DX
AL,01H
;是否为第1行 L2
;不是则继续判断
AL,00H
;设置第1行第1列的对应的键值
KCODE
AL,02H
;是否为第2行 L3
;不是则继续判断
AL,04H
;设置第2行第1列的对应的键值
KCODE
AL,04H
;是否为第3行 L4
;不是则继续判断
AL,08H
;设置第3行第1列的对应的键值
KCODE
L4: TEST
AL,08H
;是否为第4行
JNZ
NEXT
;不是则继续判断
MOV
AL,0CH
;设置第4行第1列的对应的键值
KCODE: ADD
AL,CL
;将第1列的值加上当前列数,确定按键值
CALL
PUTBUF
;保存按键值
PUSH
AX
KON: CALL
CALL
CALL
JNZ
POP
NEXT: INC
MOV
TEST
JZ
ROL
MOV
JMP
KERR: RET
GETKEY1 ENDP
CCSCAN PROC
MOV
MOV
OUT
MOV
IN
NOT
AND
RET
CCSCAN ENDP
DIS
;显示刷新 CLEAR
;清屏
CCSCAN
;扫描按键,判断按键是否弹起 KON
;未弹起则继续循环等待弹起 AX
CL
;当前检测的列数递增
AL,CH
AL,08H
;检测是否扫描到第4列 KERR
;是则跳回到开始处
AL,1
;没检测到第4列则准备检测下一列
CH,AL COLUM NEAR
;扫描是否有按键闭合子程序
AL,00H
DX,MY8255_A;将4列全选通,X1~X4置0 DX,AL DX,MY8255_C AL,DX
;读Y1~Y4 AL
AL,0FH
;取出Y1~Y4的反值
CLEAR PROC
NEAR
;清除数码管显示子程序
MOV
DX,MY8255_B;段位置0即可清除数码管显示
MOV
AL,00H
OUT
DX,AL
RET
CLEAR ENDP
DIS
键值并显示
AGAIN:
相应的键值
NEAR
;显示键值子程序
PUSH
AX
;以缓冲区存放的键值为键值表偏移找到MOV
SI,3000H MOV
DL,0F7H MOV
AL,DL PUSH
DX MOV
DX,MY8255_A OUT
DX,AL
;设置X1~X4,选通一个数码管 MOV
AL,[SI]
;取出缓冲区中存放键值 MOV
BX,OFFSET DTABLE AND
AX,00FFH ADD
BX,AX MOV
AL,[BX]
;将键值作为偏移和键值基地址相加得到MOV
DX,MY8255_B OUT
DX,AL
;写入数码管A~Dp CALL
DALLY INC
SI
;取下一个键值 POP
DX MOV
AL,DL TEST
AL,01H
;判断是否显示完? JZ
OUT1
;显示完,返回 ROR
AL,1 MOV
DL,AL PROC
JMP
AGAIN
;未显示完,跳回继续
OUT1: POP
AX
RET
DIS ENDP
PUTBUF PROC
NEAR
;保存键值子程序
MOV
MOV
CMP
JNZ
MOV
GOBACK: RET
PUTBUF ENDP
DALLY PROC
PUSH
MOV
D1: MOV
D2: DEC
JNZ
LOOP
POP
RET
DALLY ENDP
CODE ENDS
END
DI,OFFSET KEY [DI],AL DI,2FFFH GOBACK DI,3004H NEAR
;软件延时子程序 CX CX,000FH AX,000FH AX D2 D1 CX START
7.2 8086 最小模式的硬件连接图