(三)、光敏、分压传感器
1、IIC通信协议
I2C 协议采用双线结构传输数据,包括一个数据线和一个时钟线(即 SDA 和 SCL 线),其中 SDA(Serial Data)线用于双向数据传输,而 SCL(Serial Clock)线则用于同步数据传输的时钟信号。通信始终由主设备(Master)控制,从设备(Slave)被动接收和回应。这种简单的线路连接方式使得设备之间的互连变得非常容易。下图即是 I2C 的基本结构。
在蓝桥杯中,I2C协议主要用于AT24C02储存与读取、光敏电阻的读取、电压采集、DA等功能,现在我们暂时只介绍光敏电阻。
通信协议官方会给出,我们只需要学会用分装的函数就行,包括通信起始信号、停止信号、发送一个字节数据、接收一个字节数据、发送反馈(主机是否继续接收、主机发送、从机接收)、接收反馈(判断从机是否收到,主机接收、从机发送)
为了操作方便,我们在开头sbit sda= P2^1;sbit scl = P2^0;这样在操作P2^0引脚电平时就可以直接操作scl(scl = 0与P2^0 = 0效果相同)。
下面我们简单介绍AD设备读取的时序。(如图 十七)
① 初始化(通信起始信号)
②发送I2C设备地址 (高七位是设备地址,最后一位是读写位,写为0,读取为1,A2、A1、A0置0,**开始写操作0x90,**如图 十六)
③从机发送反馈应答(从机发送0表明接收成功)
④写入从机地址 (光敏0x41,分压电阻0x43,差分输入0x42)
⑤从机发送反馈应答
⑥重新初始化(读与写之间必须重新初始化)
⑦发送I2C设备地址开始读操作
⑧读取数据( 继续读主机发送0、不再读取主机发送1)
⑨停止信号

图 十五 I2C 的基本结构

图 十六 I2C 设备地址

图 十七 IIC 通信过程(AD)
2、代码解读(图 十八)
实际使用时只需要调用函数 AD_Read(从机地址),记得填写从机地址,通常会将0-255范围光敏阻值转化为0-5.0V电压,只需将获得的AD数据/51.0即可完成。

图 十八 代码解读(AD数据读取)
(四)、DA
1、DA时序图
下面我们简单介绍AD设备读取的时序。(如图 十九)
①初始化(通信起始信号)
②发送I2C设备地址 (高七位是设备地址,最后一位是读写位,写为0,读取为1,A2、A1、A0置0,**开始写操作0x90,**如图 十六)
③从机发送反馈应答(从机发送0表明接收成功)
④写入数据0x41(打开DA通道)
⑤从机发送反馈应答
⑥写入DA数据(写入数据0-255对应0-5V)
⑦从机发送反馈应答
⑧停止信号

图 十九 DA 写入时序
2、DA代码展示

图 二十 DA代码展示
附参考代码如下,希望对友友有帮助
cs
#include <STC15F2K60S2.H>
#include <INTRINS.H>
sbit sda = P2^1;
sbit scl = P2^0;
#define DELAY_TIME 5
//
static void I2C_Delay(unsigned char n)
{
do
{
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
}
while(n--);
}
//
void I2CStart(void)
{
sda = 1;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 0;
I2C_Delay(DELAY_TIME);
scl = 0;
}
//
void I2CStop(void)
{
sda = 0;
scl = 1;
I2C_Delay(DELAY_TIME);
sda = 1;
I2C_Delay(DELAY_TIME);
}
//
void I2CSendByte(unsigned char byt)
{
unsigned char i;
for(i=0; i<8; i++){
scl = 0;
I2C_Delay(DELAY_TIME);
if(byt & 0x80){
sda = 1;
}
else{
sda = 0;
}
I2C_Delay(DELAY_TIME);
scl = 1;
byt <<= 1;
I2C_Delay(DELAY_TIME);
}
scl = 0;
}
//
unsigned char I2CReceiveByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++){
scl = 1;
I2C_Delay(DELAY_TIME);
da <<= 1;
if(sda)
da |= 0x01;
scl = 0;
I2C_Delay(DELAY_TIME);
}
return da;
}
//
unsigned char I2CWaitAck(void)
{
unsigned char ackbit;
scl = 1;
I2C_Delay(DELAY_TIME);
ackbit = sda;
scl = 0;
I2C_Delay(DELAY_TIME);
return ackbit;
}
//
void I2CSendAck(unsigned char ackbit)
{
scl = 0;
sda = ackbit;
I2C_Delay(DELAY_TIME);
scl = 1;
I2C_Delay(DELAY_TIME);
scl = 0;
sda = 1;
I2C_Delay(DELAY_TIME);
}
/*
IIC通信过程
1、AD通信--读取数据
I2CStart()起始信号
开始写操作0x90 I2CSendByte(0x90)
等待反馈 I2CWaitAck()
写入从机地址 I2CSendByte(Address)
等待反馈 I2CWaitAck()
重新开始,开始读操作0x91 I2CStart() I2CSendByte(0x91)
读取数据并发送反馈
返回数据
停止I2CStop()
2、DA通信
I2CStart()起始信号
开始写操作0x90
等待反馈
写操作0x41打开通道 I2CSendByte(0x41)
等待反馈
写入数据
等待反馈
停止I2CStop()
*/
void DA_Write(unsigned char Data)
{
I2CStart();
I2CSendByte(0x90); //开始写操作
I2CWaitAck();
I2CSendByte(0x41); //打开DA通道
I2CWaitAck();
I2CSendByte(Data); //写入数据
I2CWaitAck();
I2CStop();
}
unsigned char AD_Read(unsigned char Address) //Address--0x43是分压电阻、0x41光敏电阻
{
unsigned char temp;
I2CStart();
I2CSendByte(0x90); //开始写操作
I2CWaitAck();
I2CSendByte(Address); //写入从机地址
I2CWaitAck();
I2CStart();
I2CSendByte(0x91); //开始读操作
I2CWaitAck();
temp = I2CReceiveByte(); //读取数据并反馈
I2CSendAck(1); //停止读取
I2CStop();
return temp;
}