东南大学微机实验综合课程设计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
东南大学自动化学院
微机实验及课程设计报告
《参数可调波形发生器》
姓名:学号:
专业:实验室:
组别:同组人员:
设计时间:
评定成绩:审阅教师:
目录
一.设计目的和要求--------------------------------------3 二.原理设计--------------------------------------------4 三.方案论证与实现--------------------------------------6 四.设计思路及流程图--------------------------------------------------------7 五.编程实现--------------------------------------------------------------------10六.方案测试与结果分析----------------------------------18 六.改进与提高------------------------------------------19 七.分析与总结------------------------------------------19
一、设计要求
1)基本要求
编制1 个参数在线可调的波形发生程序,由D/A 输出,构成参数在线可调的波形发生器,并用示波器观察波形。
函数波形可选
f(t)=asin(bt),其中a、b参数在线可调(也可自己选择,但要求至少2 个参数可调且调节很明显)。
参数调节采用如下两种方式之一:(1)两个可调电位器输出通过A/D 转换后作为可调参数;
(2)参数通过实验装置上的键盘实时修改(调整);
(3)精确时间,开关选择标准信号输出(例如a=2V, b=100πRAD/s,即50Hz 正弦波)。
2)设计提示
(1)当用电位器调节参数时,输出零不能对应相应的参数值就为零;
(2)当通过键盘修改参数时,先键入参数名如“a”,显示当前参数值,修改后再键入参数名,则修改参数完成,随后输出波形发生变化。
3)进一步设计要求
(1)分别采用两种参数调节方式在线调节参数;
(2)产生周期性三次可调函数f(t)=at3+bt2+ct+d。
二、原理设计
方案1 参数通过实验装置上的键盘实时修改运行程序后,程序首先显示一段字符串,提示输入相应的数字会得到不同的波形输出。
从键盘上敲入1后,程序会跳转到参数可调的正弦波发生器代码区域。
之后,显示输入可调参数a(0~255)、b(0~255)的信息。
输入a后,波形的幅度会发生相应的变化;输入b后,波形的频率会发生相应的变化。
从键盘上敲入0后,退出程序。
通过检测开关的状态,判断输出标准正弦波还是a,b值所对应的波形。
程序中的主要部分功能原理如下:
(1)程序中的a、b参数的输入
采用百位、十位、个位数字逐个读入的方法。
输入百位数字以后,由于a、b的取值范围在000~255之间、故要判断输入的数字是否小于’0’,大于’2’,若小于’0’或大于’2’,则重新输入。
输入的数若在'0'~'2'之间,将输入的数减去30h,有ASCII码值变为相应的数字,再将此数乘以100后存入c。
输入十位数字后,判断输入的数字是否小于’0’,大于’9’,若小于’0’或大于’9’,则重新输入。
输入的数若在'0'~'9'之间,将输入的数减去30h,有ASCII码值变为相应的数字,再将此数乘以10后存入d。
输入个位数字后,判断输入的数字是否小于’0’,大于’9’,若小于’0’或大于’9’,则重新输入。
输入的数若在'0'~'9'之间,将输入的数减去30h,有ASCII码值变为相应的数字,并将之存
入e 。
之后对c 、d 和e 求和,从而得到a 的值。
同样的可以得到b 的值。
(2) 正弦波幅度的改变
实验中所用的8位D/A 转换器DAC0832的输入数据与输出电压的关系为:5256
2-⨯=N U U REF
o (REF U 表示参考电压,N 表示输入数据)。
产生正弦波是根据正弦函数建立一个正弦数字量表,取值范围为一个周期,此正弦数据表的输出幅度为5V 。
读取一个正弦数据表中的数据后,将此数据乘以a 后再除以255,这样就相当于将输出正弦波的幅度变为原来的a/255倍。
(3) 正弦波频率的改变
正弦波频率的改变是通过改变读取正弦数据表中的两个相邻数据的时间间隔实现的。
输入的数据b 加上10表示应调用的延时子程序的次数,设延时子程序的延时时间为t ,那么读取正弦数据表中的两个相邻数据的时间间隔为b*t 。
方案2 两个可调电位器输出通过A /D 转换后作为可调参数 先读正弦波数据的首地址和一周期取值数,然后按偏移值取出正弦波数据。
启动ADC0809模/数转换器,读入IN0的值(IN0的值可以通过调节滑动变阻器1来实现),将取出的正弦波数据乘以此数据除以255,再将得到的数据赋值给DAC0832,调用延时子程序,之后将数据表偏移量加一,一周期剩余取值数减一。
判断一周期内取值是否结束,若没有结束则继续按偏移值取出正弦波数据,若结束则返回
到读正弦波数据的首地址和一周期取值数。
三、方案论证与实现
针对设计思路,我们用到的硬件资源有:、0832、8255、1个LED 灯和1个逻辑电平开关、0809和2个电位器。
各个硬件的主要作用和工作方式如下:
1)0832
根据键盘输入或者电位器调节得到的参数a、b,改变正弦波形数据表的数据,将得到的新数据输出给DAC0832,,用示波器观察双极性输出端Ub输出正弦波形。
2)8255、1个LED灯与1个逻辑电平开关
8255的C口接逻辑电平开关,作为输入,用来选择是否要输出标准正弦波形;A口接LED灯,作为输出,用来显示此时输出波形是否为标准正弦波形。
3)0809和2个电位器
通过实验台的两个电位器输出0~5V电压分别送入ADC0809的通道0和1(IN0、IN1),通过A/D转换,得到参数a和b。
;CS_AD-----2A0H,CS_DA-----298H;V1-----IN0,V2-----IN1,Ub-----示波器;C0-----K1(开关),A0-----LED灯
ioport equ 0EC00H-0280h ;TPC的io地址
adcs equ ioport+2A0h ;CS_AD,ADC0809片选地址
adcs1 equ ioport+2A1h
dacs equ ioport+298h ;CS_DA,DAC0809片选地址
io8255a equ ioport+288h ;8255A口地址
io8255b equ ioport+28bh ;8255控制寄存器端口地址
io8255c equ ioport+28ah ;08255C口地
四、设计思路及流程图
原理设计清晰了我的设计思路,我将整个整个程序分为了五个部分,分别为主程序设计、参数调整子程序(键盘输入及电位器调节),调幅及调频子程序设计、正弦波输出子程序、延时子程序。
1. 主程序设计:主要功能有
1) 控制整个程序的流程及程序跳转;
2) 通过检测开关的状态,判断输出标准正弦波还是当前a ,b 值所对应的波形;
3) 判断参数调节的方式是键盘输入还是电位器调节。
____
CS
PA0PA1PA2PA3PA4PA5PA6PA7
PC0PC1PC2PC3PC4
PC5PC6PC7
K0()
逻辑电平开关LED
8255
288H~28FH
)电位器)
电位器
2.参数调整程序设计:略。
(原理设计中已详细解释)
3.调幅及调频子程序设计:略。
注:需要输出标准正弦波时,将相应的a,b值修改,并保存之前的a,b值。
4.正弦波输出子程序设计:
正弦波输出子程序的主要功能有:
1)读取正弦波数据表的数据并利用数模转换显示;
2)每显示一次数据后需要调用延时子程序;
3)数据表偏移地址加1,读取下一数据,重复以上步骤。
5.延时子程序设计:
延时子程序的主要功能有:
1)通过b值的改变得到相应的第一层延时参数;
2)延时子程序内嵌套第二层延时程序;
延时部分主要流程:延时程序涉及到嵌套延时,loop指令根据CX的值是否为0确定是否接着执行此指令,因而需要用到两次CX,且相互之间不能影响,因而先将外层CX堆栈(b值不同则外层延时的CX 不同),给内层CX赋值(1FFH,此值不能改变),执行lOOP指令,直到CX=0;然后将外层CX弹出减1后堆栈;接着执行内层延时,重复上述步骤,直到外层CX=0。
四、编程实现
1、主程序设计
message1 db 0dh,0ah,0dh,0ah
db ' PRESS 1 FOR SINWAVE MODIFIY WITH THE PC KEYBOARD.',0dh,0ah db ' PRESS 2 FOR SINWAVE MODIFIY WITH THE
VARIABLE RESISTANCE.',0DH,0AH
db ' PRESS 0 FOR QUIT TO DOS.',0DH,0AH,'$'
db 0dh,0ah
message2 db 0dh,0ah,0dh,0ah
db 'Sinwave [f=a sin(b t)] is modified by the PC keyboard .',0DH,0AH db '-Directly press A or B to view the parameter .',0DH,0AH
db '-Input num(0-17)+A or(0-9) B to modify the parameter .',0DH,0AH db 'Input 0 quit to the begin',0dh,0ah,'$'
db 0dh,0ah
message3 db 0dh,0ah,0dh,0ah
db 'Sin wave [f=a sin(b t)] modified by the
variable resistance .',0DH,0AH
db 'Press anykey on the PC keyboard to return to
the begin.',0dh,0ah,'$'
db 0dh,0ah
message4 db 0dh,0ah
db 'please input num!',0dh,0ah,'$'
db 0dh,0ah
a d
b 1h ;可调参数a
b db 1h ;可调参数b
c db '1' ;c为百位数字f乘以100
d db '1' ;d为十位数字g乘以10
e db '1' ;e为个位数字h乘以1
f db '0' ;参数a的百位f
g db '0' ;参数a的十位g
h db '1' ;参数a的各位h
i db '1' ;i为百位数字l乘以100
j db '1' ;j为十位数字m乘以10
k db '1' ;k为个位数字n乘以1
l db '0' ;参数b的百位l
m db '0' ;参数b的十位m
n db '1' ;参数b的各位n
data ends
begin: mov ax,data ;开机显示message1
mov ds,ax
mov ax,stacks
mov ss,ax
lea dx,message1
mov ah,09h
int 21h
judge1: mov dx,0ffh
mov ah,07h
int 21h
cmp al,'1' ;按下'1',则键盘输入
jz start
cmp al,'2' ;按下'2',则电位器调节
jz sinvr1
cmp al,'0'
jnz begin ;不是'0',重新选择
jmp qit ;按下'0',则退出DOS
sinvr1: jmp sinvr
start: lea dx,message2
mov ah,09h
int 21h
2、参数调整程序设计
(1)键盘输入
l1: call sinout ;每次调用sinout,必须要有键盘输入,才会接着往下执行mov dl,0ah
mov ah,02h
int 21h
mov ah,08h
int 21h
cmp al,'a'
jnz ccc ;若不是a,跳转比较是否为b
jmp ddd ;是a,则跳转到a处理代码
ccc: jmp l2 ;若不是a,跳转比较是否为b
ddd: mov dl,al ;输入是a,a处理代码
mov ah,02h
int 21h
mov dl,0ah
mov ah,02h
int 21h ;输出回车
mov al,f ;输出a的百位f
mov dl,al
mov ah,02h
int 21h
mov al,g ;输出a的十位g
mov dl,al
mov ah,02h
int 21h
mov al,h ;输出a的个位h
mov dl,al
mov ah,02h
int 21h
ggg: lea dx,message4 ;输出“请输入修改后a的参数值”.
mov ah,09h
int 21h
mov ah,08h ;输入
int 21h
cmp al,'0'
jb ggg
cmp al,'2'
ja ggg
mov f,al ;显示输入的百位f
mov dl,al
mov ah,02h
int 21h
sub al,30h
mov bl,64h
mul bl
mov c,al ;c为百位数字f乘以100
mov ah,08h
int 21h
cmp al,'0'
jb ggg
cmp al,'9'
ja ggg
mov g,al ;显示输入的十位g
mov dl,al
mov ah,02h
int 21h
sub al,30h
mov bl,0ah
mul bl
mov d,al ;d为十位数字g乘以10
mov ah,08h
int 21h
cmp al,'0'
jb ggg
cmp al,'9'
ja ggg
mov h,al ;显示输入的个位h
mov dl,al
mov ah,02h
int 21h
sub al,30h
mov bl,01h
mul bl
mov e,al ;e为个位数字h乘以1
mov al,e
add al,d ;求和
add al,c
cmp al,0ffh ;若输入数字大于255则重新输入
ja ggg
mov a,al ;将最终输入得到的值赋给参数a
jmp l1 ;得到a的数值后重新跳到输入界面,
l2: cmp al,'b'
jnz eee ;若不是a,b跳转比较是否为0
jmp fff
eee: jmp l3 ;若不是a,b跳转比较是否为0
fff: ... ;与输入a时主要思想一致,不再给出具体代码
hhh: ...
l3: cmp al,'0' ;输入为零返回
jnz l4 ;若不是a,b,0,跳转到start重新等待键盘输入
jmp begin ;输入为0,返回上一级,即程序主界面的功能选择l4: jmp start ;若不是a,b,0,跳转到start重新等待键盘输入
(2)电位器调节参数
sinvr: lea dx,message3 ;使用电位器设置正弦波参数
mov ah,09h
int 21h
lea dx,mess2
int 21h ;去掉返回功能
sin1:
call sinout
lea dx,messab ;装入地址
mov ah,09h ;显示字符串
int 21h
mov al,00h
mov dx,adcs
out dx,al
in al,dx ;从A/D读入修改的幅度
CMP AL,'0'
JE ABA
A1: mov a,al ;幅度存到a
mov al,00h ;moomyu修改
mov dx,adcs1
out dx,al
in al,dx ;从A/D读入修改的频率
CMP AL,'0'
JE ABB
B1: mov b,al ;频率存到b
call sinout ;修改幅度和频率后重新调用sinout
mov ah,08h
int 21h
jz sin1
jmp bg
lea dx,message2 ;装入地址
mov ah,09h ;显示字符串
int 21h
mov ah,08h
int 21h
cmp al,'q'
jnz sin1
jmp bg
ABA:inc al
jmp A1
ABB:inc al
jmp B1
4、正弦波输出设计
;正弦波数据表
SIN DB 128D,135D,141D,148D,155D,161D,167D,174D,180D,186D DB 192D,198D,203D,209D,214D,219D,223D,227D,231D,235D
DB 239D,242D,245D,248D,250D,252D,253D,254D,255D
DB 255D,254D,253D,252D,250D,248D,245D,242D,239D
DB 235D,231D,227D,223D,219D,214D,209D,203D,198D,192D
DB 186D,180D,174D,167D,161D,155D,148D,141D,135D,128D
DB 121D,115D,108D,101D, 95D, 89D, 82D, 76D, 70D
DB 64D, 58D, 53D, 47D, 42D, 37D, 33D, 29D, 25D, 21D
DB 17D, 14D, 11D, 08D, 06D, 04D, 03D, 02D, 01D, 00D
DB 00D, 01D, 02D, 03D, 04D, 06D, 08D, 11D, 14D, 17D
DB 21D, 25D, 29D, 33D, 37D, 42D, 47D, 53D, 58D, 64D
DB 70D, 76D, 82D, 89D, 95D,101D,108D,115D,121D
sinout proc near ;输出正弦波
push ax
push bx
push cx
push dx
push si
mov ax,1h
sub cx,cx
mov cl,b
cmp cl,0
je S_OUT0
mov SI,0h
judge2: mov dx,io8255b ;设8255为C口输入,A口输出mov al,8bh
out dx,al
mov dx,io8255c ;从C口输入一数据
in al,dx
mov dx,io8255a
out dx,al
and al,00000001h
mov ah,0 ;判断开关状态
mov c,al
cmp c,1
jnz S_OUT2
jmp stadard
S_OUT2: mov dl,0ffh ;幅度
mov ah,06h
int 21h
jnz S_END
mov al,SIN[SI] ;从正弦波数据表中取数据mov bl,a
cmp bl,0
je S_OUT0
mov ah,00h
mov ah,00h
mul bl ;乘以a
mov bl,255D
div bl ;除以255
push cx
neg cl
add cl,10 ;b+10作为调用子程序的次数S_OUT1: call sin_delay1 ;频率
loop S_OUT1
pop cx
mov dx,dacs
out dx,al ;输出数据到dac0832
inc si
cmp si,116 ;共116个数据
jne S_OUT2
mov si,0h
jmp S_OUT2
S_END:pop SI
pop dx
pop cx
pop bx
pop ax
ret
S_OUT0:sub ax,ax
mov dx,dacs
out dx,al ;S_OUT0输出的是空信号,输出都为零jmp S_END
sinout ENDP
stadard: mov a,08h ;输出标准正弦波
mov b,01h
call sinout
jmp judge2
5、延时子程序设计
sin_delay1 proc near
push cx
mov cx,0f00h
loop $
pop cx
ret
sin_delay1 endp
五、方案测试与结果分析
将程序运行,可以达到预期的效果。
当用键盘输入调节参数时,正弦波形幅度可以从0~5V以每0.3V为间隔连续调节,频率调节明显,先键入参数名如“a”,显示当前参数值,修改后再键入参数名,则修改参数完成,随后输出波形会发生变化;以电位器调节参数时,幅度、频率变化比较明显;标准波形满足2V,50Hz要求。
在运行代码的过程中也遇到了一些问题,主要的问题及解决思路如下:
1.堆栈问题
问题描述:在延时程序嵌套子延时,用到两次CX值,为保存原始的CX,因而要进行三次堆栈及弹出,过程中发现堆栈和弹出的顺序错乱使得CX发生值的突变,使得延时环节发生错误。
解决方法:主要在程序中随时将需要保护的寄存器内容推入堆栈进行保护,同时要注意先进先出,保证堆栈与出栈一一对应。
2.频率调节某些情况无法实现
问题描述:b值大小与延时环节的时间t成反比,此时需要用到出发
来决定延时程序最外层的CX值大小,即CX=T(程序中设定)/b;发现利用除法效果不明显,且因为除法较为复杂,不容易实现。
解决方法:利用NEG函数指令,对b求补,可以转化为乘法,及CX=T ×(NEG(b)+20H),可以满足b值越大,延时越小,但不能准确满足延时环节的时间t与b值大小的反比关系。
实验表明,频率调节较为明显,基本上满足要求。
六、改进与提高
通过修改代码基本上实现了波形可调发生器的设计,包括基本功能和一部分扩展功能,但是通过实验,有很多需要改进的地方。
1、一部分功能不够完善,例如在利用电位器调节参数时,幅度及频率不是实时改变的,只有改变电位器后,按ENTER键才可以看到变化。
2、频率调节,对b值采用求补方法来确定延时时间,不能满足两者的反比关系,使得频率调节有一定的误差。
3、将本题延伸,定义其他波形的数据表,可以扩展到方波、三角波、锯齿波等其他波形。
七、分析与总结
在设计过程中,会遇到各种问题,很多时候,程序运行的结果与预想的不一样,没有正确的结果,此时需要耐心分析代码,找出问题。
本次试验,常常遇到的问题是,程序跳转发生错误,逻辑发生错误,在修改的过程中,更加深刻地意识到程序模块之间的跳转规则。
模块
调试完成,接着进行系统调试,利用TD查看寄存器的值可以知道程序是否按照预想的运行。
系统调试是一件非常繁琐的事情,要使系统设计的更为完善,就必须花费大量的时间在调试上。
在实验验收的过程中,我们的程序并不太得到验收老师的认可,我们自己也承认没有精确计时等原因使整个课程设计有些简单,不太符合课程的要求。
一开始为了贪图方便就采用了软件计时的方法,并没有看到精确计时的要求。
也是对硬件的不为熟悉,对8253及8255的应用也有所欠缺。
验收结束后,我又专门花时间研究了下,虽然对本次课程设计的帮助已经不大,但我认识到其实精确计时也并不很难。
对于两个可调电位器输出通过A/D 转换后作为可调参数的设计方案
主程序流程图:
延时子程序流程图:
(1)主程序设计:dep proc near
mov dx,io8255b
mov al,10010000b ;写8255控制字,A组工作于方式0,输入
out dx,al
mov dx,io0809b ;延时
out dx,al
mov cx,0ffh
delay3: loop delay3
in al,dx
mov bl,al
mov dx,io8253c
mov al,00010000b;写8253控制字,CNT0,只读/写低字节,方式0,二进制 out dx,al
mov al,bl
mov dx,io8253a ;往8253写计数初值
out dx,al
check:
mov dx,io8255a
in al,dx
and al,01h
cmp al,00h
jz check
ret
dep endp
(2)延时子程序:
main proc far
start:
mov ax,data
mov ds,ax
ll: mov si,offset sin ;置正弦波数据的偏移地址为SI
mov bh,64 ;一组输出32个数据
lll: mov dx,io0809a ;启动A/D转换器
out dx,al
mov cx,0ffh ;延时
delay2 :loop delay2
mov dx,io0809a
in al,dx ;从A\D转换器输入数据
mov ah,[si] ;从数据表中取一个数据
mul ah ;ah与al相乘,存入ax
mov dl,0ffh
div dl ;ax除以dl,商在al,得到振幅
mov dx,io0832a ;将数据输出到D/A转换器
out dx,al
mov ah,06h ;判断是否有键按下
mov dl,0ffh
int 21h
jne exit
call dep
inc si ;取下一个数据
dec bh
jnz lll ;若未取完32个数据则转lll
jmp ll
exit: mov ah,4ch ;退出
int 21h
main endp
参考文献
【1】戴先中.微机硬件原理实现——原理与接口[M].南京:东南大学出版社,1999 【2】杨素行.微型计算机系统原理与应用(第二版).北京:清华大学出版社,2004
延时子程序功能原理:先启动8255,写8255的控制字,A组工作于方式0,输入,目的是让PA0读8253的OUT0的高低电平,来判断计数是否结束。
启动ADC0809,读入IN1的值(IN1的值可以
通过调节滑动变阻器2来实现)。
启动8253计数器,将读入的IN1的值作为8253定时器的计数初值,读取8255的PA0,判断其是否是1。
是1,说明计数器OUT0变为高电平,计数结束,返回主程序。
不是1,则继续判断。