📄 ad_contrl.c
字号:
/******************************************************************************
*
** 函数原型:unsigned int ADS7841_Read_Data(unsigned char Channel);
** 功 能:SPI总线的A/D ADS7841 驱动程序
** 入口参数:unsigned char Channel 表示选择读取通道
** 出口参数:unsigned int 返回所读取得12位数据。
** 说 明:ADS7841为12位A/D,先对其进行设置:数据位D0---D7,其中D0---D1是
** 设置ADC的功耗模式,D2是模拟输入通道设置,H为4个单通道,L为两个
** 差分输入,D3为mode,当mode(pin)接地时为12位采样方式,接高电平时
** mode为1时8位采集,为0时12位采集,D4---D6为输入通道选择,D7为起始位
*
*******************************************************************************/
#include "SPCE061A.h"
#include "AD_Contrl.h"
void Init_IOA_IOB(void)
{
*P_IOA_Dir|=0xe400; //设置IOA15(DCLK)=(1,1,0),IOA14(CS)=(1,1,1)
*P_IOA_Dir&=0xe7ff; //IOA13(DIN)=(1,1,0)IOA12(BUSY)=(0,0,0)
//IOA11(DOUT)=(0,0,0),IOA10(MODE)=(1,1,0)
*P_IOA_Attrib|=0xe400; //其他位不变
*P_IOA_Attrib|=0xe7ff;
*P_IOA_Data|=0x4000;
*P_IOA_Data&=0x41ff;
*P_IOB_Dir=0xffff; //设置IOB口为同相低电平输出口
*P_IOB_Attrib=0xffff;
*P_IOB_Data=0x0000;
}
unsigned int AD7841_Read_Data(void)
{
unsigned int AD_Result=0,a=0,b;
unsigned char i,DataInput=0;
*P_IOA_Dir |= 0x2000; //DIN(IOA13)为带数据缓存器的低电平输出。
*P_IOA_Attrib |= 0x2000;
*P_IOA_Data &= 0xdfff;
DataInput=0x0094; //S=1;A2A1A0=001(CH1);MODE=0(12位采集);SGL/DIF=1(4个单通道);PD1PD0=00
DataInput=DataInput<<6;
*P_IOA_Data &= 0xbfff; // CS(IOA14)为低电平
delay(1);
*P_IOA_Data &= 0x5fff; // DCLK(IOA15)为低电平 DIN(IOA13)为低电平
delay(3);
for(i=0; i<8; i++)
{
a = DataInput;
a &= 0x2000; //保留DataInput的13位,其他的全为零
*P_IOA_Data &= 0xdfff; // IOA13 = 0,其他的不变。
*P_IOA_Data |= a; //将DataInput的13位送给IOA13,并不影响IOA的其他位。
*P_IOA_Data &= 0x7fff; // clk low 产生高电平宽度为delay(3)的脉冲,供CLK(8次)。
delay(3); //延迟,清看门狗???
*P_IOA_Data |= 0x8000; // clk high
DataInput = DataInput << 1;
}
delay(1);
*P_IOA_Data &= 0x7fff; // clk low
while(*P_IOA_Data&0x1000)
{
delay(1);
*P_IOA_Data |= 0x8000; // clk high
delay(1);
*P_IOA_Data &= 0x7fff; // clk low 产生高电平宽度为delay(3)的脉冲。
*P_Watchdog_Clear = 0x0001;
} //当BUSY脚由高变为低时,则开始数据输出
delay(1);
for(i=0;i<12;i++) //读取12位AD转换值
{
*P_IOA_Data |= 0x8000; // clk high
delay(1);
b=0x0800;
b &= *P_IOA_Data; //取出DOUT (IOA11)的数据。
b=b>>11;
a |= b;
AD_Result=a;
a=a<<1;
*P_IOA_Data &= 0x7fff; // clk low
}
for(i=0;i<4;i++) //滤掉多余的4个时钟
{
*P_IOA_Data |= 0x8000; // clk high将CLK置1。且不影响其他位,
delay(1);
*P_IOA_Data &= 0x7fff; // clk low
delay(1);
}
*P_IOA_Data |= 0x4000; // CS(IOA14)为高电平,禁止芯片
AD_Result&=0x0fff; //屏蔽高4 位
return AD_Result;
}
void delay(unsigned int i)
{
for(;i>0;i--);
}
/*
unsigned int ADS7841_Read_Data(unsigned char Channel) //Channel=0:CH0;1:CH1;2:CH2;3:CH3;
{
unsigned int ADCResult=0;
unsigned char DataInput=0;
unsigned char i,ADS7841_CHANNEL;
switch (Channel)
{
case 0:ADS7841_CHANNEL=0x10;break;
case 1:ADS7841_CHANNEL=0x50;break;
case 2:ADS7841_CHANNEL=0x20;break;
case 3:ADS7841_CHANNEL=0x60;break;
default:ADS7841_CHANNEL=0x10;break;
}
DataInput=ADS7841_S|ADS7841_CHANNEL|ADS7841_MODE|ADS7841_SGL_DIF|ADS7841_POWER_DOWN;
DCLK=0;
DIN=0;
CS=VALID;
for(i=0; i<8; i++)
{
DIN=DataInput&0x80;
DataInput=DataInput<<1;
DCLK=0;
NOP;
DCLK=1; //模拟SPI串行接口 发送数据
}
NOP;
DCLK=0;
while(BUSY)
{
NOP;
DCLK=1;
NOP;
DCLK=0;
} //当BUSY脚由高变为低时,则开始数据输出//
NOP;
for(i=0;i<12;i++)
{
DCLK=1;
ADCResult=(ADCResult<<1)|DOUT; //模拟SPI串行接口 接收数据
DCLK=0;
NOP;
}
for(i=0;i<4;i++)
{
DCLK=1;
NOP;
DCLK=0;
NOP;
}
CS=INVALID;
return ADCResult;
}
#include <Reg52.h>
#include <Intrins.h>
#include <AbsAcc.h>
#include "meter.h"
////////////////////////////////////
uint ADS7841_READ(uchar CH)
{
uchar i, dt;
uint AD_RESULT=0;
CS7841=0; // 芯片允许
_nop_();
SCK=0;
SDI=0;
dt=CH;
i=0;
while(i<8) //写入8位控制字
{
if(dt>=0x80)
SDI=1; //时钟上升沿锁存SDI
else
SDI=0;
_nop_();
SCK=1; //开始发送命令字
_nop_();
dt<<=1;
SCK=0; //时钟脉冲,一共24个
i++;
}
//等待转换完成(20us)
for(i=0;i<20;i++) { _nop_(); }
SCK=1;
i=0;
while(i<12) //读取12位AD转换值
{
AD_RESULT<<=1; _nop_();
SCK=0;
if(SDO)
AD_RESULT|=0x0001; //用时钟的下降沿读取
if(i==7) { _nop_(); _nop_(); }
SCK=1;
i++;
}
i=0;
while(i<4) //滤掉多余的4个时钟
{
_nop_();
SCK=0; _nop_();
SCK=1;
i++;
}
SDI=1;
CS7841=1; //禁止芯片
AD_RESULT&=0x0fff; //屏蔽高4 bit
return AD_RESULT;
}
///////////////////////////////////////////////////
uint ADS7841_READ(uchar CH)
{
uchar i;
uchar dt;
uint AD_RESULT=0;
SCK=0;
SDI=0;
CS7841=0; // 芯片允许
_nop_();
dt=CH;
i=0;
while(i<8) //写入8位控制字
{
if(dt>=0x80) SDI=1; //时钟上升沿锁存SDI
else SDI=0;
SCK=1; //开始发送命令字
SCK=0; //时钟脉冲,一共24个
dt<<=1;
i++;
}
SDI=0;
//等待转换完成(20us)
for(i=0;i<20;i++) { _nop_(); }
i=0;
SCK=1;
while(i<12) //读取12位AD转换值
{
AD_RESULT<<=1;
SCK=0;
if(SDO) AD_RESULT|=0x0001; //用时钟的下降沿读取
if(i==7) { _nop_(); _nop_(); }
_nop_();
SCK=1;
i++;
}
i=0;
while(i<4) //滤掉多余的4个时钟
{
SCK=0;
SCK=1;
i++;
}
SCK=0;
CS7841=1; //禁止芯片
AD_RESULT&=0x0fff; //屏蔽高4 bit
return AD_RESULT;
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -