本文共 3631 字,大约阅读时间需要 12 分钟。
IIC是一种多向控制总线,也就是说多个芯片可以连接到同一总线结构下,同时每个芯片都可以作为实时数据传输的控制源。主要包括启始、停止、读、写、应答信号。这种方式简化了信号传输总线接口。
IIC总线上可以挂多个器件,而每个器件都有唯一的地址,这样可以标识通信目标。数据的通信的方式采用主从方式,主机负责主动联系从机,而从机则被动回应数据。
(1)开始和停止信号
void start(){ SDA = 1; //初始时,SDA=1 SCL = 1; //初始时,SCL=1 delay(); //保持时间大于4.7us SDA = 0; //SDA下降沿 delay(); //SDA下降沿保持时间大于4.0us}
void stop(){ SDA = 0; //初始时,SDA=0; SCL = 1; //初始时,SCL=1; delay(); //保持时间大于4.0us SDA = 1; //SDA上升沿 delay(); //保持时间大于4.7us}
(2)应答信号
void ack(){ uchar i = 0; //定义缓冲变量 SCL = 1; delay(); while(SDA == 1 && i < 250)i++; //稳定时间大于4us SCL = 0; //SCL=0时,SDA数据才可以改变 delay();}
(2)数据传送流程:
a.写入数据
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.读取数据
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值}
void I2C_init() { SDA = 1; delay(); SCL = 1; delay();}
PCF8591是单片、单电源低功耗8位CMOS数据采集器件,具有4个模拟输入、一个输出和一个串行I2C总线接口。3个地址引脚A0、A1 和A2 用于编程硬件地址,允许将最多8个器件连接至I2C总线而不需要额外硬件。器件的地址、控制和数据通过两线双向I2C总线传输。器件功能包括多路复用模拟输入、片上跟踪和保持功能、8位模数转换和8位数模拟转换。最大转换速率取决于I2C总线的最高速率。
总线启动后,发送的第一个字节。
由电路原理图可知,A0 A1 A2均为0,所以:总线启动后,发送的第二个字节。
将AIN端口输入的模拟电压转换为数字量并发送到总线上。
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; //返回读取的数据值}
将从总线上接收到的数字量通过AOUT输出。
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!
转载地址:http://qacjo.baihongyu.com/