51_LanQiaoBei/模板/蓝桥杯全模块测试例程/EEPROM存储模块/Driver/iic.c

206 lines
3.9 KiB
C
Raw Normal View History

2025-04-13 01:02:19 +08:00
/* # I2C代码片段说明
1.
2.
*/
#include "iic.h"
#include "intrins.h"
#define DELAY_TIME 5
sbit scl = P2 ^ 0;
sbit sda = P2 ^ 1;
//
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);
}
unsigned char Ad_Read(unsigned char addr)
{
unsigned char temp;
// 选择芯片为PCF
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
temp = I2CReceiveByte();
I2CSendAck(1);
I2CStop();
return temp;
}
// 写入的值是数字值0-255而不是模拟值
void Da_Write(unsigned char dat)
{
// 选择芯片为PCF
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x41);
I2CWaitAck();
I2CSendByte(dat);
I2CWaitAck();
I2CStop();
}
/// @brief EEPROM 写函数
/// @param EEPROM_String 写入的数组指针(如果只写入一个数据,那么要用&data
/// @param addr 8的倍数
/// @param num 写入的数组大小
void EEPROM_Write(unsigned char *EEPROM_String, unsigned char addr, unsigned char num)
{
// 选择芯片为EEPROM模式为写
I2CStart();
I2CSendByte(0xA0);
I2CWaitAck();
I2CSendByte(addr); // 写入的数据的地址
I2CWaitAck();
while (num--)
{
I2CSendByte(*EEPROM_String++);
I2CWaitAck();
I2C_Delay(200);
}
I2CStop();
}
/// @brief EEPROM 读函数
/// @param EEPROM_String 读取的数组指针(如果只读取一个数据,那么要用&data
/// @param addr 8的倍数
/// @param num 读取的数组大小
void EEPROM_Read(unsigned char *EEPROM_String, unsigned char addr, unsigned char num)
{
// 选择芯片为EEPROM模式为写
I2CStart();
I2CSendByte(0xA0);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
// 选择芯片为EEPROM模式为读
I2CStart();
I2CSendByte(0xA1);
I2CWaitAck();
while (num--)
{
*EEPROM_String++ = I2CReceiveByte();
if (num)
I2CSendAck(0);
else
I2CSendAck(1); // 停止读取
}
I2CStop();
}