一、实验内容
利用实验台上的0809做A/D转换实验,实验台上的W1电位器提供模拟量输入。编制程序,将模拟量转换成数字量。(要求模拟量由0809的IN2采集)
二、仿真图
三、代码
C语言实现:
#include
#include
#define AD XBYTE[0XFF22] //定义AD0808的地址 Y4(20) Y1(01) Y7(31)
#define PA XBYTE[0XFF28] //定义8255A中PA段的地址
#define PB XBYTE[0XFF29] //定义8255A中PB段的地址
#define PC XBYTE[0XFF2a] //纯属方便定义,没用到
#define COM8255 XBYTE[0XFF2B] //定义8255A的控制字 Y5(FF2B) Y3(FF1B) Y7(FF3B)
#define uint unsigned int
#define uchar unsigned char
float x=0;
uchar count=0;
uchar xdata *ad=&AD;//定义指针指向AD8080的地址
//uchar table[]={0xC0,0xF9,0xA4,0xB0,
// 0x99,0x92,0x82,0xF8,
// 0x80,0x90,0x88,0x83,
// 0xC6,0xA1,0x86,0x8E}; //数码管共阳极的显示编码
uchar table[]=
{0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};//数码管共阴极的显示编码
void delayMS(unsigned int ms)//延时函数
{
unsigned char i,j;
for(i=ms;i>0;i--)
for(j=60;j>0;j--);
}
void main()
{
IT0=1; //设置外部中断为边沿触发
EX0=1; //打开外部中断
EA=1; //打开总中断
*ad=0x01; // AD0808数值进行初始化
COM8255=0x89;//10000000 //8255A数值进行初始化,设置端口为输出
delayMS(100); //进行适当的延时
while(1)
{
PB=0X00;
PA=0xff;//进行消影
PB=0X80;
PA=~table[count%16]; //选定最后一位数码管(段选),进行显示
delayMS(1); //进行延时,但延时时间不宜过长
PB=0X00;
PA=0xff ; //进行消影
PB=0X40;
PA=~table[count/16];
delayMS(1);//选定倒数第二位数码管(段选),进行显示
}
}
void ad0() interrupt 0//进入外部中断,此处为了通过脉冲方便进行AD0808的采样
{
count=*ad; //此处count的值应为采集到的数据,范围应在0~255
// x=x*0.9+count*0.1; //此处程序完成了低通滤波的功能,在实际演示中,由于种种限制,数字会有较大变化,不利于人的观察
// count=(uchar)x; //再将处理好的值赋给count,此时的数字显示趋于稳定
*ad=0x01; //清除采集到的数据当下,一个脉冲到来时重新采集
}
汇编实现:
AD EQU 0FFE2H ;1111 1111 11/10 0(138)/010(通道数)
COM8255 EQU 0FFEBH ;键盘显示单元的8255控制口1111 1111 11/10 1/010
PA EQU 0FFECH ;字形控制口 1111 1111/11/10 1/0?/00(00指向PA) p184
PB EQU 0FFEDH ;字位/键扫控制口 1111 1111/ 11/10 1/0?/01(01指向PB)
ORG 0000H
LJMP START
ORG 0030H
START: MOV SP, #60H
MOV DPTR,#AD ;
MOVX @DPTR,A ;0809的通道0采样
MOV DPTR,#COM8255 ;片选
MOV A,#89H ;P186 命令字:选择工作方式,A,B口输出 1/000 1/00/1 (A,B:方式0)
MOV DPTR,#0FFEBH ;控制寄存器送入DPTR,8255才工作 0111 1111/ 11/10 1/0?/11
// MOVX @DPTR,A ;方式寄存器送入控制寄存器
MOVX @DPTR,A ;累加器送外部RAM,8255初始化
MOV R7,#100 ;保证转换结束,EOC=1
CALL DELAY ;
MOV DPTR,#AD ;
L1: JB P3.2,L1
MOVX A,@DPTR ;读取AD转换数据
while1:
MOV B,A;此处略有不同,先把数据拆分,不然下边麻烦
SWAP A ;累加器高四位与低四位互换
ANL A,#0FH ;进位内容与直接地址内容相与,取高4位
ANL B,#0FH ;进位内容与直接地址内容相与,取低4位
MOV R4,A ; R4存高位相当于/16
MOV R5,B ; R5存低位相当于%16
MOV DPTR,#AD
MOVX @DPTR,A ;开始下次AD转换
MOV R3,#64h ;???
for:;第一个数码管显示
MOV DPTR,#PB ;进行消影,先位选
MOV A,#00H ;全选
MOVX @DPTR,A ;输出
MOV DPTR,#PA ;再段选
MOV A,#0FFH ;全选
MOVX @DPTR,A ;输出
MOV DPTR,#PB
MOV A,#80H //1000 0000,选中第一位
MOVX @DPTR,A //第一位输出
MOV DPTR,#LEDMAP //指向表头
MOV A,R5 // R5存低位相当于%16
MOVC A,@A+DPTR ;变位寻址
MOV DPTR,#PA ;选定的数送入RAM
MOVX @DPTR,A ;再输出
MOV R7,#1
CALL DELAY ;第二个数码管显示
MOV DPTR,#PB //进行消影
MOV A,#00H //
MOVX @DPTR,A //
MOV DPTR,#PA ;
MOV A,#0FFH ;
MOVX @DPTR,A ;
MOV DPTR,#PB
MOV A,#40H //0100 0000,选中第二位
MOVX @DPTR,A
MOV DPTR,#LEDMAP
MOV A,R4 ;R4存高位相当于/16
MOVC A,@A+DPTR;
MOV DPTR,#PA
MOVX @DPTR,A
MOV R7,#1 ;
CALL DELAY
DJNZ R3,for
MOV DPTR,#AD
L2:JB P3.2,L2
MOVX A,@DPTR ;读取AD转换数据
JMP while1
DELAY: MOV R6,#135
DJNZ R6,$
DJNZ R7,DELAY;
RET
LEDMAP: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H ;字形表
DB 80H,90H,88H,83H,0C6H,0A1H,86H,8EH,0FFH
END
|