本帖最后由 51黑黑黑 于 2016-2-13 00:39 编辑

与其它逐次逼近式的AD操作类似,有几个点需要主要:1.有8个通道,内部还有一个通道用于测温;2.内部可产生一个1.2V电压基准,并能x2输出到Vref,但必须接到Vref0上,当然也可以外接基准电压;3.有低功耗跟踪方式可供选择;4.内部有运放增益,对微弱信号特别有效

一般采用向ADBUSY写1的方式进行转换,以下是读取AD值的函数:
uint GetAD0value(uchar channel)//0~7对应AIN0~7,8是温度传感器
{//AD采样
uint ad0_value;
AMX0SL=channel;
AD0INT=0;
AD0BUSY=1;//启动AD转换
while(!AD0INT);
{
ad0_value=ADC0H;
ad0_value<<=8;
ad0_value+=ADC0L;//AD转换结果
}
return ad0_value;
}
温度的转换利用以下关系式:[2.4*GetAD0value(8)-3177.7]/117;
----------------以下为SMBus介绍-------------------------------------
C8051F020的SMBus兼容I2C,因此可以方便地挂接多个I2C器件,如下图:
主发送器方式:
主接收器方式:
SMB0STA:
bit SM_BUSY;//读和写时的忙标志位
void SMBus_Init()
{
SMB0CN=0x44;
SMB0CR=0xec;//频率400k
EIE1|=0x02;
SM_BUSY=0;
} void SM_Send(uchar chip_select,uintbyte_address,uchar out_byte)
{//i2c写驱动
while(SM_BUSY);//等待SMBus空闲
SM_BUSY=1;//占用SMBus(设置为忙)
SMB0CN=0x44;
BYTE_NUMBER=2;//2地址字节
COMMAND=chip_select;
HIGH_ADD=byte_address>>8;//高8位地址
LOW_ADD=byte_address&0x00FF;//低8位地址
WORD=out_byte;//待写数据
STA=1;//启动传输过程
while(SM_BUSY);//等待传输结束
} uchar SM_Receive(uchar chip_select,uintbyte_address)
{//i2c读驱动
while(SM_BUSY);//等待总线空闲
SM_BUSY=1;//占用SMBus(设置为忙)
SMB0CN=0x44;
BYTE_NUMBER=2;//2地址字节
COMMAND=chip_select|1;
HIGH_ADD=byte_address>>8;//高8位地址
LOW_ADD=byte_address&0x00FF;//低8位地址
STA=1;//启动传输过程
while(SM_BUSY);//等待传输结束
return WORD;
} void i2c_ISR() interrupt 7
{
switch (SMB0STA)
{// SMBus 状态码(SMB0STA 寄存器)
case 0x08://起始条件已发出
SMB0DAT=COMMAND&0xfe;//从器件的地址+W
STA=0;//手动清除START位
break;
case 0x10://重复起始条件已发出
SMB0DAT=COMMAND;//COMMAND中应保持从地址+R
STA=0;
break;
case0x18://从地址+W已发出,收到ACK
SMB0DAT=HIGH_ADD;//如果是EEPROM,装入待写存储器地址的高字节
break;
case0x20://从地址+W已发出收到NACK
STO=1;
STA=1;
break;
case0x28://数据字节已发出收到ACK
switch (BYTE_NUMBER)
{
case 2://如果BYTE_NUMBER==2,
SMB0DAT=LOW_ADD;//发送了LOW_ADD
BYTE_NUMBER--;
break;
case1://如果BYTE_NUMBER==1,LOW_ADD已发送
if(COMMAND&0x01)
{//如果R/W=READ,发送重复起始条件
STO=0;
STA=1;
}
else
{
SMB0DAT=WORD;//如果R/W=WRITE,装入待写字节
BYTE_NUMBER--;
}
break;
default://如果BYTE_NUMBER==0,传输结束
STO=1;
SM_BUSY=0;//释放SMBus
}
break;
case0x30://数据字节已发出收到NACK
STO=1;
STA=1;
break;
case0x40://从地址+R已发出收到ACK
AA=0;//只收一个字节,清AA
break;
case0x48://从地址+R已发出收到NACK
STA=1;
break;
case 0x58://数据字节收到NACK已发出
WORD=SMB0DAT;
STO=1;
SM_BUSY=0;//释放SMBus
break;
default:
STO=1;//通信复位
SM_BUSY=0;
break;
}
SI=0;//清除中断标志
}
|