吉林大学微机接口实验五:D/A转换

1.实验内容

2.实验原理/预备知识 

D/A转换器TLC7528是关键,其用法参见:

芯片部件汇总:常用功能部件大全-优快云博客

直接找"TLC7528 D/A数模转换器"(实际上学校的讲义已经讲的很清楚,我只是给搬到了博客里)

3.实验电路图

        本次实验的电路较简单,直接按照讲义连接即可。只是拓展实验由于需要使用外部中断,需要加一根线,将'KK1+'端口连接到一个外部中断端口(MIR6或MIR7):

 4.实验代码(汇编和C语言版):

汇编语言:

 基础实验:

A0832 EQU 0600H     ;  IOY0地址是0600H,IOY1地址是0640H,IOY2地址是0680H
  
CODE SEGMENT
    ASSUME  CS:CODE

START:
    ;产生锯齿波
    MOV CX, 07H       ;锯齿波周期数
JUCHI:
    MOV DX, A0832     ;DAC0832接IOY0,0600H为控制端口地址
    MOV AL, 00H       ;AL为数字量
JC1: 
    OUT DX, AL        ;转换为模拟量
    CALL DELAY1       ;延时,此为短延时
    CMP AL ,0FFH
    JE JC2
    INC AL            ;AL步加1,直到等于0FFH
    JMP JC1
JC2:
    LOOP JUCHI

    ;产生矩形波
    MOV CX, 05H       ;矩形波周期数
JUXING:
    MOV DX, A0832
    MOV AL, 00H       ;先输出00H的波形
    OUT DX, AL
    CALL DELAY2       ;长延时
    MOV AL, 0FFH      ;再输出0FFH的波形
    OUT DX, AL
    CALL DELAY2       ;长延时
    LOOP JUXING

    ;产生三角波
    MOV CX, 05H       ;三角波周期数
SANJIAO:
SJ1:
    MOV DX, A0832
    OUT DX, AL
    CALL DELAY1       ;短延时
    CMP AX, 0FFH
    JE SJ2           
    INC AL            ;将AL从00H步加0FFH
    JMP SJ1
SJ2:
    MOV DX, A0832
    OUT DX, AL
    CALL DELAY1       ;短延时
    CMP AL, 00H
    JE SJ3
    DEC AL            ;将AL从0FFH步减至00H
    JMP SJ2
SJ3:
    LOOP SANJIAO
    
    ;产生阶梯波
    MOV CX, 0FFFFH     ;产生阶梯波的周期数为0FFFF次
    MOV AX, 0FEH       ;设置波形振幅最大值为0FEH
    MOV BL,05H         ;阶梯波中的阶梯数
    DIV BL             ;用最大振幅除以阶梯数,得到每个台阶的高度
    MOV BL, AL         ;将上述除法的商保存在BL中
    MOV BH, 00H        ;BH置0
JIETI:
    MOV AX,0000H       ;AX初始化0000H
JT1:
    MOV DX, A0832
    OUT DX, AL
    CMP AX, 00FFH      ;判断AX是否达到幅度上限
    JAE JT2            ;达到上限,表示一次阶梯波完整生成,开始新一次生成
    CALL DELAY2        ;长延时
    ADD AX, BX         ;用当前阶梯高度加上每个阶梯的高度得到下一阶梯的高度
    JMP JT1
JT2:    
    LOOP JIETI

DELAY1:                ;短延时
    PUSH CX
    MOV CX, 01FFH
D1: 
    PUSH AX
    POP AX
    LOOP D1
    POP CX
    RET

DELAY2:                ;长延时
    PUSH CX
    MOV CX, 0FFFFH
D2: 
    PUSH AX
    POP AX
    LOOP D2
    POP CX
    RET

CODE ENDS
    END START

扩展实验:

CODE SEGMENT
    ASSUME CS:CODE
START:
    MOV AX,0000H
    MOV DS,AX
    
    ;设置中断向量
    MOV AX,OFFSET MIR6
    MOV SI,0038H ;MIR6中断的矢量地址
    MOV [SI],AX
    INC SI
    INC SI
    MOV AX,CS
    MOV [SI],AX
	
    CLI
    MOV AL,11H    
    OUT 20H, AL    	;命令字ICW1, 11H=00010001B
    MOV AL, 08H
    OUT 21H, AL    	;命令字ICW2, 08H=00001000B 
    MOV AL, 04H
    OUT 21H, AL    	;命令字ICW3, 04H=00000100B
    MOV AL, 03H
    OUT 21H, AL    	;命令字ICW4, 03H=00000011B
    MOV AL, 0AFH   	;OCW1, AF = 10101111B
    OUT 21H, AL 
    STI
    MOV BL,00H
    
