JOSEPF WU 您好、
我使用的是 Atmel 8052微控制器 IC、希望您能为我提供帮助。 我已将 SCL 引脚连接到8052的端口1.0、 将 SDA 引脚连接到8052的端口1.1。 在程序中、您可以看到它。 我将从过去3天到4天进行这项工作。 我遵循了数据表中所示的相同时间图。 仍然无法读取16位。 我只获得正确的 MSB 8位数据、它会随着我更改输入电压而变化。 我将其称为正确的、因为它根据设定增益为7F。 当我将增益设置为 ±2.048时、我在2V 时得到7F。 因此、基本而言、我的半操作是绝对正确的。 即使我尝试在那里读取配置寄存器、我也会正确获得 MSB 8位。 我在这里没有遇到会影响 lsb 8位数据的错误。 请抽出一些时间并帮助我。
#include
sbit SCL=P1^0;
sbit SDA=P1^1;
sbit D7= B^7;//MSBbit
位标志=0、RT=1、位=0;
unsigned char i、ini_char、t、string、STX=02、CR=0x0D、AD1、AD2、AD3、AD4、DATA0、Data1、E、ADC_L、OK、ADS;
unsigned int ADC_M;
unsigned char check [5];
unsigned char 半字节[5];
void main();
void port_ini();
void serial_isr (void);
void go (ini_char);
void send_adc_reading();
void hex_TO_BCD();
void adc_write();
void ADC_WR ();
void SPI();
void ADCM();
void ADCL();
///---------------------------------------------------------
//---- 主要方案-----------------------
///---------------------------------------------------------
void main()
{
//
port_ini();
adc_write();
while (1)
{
adc_write();
如果(RT=0)
{
for (i=0;i<5;i++)
{
半字节[i]=check[i];
}
RT=1;
INI_CHAR=n半 字节[0];
GO (ini_char);
}
}
}
void port_ini()
{
EA=1;//all_interrupt_enable
ES=1;//serial_interrupt_enable
TMOD=0x20;//TIMER1模式2 (自动重新加载)
TH1=0xFD;//9600波特率
SCON=0x50;// REN 使能、8位1停止位
TR1=1;
SCL=1;
SDA=1;
}
void adc_write()
{
ADC_M=0x00;//清除以前的数据以收集新数据
ADC_L=0x00;//清除以前的数据以收集新数据
//写入操作
SCL=1;
SDA=1;
SDA=0;//start
B=0x90;//从地址+WR
ADC_WR ();
SCL=0;
SCL=1;
B=0x01;//配置寄存器
ADC_WR ();
SCL=0;
SCL=1;
B=0xC3;//OS=1、A0 CH、单次触发模式
ADC_WR ();
SCL=0;
SCL=1;
SCL=0;
SCL=0;
SCL=0;
B=0x83;//128SPS
ADC_WR ();
SCL=0;
SCL=1;
SCL=0;//停止
SCL=1;
SDA=1;//停止
TH0=0xDC;//DC
TL0=0x00;
tr0=1;
while (TF0=0);//延迟10ms
tr0=0;
TF0=0;
SCL=1;
SDA=1;
SDA=0;//start
//读取操作
B=0x90;//从地址+WR
ADC_WR ();
SCL=0;
SCL=1;
B=0x00;//转换寄存器
ADC_WR ();
SCL=0;
SCL=1;
SCL=0;
SCL=1;
SDA=1;//停止
SCL=1;
SDA=1;
SDA=0;//start
B=0x91;//从地址+RD
ADC_WR ();
SCL=0;
SCL=1;
ADCM();//调用 ADCM 子例程
SCL=0;
SCL=1;
SCL=0;
SCL=1;
SDA=1;//停止
E=ADC_M/256;//MSB
hex_TO_BCD();
AD4=Data1;
AD3=DATA0;
E=ADC_M%256;//LSB
hex_TO_BCD();
AD2=Data1;
AD1=DATA0;
}
空 ADC_WR ()
{
对于(i=0;i<8;i++)
{
SCL=0;
SDA=D7;
SCL=1;
b = B<<1;//将左 B reg 旋转到 MSB 以检测下一个位
}
}
空 ADCM()
{
for (i=0;i<16;i++)
{
SCL=0;//从模拟接收数字数据的高到低脉冲
如果(SDA=1)//首先旋转,则添加
{
ADC_M= ADC_M << 1;//每次旋转0都将在 LSB 处发生
ADC_M=ADC_M+1;
}
否则、如果(SDA=0)//仅旋转
{
ADC_M=ADC_M << 1;//每次旋转0都将在 LSB 处发生
}
SCL=1;
}
}
//
void ADCL()
{
for (i=0;i<8;i++)
{
SCL=0;//从模拟接收数字数据的高到低脉冲
如果(SDA=1)//首先旋转,则添加
{
ADC_L= ADC_L << 1;//每次旋转0都将在 LSB 处发生
ADC_L=ADC_L+1;
}
否则、如果(SDA=0)//仅旋转
{
ADC_L=ADC_L << 1;//每次旋转0都将在 LSB 发生
}
SCL=1;
}
SCL=0;
OK = 0;
SCL=1;
}
//
//---------------------------------- //
//---- 串行通信--- //
//---------------------------------- //
void serial_ISR (void)中断4.
{
if (Ri=1)//if RI 被置位
{
string=SBUF;//将 SBUF 的内容移动到字符串中
RI=0;//清除 RI 复位
if (string=cr)//如果检测到回车(cR=0x0D)
{
flag=0;//清除标志
T=0;//clear t
RT=0;
}
否则、如果(flag==1)//if 标志被置位
{
check[t]=string;//将数据传输到数组中
T++;//递增数组指针
}
否则、如果(STRING=STX && RT=1)//if STX=0x02被检测到并且 RT 被置位
{
flag=1;//设置标志1
T=0;//从0位置开始指针
}
}
}
//********
///--------------------------------
//---- 去 BYTE0,然后休息---
///--------------------------------
void go (int ini_char)//第一个接收到的 char
{
switch (ini_char)
{
案例"R"://if R
{
SEND_ADC_READING ();
中断;
}
}
}
//********
///--------------------------------
//---- SEND_ADC_READING ----------
///--------------------------------
void send_adc_reading()
{
SBUF= STX;
while (TI=0);
TI=0;
SBUF='R';
while (TI=0);
TI=0;
SBUF= AD4;
while (TI=0);
TI=0;
SBUF= AD3;
while (TI=0);
TI=0;
SBUF= AD2;
while (TI=0);
TI=0;
SBUF= AD1;
while (TI=0);
TI=0;
SBUF= CR;
while (TI=0);
TI=0;
}
//********
///-------------------------------- //
//---- 十六进制_至_BCD ---------------- //
///-------------------------------- //
void hex_TO_BCD ()
{
Data1=E/16;//6A/10=6 MSB
if (Data1>9)
{
Data1=Data1+0x37;
}
其他
{
Data1=Data1+0x30;
}
Data0=E%16;//A LSB
if (DATA0>9)
{
Data0=DATA0+0x37;
}
其他
{
Data0=DATA0+0x30;
}
}
//********