吉林大学微机接口实验五:D/A转换
1.实验内容
2.实验原理/预备知识
D/A转换器TLC7528是关键,其用法参见:
芯片部件汇总:常用功能部件大全-CSDN博客
直接找"TLC7528 D/A数模转换器"(实际上学校的讲义已经讲的很清楚,我只是给搬到了博客里)
3.实验电路图
本次实验的电路较简单,直接按照讲义连接即可。只是拓展实验由于需要使用外部中断,需要加一根线,将'KK1+'端口连接到一个外部中断端口(MIR6或MIR7):
4.实验代码(汇编和C语言版):
汇编语言:
基础实验:
A0832 EQU 0600H ; IOY0地址是0600H,IOY1地址是0640H,IOY2地址是0680HCODE SEGMENTASSUME CS:CODESTART:;产生锯齿波MOV CX, 07H ;锯齿波周期数
JUCHI:MOV DX, A0832 ;DAC0832接IOY0,0600H为控制端口地址MOV AL, 00H ;AL为数字量
JC1: OUT DX, AL ;转换为模拟量CALL DELAY1 ;延时,此为短延时CMP AL ,0FFHJE JC2INC AL ;AL步加1,直到等于0FFHJMP JC1
JC2:LOOP JUCHI;产生矩形波MOV CX, 05H ;矩形波周期数
JUXING:MOV DX, A0832MOV AL, 00H ;先输出00H的波形OUT DX, ALCALL DELAY2 ;长延时MOV AL, 0FFH ;再输出0FFH的波形OUT DX, ALCALL DELAY2 ;长延时LOOP JUXING;产生三角波MOV CX, 05H ;三角波周期数
SANJIAO:
SJ1:MOV DX, A0832OUT DX, ALCALL DELAY1 ;短延时CMP AX, 0FFHJE SJ2 INC AL ;将AL从00H步加0FFHJMP SJ1
SJ2:MOV DX, A0832OUT DX, ALCALL DELAY1 ;短延时CMP AL, 00HJE SJ3DEC AL ;将AL从0FFH步减至00HJMP SJ2
SJ3:LOOP SANJIAO;产生阶梯波MOV CX, 0FFFFH ;产生阶梯波的周期数为0FFFF次MOV AX, 0FEH ;设置波形振幅最大值为0FEHMOV BL,05H ;阶梯波中的阶梯数DIV BL ;用最大振幅除以阶梯数,得到每个台阶的高度MOV BL, AL ;将上述除法的商保存在BL中MOV BH, 00H ;BH置0
JIETI:MOV AX,0000H ;AX初始化0000H
JT1:MOV DX, A0832OUT DX, ALCMP AX, 00FFH ;判断AX是否达到幅度上限JAE JT2 ;达到上限,表示一次阶梯波完整生成,开始新一次生成CALL DELAY2 ;长延时ADD AX, BX ;用当前阶梯高度加上每个阶梯的高度得到下一阶梯的高度JMP JT1
JT2: LOOP JIETIDELAY1: ;短延时PUSH CXMOV CX, 01FFH
D1: PUSH AXPOP AXLOOP D1POP CXRETDELAY2: ;长延时PUSH CXMOV CX, 0FFFFH
D2: PUSH AXPOP AXLOOP D2POP CXRETCODE ENDSEND START
扩展实验:
CODE SEGMENTASSUME CS:CODE
START:MOV AX,0000HMOV DS,AX;设置中断向量MOV AX,OFFSET MIR6MOV SI,0038H ;MIR6中断的矢量地址MOV [SI],AXINC SIINC SIMOV AX,CSMOV [SI],AXCLIMOV AL,11H OUT 20H, AL ;命令字ICW1, 11H=00010001BMOV AL, 08HOUT 21H, AL ;命令字ICW2, 08H=00001000B MOV AL, 04HOUT 21H, AL ;命令字ICW3, 04H=00000100BMOV AL, 03HOUT 21H, AL ;命令字ICW4, 03H=00000011BMOV AL, 0AFH ;OCW1, AF = 10101111BOUT 21H, AL STIMOV BL,00HA1:CMP BL,00HJZ JUCHICMP BL,01HJZ JUXINGCMP BL,02HJZ SANJIAOJMP JIETIJUCHI:MOV DX, 0600H ;DAC0832接IOY0,0600H为控制端口地址MOV AL, 00H ;AL为数字量
JC1: OUT DX, AL ;转换为模拟量CALL DELAY1 ;短延时CMP AL ,0FFHJE A1INC AL ;AL步加1,直到等于0FFHJMP JC1JUXING:MOV DX, 0600HMOV AL, 00H ;先输出00H的波形OUT DX, ALCALL DELAY2 ;长延时MOV AL, 0FFH ;再输出0FFH的波形OUT DX, ALCALL DELAY2 ;长延时JMP A1SANJIAO:MOV AL, 00H
SJ1:MOV DX, 0600HOUT DX, ALCALL DELAY3 ;短延时CMP AL, 0FFHJE SJ2 INC AL ;将AL从00H步加0FFHJMP SJ1
SJ2:MOV DX, 0600HOUT DX, ALCALL DELAY3 ;短延时CMP AL, 00HJE A1DEC AL ;将AL从0FFH步减至00HJMP SJ2JIETI:MOV AX, 0FEH ;设置波形振幅最大值为0FEHMOV CL,05H ;阶梯波中的阶梯数DIV CL ;用最大振幅除以阶梯数,得到每个台阶的高度MOV CL, AL ;将上述除法的商保存在CL中MOV CH, 00H ;CH置0
JT1:MOV AX, 0000H ;AX初始化0000H
JT2:MOV DX, 0600HOUT DX, ALCMP AX, 0FFH ;判断AX是否达到幅度上限JAE A1 ;达到上限,表示一次阶梯波完整生成CALL DELAY4 ;长延时ADD AX, CX ;用当前阶梯高度加上每个阶梯的高度得到下一阶梯的高度JMP JT2DELAY1:PUSH AXPUSH CXMOV AX, 01H ;调节循环次数来改变周期
D1: MOV CX, 0FFH
DD1: LOOP DD1DEC AXCMP AX, 00HJNZ D1POP CXPOP AXRETDELAY2:PUSH AXPUSH CXMOV AX, 7FH ;调节循环次数来改变周期
D2: MOV CX, 0FFH
DD2: LOOP DD2DEC AXCMP AX, 00HJNZ D2POP CXPOP AXRETDELAY3:PUSH AXPUSH CXMOV AX, 01H ;调节循环次数来改变周期
D3: MOV CX, 0FFH
DD3: LOOP DD3DEC AXCMP AX, 00HJNZ D3POP CXPOP AXRETDELAY4:PUSH AXPUSH CXMOV AX, 7FH ;调节循环次数来改变周期
D4: MOV CX, 0FFH
DD4: LOOP DD4DEC AXCMP AX, 00HJNZ D4POP CXPOP AXRETMIR6:INC BLCMP BL, 03HJA MIRET
M:MOV BL, 00HIRETCODE ENDSEND START
C语言版本:
我以前提过,只要在TDX-PITE软件中点左上方设置->语言->C,即可切换成C语言模式。
#include "conio.h"
typedef unsigned char u8;
typedef unsigned int u16;u16 DAC = 0x0600;
u8 value = 0;
u8 time = 0;void delay(u16 time);
void sawtooth();
void rectangle();
void triangle();
void ladder(u8 num);void main() {while(1) {sawtooth();rectangle();triangle();ladder(5);}
}void delay(u16 time)
{int i=0;for(;i<time;i++){int j=0;for(;j<50;j++);}
}void sawtooth() { //value连续变化,输入到DAC中,就是锯齿形状int Loop = 5;for(;Loop>0;Loop--){value = 0;for(;value <= 0x0FE;value++) {outportb(DAC, value); delay(10);}}
}void rectangle() { //value一高一低两个离散的值输入到DAC,就是矩阵形状int Loop = 5;for(;Loop>0;Loop--){value = 0;outportb(DAC, value);delay(500);value = 0x0FF;outportb(DAC, value);delay(500);}
}void triangle() {//其实就是锯齿,先从低到高再从高到低int Loop = 5;for(;Loop>0;Loop--){value = 0;for(;value<=0x0FE;value++){outportb(DAC, value);delay(10);}for(;value>0;value--){outportb(DAC, value);delay(10);}}
}void ladder(u8 num) { //num逐渐减小,step跳跃性的逐渐增大,形成阶梯状int Loop = 5;int num0 = num;u8 step = 0x0FF / (num+1);for(;Loop>0;Loop--){num = num0;value = 0;for(;num>0; num--) {outportb(DAC, value);delay(100);step = 0xFF / (num+1);value += step;}}
}
必须提到一点,在 TDX-PITE 的编译器下,不能在for循环中定义一个变量,即不能写:
for(int i=0;i<10;i++);
这样写会报错,必须写:
int i = 0;
for(;i<10;i++);
原因尚不明确,网上相关资料太少,网上有很多关于C51的资料很多,但关于如何用C语言操作8086微机的资料较少,我也是参照了一位学长的博客:
吉林大学微机接口实验代码(五)_吉林大学微机系统实验-CSDN博客
如果你知道什么关于C语言在微机接口技术中的应用的资料,可以告诉我。
。