51_LanQiaoBei/模板/蓝桥杯全模块测试例程/EEPROM存储模块/Driver/iic.c
2025-04-13 01:02:19 +08:00

206 lines
3.9 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* # 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();
}