该驱动多增加了一次写端口地址,目的是读取需要的端口值。
因为AD操作时,写地址后要再下次才能读上次的数据。
(这在输入的模拟信号是多端口时,避免逻辑错误。
当然也可以采取其他方式避免这种逻辑错误)
#include<reg52.h>
#include <intrins.h>
sbit AD_OUT=P3^2; //从 2543读数据
sbit AD_IN =P3^3; //输出信号to 2543
sbit AD_CS =P3^4; //片选2543
sbit AD_CLK=P3^5; //时钟信号
sbit AD_EOC=P3^7;//无用
void AD2543_ini() //初始化2543
{
AD_CS=1;
AD_CLK=0;
}
unsigned int Read2543(unsigned char port) //port为准备读取的端口
{
unsigned int ad=0,n;//变量ad为返回值,n为临时变量(用于端口操作)
unsigned char i;
AD_CLK=0; //clk先给0,避免出错
AD_CS=0; //片选,0有效
n=port; //用n来操作端口port,目的是写2次端口地址,这样回来的才是真正的端口ad值
n<<=4; //先偏移4,让地址到高位
for(i=0;i<12;i++) //输入12位端口地址(其实前4位是地址,后8位都是0)
{
AD_IN=(bit)(n&0x80); //高位(第8位)输出。(串口模式)
AD_CLK=1;
AD_CLK=0;
n<<=1; //左移1位。利用循环逐位输出
}
AD_CS=1; //关闭片选
{_nop_();_nop_();_nop_();_nop_();} //缓冲一下
{_nop_();_nop_();_nop_();_nop_();} //缓冲
AD_CS=0; //再次片选
n=port; //再次写端口地址
n<<=4;
for(i=0;i<12;i++)
{
AD_IN=(bit)(n&0x80);
AD_CLK=1;
AD_CLK=0;
n<<=1;
}
AD_CS=1; //停止
{_nop_();_nop_();_nop_();_nop_();}
{_nop_();_nop_();_nop_();_nop_();}
AD_CS=0; //片选。开始读取数据
for(i=0;i<12;i++) //12位循环
{
ad<<=1; //先左移1位
if(AD_OUT) ad|=0x01; //判断:如AD_OUT为1,则ad低位赋值1
AD_CLK=1;
AD_CLK=0;
}
AD_CS=1; //结束读数据
return(ad); //返回值ad
}
|