便携式人体脉搏检测系统(1)

PCF8951+I2C+STC89C52 ADC采集与输出

I2C

IIC是一种多向控制总线,也就是说多个芯片可以连接到同一总线结构下,同时每个芯片都可以作为实时数据传输的控制源。主要包括启始、停止、读、写、应答信号。这种方式简化了信号传输总线接口。

IIC总线上可以挂多个器件,而每个器件都有唯一的地址,这样可以标识通信目标。数据的通信的方式采用主从方式,主机负责主动联系从机,而从机则被动回应数据。
便携式人体脉搏检测系统(1)

1.I2C总线信号

(1)开始和停止信号
便携式人体脉搏检测系统(1)

  • 开始信号:SCL=1,SDA下降沿;
void start()
{
    SDA = 1;     //初始时,SDA=1
    SCL = 1;     //初始时,SCL=1
    delay();     //保持时间大于4.7us
    SDA = 0;     //SDA下降沿
    delay();     //SDA下降沿保持时间大于4.0us
}
  • 停止信号:SCL=1,SDA为上升沿。
void stop()
{
    SDA = 0;    //初始时,SDA=0;
    SCL = 1;    //初始时,SCL=1;
    delay();    //保持时间大于4.0us
    SDA = 1;   //SDA上升沿
    delay();   //保持时间大于4.7us
}

(2)应答信号
便携式人体脉搏检测系统(1)

void ack()
{
    uchar i = 0;     //定义缓冲变量
    SCL = 1;
    delay();
    while(SDA == 1 && i < 250)i++;    //稳定时间大于4us
    SCL = 0;   //SCL=0时,SDA数据才可以改变
    delay();
}

2.I2C总线数据传输条件

便携式人体脉搏检测系统(1)

  • SCL=1时,SDA必须保持稳定;
  • SCL=0时,SDA才允许改变。

3.I2C总线读写操作

便携式人体脉搏检测系统(1)
(1) 数据传送规则:

  • 每传送一个字节时必须保证是8位长度;
  • 数据传送时,先传送最高位(MSB);
  • 每个被传送的字节后面,跟随一位应答信号,即一帧实际共有9位。

(2)数据传送流程:

  • 主机向总线发送一个字节的数据后,释放总线,从机拉低总线(即应答信号),表示这一字节发送成功;
  • 主机从总线读取完一个字节的数据后,主机把总线拉低,表示这一字节发送成功。

a.写入数据
便携式人体脉搏检测系统(1)

void write_byte(uchar dat)
{
    uchar i;
    for(i = 0; i < 8; i++)
    {
        dat = dat << 1;    //先写最高位,通过左移运算符,将一个字节的数据一位一位的传送到总线上     
        SCL = 0;     //SCL=0,从机准备接收数据         
        delay();
        SDA = CY;     //CY存储的是左移后的进位
        delay();
        SCL = 1;
        delay();
    }
    SCL = 0;      //8位数据传输完后,释放SDA,准备接收应答位              
    SDA = 1;      // 释放SDA           
    delay();
}

b.读取数据
便携式人体脉搏检测系统(1)

uchar read_byte()
{
    uchar dat = 0, tmp, i;
    SCL = 0;    //SCL=0,准备接收数据
    delay();
    for(i = 0; i < 8; i++)
    {
        SCL = 1;     //SCL = 1,SDA稳定,准备读取数据     
        delay();
        tmp = SDA;     //读取此时SDA的状态       
        dat = dat << 1;    //先写最高位,通过左移运算符,将一个字节的数据一位一位的传送到总线上     
        dat = dat | tmp;    //读数据位,接收的数据位放在dat中
        delay();
        SCL = 0;    //释放SDA总线,为下一次读取做准备       
        delay();
    }
    return dat;   //  返回读取的dat值
}

4.I2C总线初始化

void I2C_init()               
{
    SDA = 1;   
    delay();
    SCL = 1;   
    delay();
}

PCF8951

PCF8591是单片、单电源低功耗8位CMOS数据采集器件,具有4个模拟输入、一个输出和一个串行I2C总线接口。3个地址引脚A0、A1 和A2 用于编程硬件地址,允许将最多8个器件连接至I2C总线而不需要额外硬件。器件的地址、控制和数据通过两线双向I2C总线传输。器件功能包括多路复用模拟输入、片上跟踪和保持功能、8位模数转换和8位数模拟转换。最大转换速率取决于I2C总线的最高速率。

1.器件地址

总线启动后,发送的第一个字节。
便携式人体脉搏检测系统(1)
便携式人体脉搏检测系统(1)
由电路原理图可知,A0 A1 A2均为0,所以:

  • lsb=0时,即器件地址为0x90时,表示主机向从机写数据,下一个字节向总线写入数据;
  • lsb=1时,即器件地址为0x91时,表示主机从从机读数据,下一个字节从总线读取数据。

2.控制字

总线启动后,发送的第二个字节。
便携式人体脉搏检测系统(1)

  • msb,默认为0;
  • 第6位,选择是否允许模拟电压输出,DA转换时设置为1,AD转换时设置为0或1均可;
  • 第5/4位,选择模拟电压输出方式;
  • 第3位,默认为0;
  • 第2位,是自动增量使能位,设置1后,每次A/D 转换后通道号将自动增加;
  • 第1/0位,是在AD转换时选择输入的电压转换为数字量的通道。
    便携式人体脉搏检测系统(1)

3.ADC

将AIN端口输入的模拟电压转换为数字量并发送到总线上。
便携式人体脉搏检测系统(1)

uchar Read_D(uchar Channel)        
{
    uchar dat;    //定义缓存变量
    start();     //启动I2C总线
    write_byte(0x90);        //向总线写入从机地址09x0,表示下一个字节向总线写入数据    ,+0,主机发送数据            
    ack();    //应答信号
    write_byte(Channel);     //向总线写入控制字Channel表示通道1        
    ack();    //应答信号
    start();     //重复启动I2C总线,读写方向和上一次相反
    write_byte(0x91);        //向总线写入从机地址09x1,表示下一个字节从总线读取数据    ,+1,主机接收数据                        
    ack();    //应答信号
    dat=read_byte();    //读取数据并赋给变量dat                    
    ack();    //应答信号
    stop();    //停止I2C总线
    return dat;   //返回读取的数据值
}

4.DAC

将从总线上接收到的数字量通过AOUT输出。
便携式人体脉搏检测系统(1)

void Out_A(uchar Digital)              
{
    start();     //启动I2C总线
    write_byte(0x90);        //向总线写入主机地址09x0,表示下一个字节向总线写入数据,+0,主机发送数据                      
    ack();   //应答信号
    write_byte(0x40);     //向总线写入控制字0x40,允许模拟输出,不自增单端,通道0             
    ack();   //应答信号
    write_byte(Digital);        //向总线写入要转换的数字量Digital
    ack();   //应答信号 
    stop();   //停止I2C总线          
}

主函数

void main()
{
    I2C_init() ;    //I2C总线初始化
    dat1 = Read_D(0x01);    //将通道1的模拟量转化为数字量,并读取  
    delay();    
    Out_A(dat1);     //将数字量转化为模拟量输出                       
    delay(); 
}

END!