蓝桥杯----DA、AD
(三)、光敏、分压传感器
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代码展示
附参考代码如下,希望对友友有帮助
#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;
}