A1:
    CMP BL,00H
    JZ  JUCHI
    CMP BL,01H
    JZ JUXING
    CMP BL,02H
    JZ SANJIAO
    JMP JIETI
    
JUCHI:
    MOV DX, 0600H     	;DAC0832接IOY0,0600H为控制端口地址
    MOV AL, 00H       	;AL为数字量
JC1: 
    OUT DX, AL        	;转换为模拟量
    CALL DELAY1      	;短延时
    CMP AL ,0FFH
    JE A1
    INC AL            	;AL步加1,直到等于0FFH
    JMP JC1

JUXING:
    MOV DX, 0600H
    MOV AL, 00H       	;先输出00H的波形
    OUT DX, AL
    CALL DELAY2      	;长延时
    MOV AL, 0FFH      	;再输出0FFH的波形
    OUT DX, AL
    CALL DELAY2       	;长延时
    JMP A1
   
SANJIAO:
    MOV AL, 00H
SJ1:
    MOV DX, 0600H
    OUT DX, AL
    CALL DELAY3       	;短延时
    CMP AL, 0FFH
    JE SJ2           
    INC AL            	;将AL从00H步加0FFH
    JMP SJ1
SJ2:
    MOV DX, 0600H
    OUT DX, AL
    CALL DELAY3      	;短延时
    CMP AL, 00H
    JE A1
    DEC AL            	;将AL从0FFH步减至00H
    JMP SJ2
    
JIETI:
    MOV AX, 0FEH        ;设置波形振幅最大值为0FEH
    MOV CL,05H         	;阶梯波中的阶梯数
    DIV CL             	;用最大振幅除以阶梯数,得到每个台阶的高度
    MOV CL, AL         	;将上述除法的商保存在CL中
    MOV CH, 00H        	;CH置0
JT1:
    MOV AX, 0000H     	;AX初始化0000H
JT2:
    MOV DX, 0600H
    OUT DX, AL
    CMP AX, 0FFH       	;判断AX是否达到幅度上限
    JAE A1              	;达到上限,表示一次阶梯波完整生成
    CALL DELAY4        	;长延时
    ADD AX, CX         	;用当前阶梯高度加上每个阶梯的高度得到下一阶梯的高度
    JMP JT2

DELAY1:
    PUSH AX
    PUSH CX
    MOV AX, 01H   		;调节循环次数来改变周期
D1:                
    MOV CX, 0FFH
DD1: 
    LOOP DD1
    DEC AX
    CMP AX, 00H
    JNZ D1
    POP CX
    POP AX
    RET
 
DELAY2:
    PUSH AX
    PUSH CX
    MOV AX, 7FH   		;调节循环次数来改变周期
D2:                
    MOV CX, 0FFH
DD2: 
    LOOP DD2
    DEC AX
    CMP AX, 00H
    JNZ D2
    POP CX
    POP AX
    RET

DELAY3:
    PUSH AX
    PUSH CX
    MOV AX, 01H   		;调节循环次数来改变周期
D3:                
    MOV CX, 0FFH
DD3: 
    LOOP DD3
    DEC AX
    CMP AX, 00H
    JNZ D3
    POP CX
    POP AX
    RET

DELAY4:
    PUSH AX
    PUSH CX
    MOV AX, 7FH   		;调节循环次数来改变周期
D4:                
    MOV CX, 0FFH
DD4: 
    LOOP DD4
    DEC AX
    CMP AX, 00H
    JNZ D4
    POP CX
    POP AX
    RET

MIR6:
    INC BL
    CMP BL, 03H
    JA M
    IRET
M:
    MOV BL, 00H
    IRET
    
CODE ENDS
    END 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微机的资料较少,我也是参照了一位学长的博客:

吉林大学微机接口实验代码(五)_吉林大学微机系统实验-优快云博客

        如果你知道什么关于C语言在微机接口技术中的应用的资料,可以告诉我。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值