找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3028|回复: 0
收起左侧

C8051F020的ADC0和SMBus

[复制链接]
ID:105323 发表于 2016-2-13 00:38 | 显示全部楼层 |阅读模式
本帖最后由 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;//清除中断标志
}

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表