- // 该代码用于测试没问题
-
- #define I2C_SCL_PORT GPIOB
- #define I2C_SCL_Pin GPIO_Pin_8
-
- #define I2C_SDA_PORT GPIOB
- #define I2C_SDA_Pin GPIO_Pin_9
-
- #define OUTPUT 0
- #define INPUT 1
-
- static void I2C_Tail(void); //发送结束标志
- static void I2C_Head(unsigned short Addrs); // 发送起始标志
-
- static void hal_I2C_Config(void); // 模拟I2C配置函数
- static void hal_I2C_SCL_SET(unsigned char i); // 设置时钟引脚
- static void hal_I2C_SDA_SET(unsigned char i); // 设置数据引脚
- static void hal_I2C_Start(void); // 起始标志
- static void hal_I2C_Stop(void); // 结束标志
- static void I2C_Delay(unsigned short t);
- static void I2C_ACK(void); // 有ACK应答
- static void I2C_NOACK(void); // 无ACK应答
- static void I2C_SendByte(unsigned char data); // 写一个byte数据时序
- static void I2C_WriteByte(unsigned short Addr, unsigned char data); // 发送一个byte
- static unsigned char I2C_RecvByte(void); // 读一个字节时序
- static unsigned char I2C_WaitAck(void); // 返回0,无应答数据 。返回1,有应答数据
-
- void hal_I2C_SDA_IO_SET(unsigned char IOMode); // OUTPUT 或者 INPUT
- unsigned char hal_IC_SDA_INPUT(void);
- unsigned char I2C_ReadByte(unsigned short Addr); // 读一个字节数据
-
-
- void hal_eeprom_Init(void)
- {
- hal_I2C_Config();
- }
-
- unsigned char I2C_ReadByte(unsigned short Addr)
- {
- unsigned char dat;
- hal_I2C_Start();
- I2C_SendByte(0xA0);
- I2C_WaitAck();
-
- I2C_SendByte((Addr>>8)&0xFF);
- I2C_WaitAck();
-
- I2C_SendByte(Addr&0xFF);
- I2C_WaitAck();
-
- hal_I2C_Start();
- I2C_SendByte(0xA1); // 发送 1010 0001 最低位的1代表从该芯片读取数据
- I2C_WaitAck();
-
- dat = I2C_RecvByte();
- I2C_NOACK();
- hal_I2C_Stop();
- return dat;
- }
-
- static unsigned char I2C_RecvByte(void)
- {
- unsigned char i = 0;
- unsigned char RecvByte = 0;
-
- hal_I2C_SCL_SET(0);
- I2C_Delay(1);
- hal_I2C_SDA_SET(1);
- hal_I2C_SDA_IO_SET(INPUT);
-
- for(; i < 8; i++)
- {
- RecvByte<<=1;
- I2C_Delay(1);
- hal_I2C_SCL_SET(1);
- I2C_Delay(1);
- if(hal_IC_SDA_INPUT()) {
- RecvByte |= 0x01;
- }
- hal_I2C_SCL_SET(0);
- }
- hal_I2C_SDA_IO_SET(OUTPUT);
- I2C_Delay(1);
- return RecvByte;
- }
-
- void hal_I2C_Read( unsigned short Addrs, unsigned char *pBuf, unsigned short Len)
- {
- unsigned short i = 0;
-
- I2C_Head(Addrs);
-
- hal_I2C_Start();
- I2C_SendByte(0xA1); // 发送 1010 0001 最低位的1代表从该芯片读取数据
- I2C_WaitAck();
-
- for( i = 0; i < Len; i++)
- {
- pBuf[i] = I2C_RecvByte();
- if(i == Len - 1) I2C_NOACK();
- else I2C_ACK();
- }
-
- hal_I2C_Stop();
- }
-
- static void I2C_WriteByte(unsigned short Addr, unsigned char data)
- {
- hal_I2C_Start(); // 发送有效数据起始标志
-
- // 该芯片最低位的一个bit位代表读/写:0 代表写入数据 || 1 代表读出数据
- I2C_SendByte(0xA0); // 发送需要通信的硬件地址(对应的硬件手册上有!!!!!)
- I2C_WaitAck();
-
- I2C_SendByte((Addr>>8)&0xFF); // 发送写入的地址(高字节地址)
- I2C_WaitAck();
-
- I2C_SendByte(Addr&0xFF); // 发送写入的地址(低字节地址)
- I2C_WaitAck();
-
- I2C_SendByte(data);
- I2C_WaitAck();
-
- hal_I2C_Stop(); // 发送有效数据结束标志
- I2C_Delay(20000);
- }
-
-
- static unsigned char I2C_WaitAck(void)
- {
- hal_I2C_SDA_SET(1);
- hal_I2C_SDA_IO_SET(INPUT); // 设置SDA引脚为输入引脚
- hal_I2C_SCL_SET(1);
- I2C_Delay(1);
- if(hal_IC_SDA_INPUT()) { // 该引脚为高电平,代表无应答
- hal_I2C_SDA_IO_SET(OUTPUT); // 设置SDA引脚为输出引脚
- return 0;
- }
-
- hal_I2C_SCL_SET(0);
- hal_I2C_SDA_IO_SET(OUTPUT);
- I2C_Delay(1);
- return 1;
- }
-
- static void I2C_Head(unsigned short Addrs)
- {
- hal_I2C_Start(); // 发送有效数据起始标志
-
- // 该芯片最低位的一个bit位代表读/写:0 代表写入数据 || 1 代表读出数据
- I2C_SendByte(0xA0); // 发送需要通信的硬件地址(对应的硬件手册上有!!!!!)
- I2C_WaitAck();
-
- I2C_SendByte((Addrs>>8)&0xFF); // 发送写入的地址(高字节地址)
- I2C_WaitAck();
-
- I2C_SendByte(Addrs&0xFF); // 发送写入的地址(低字节地址)
- I2C_WaitAck();
- }
-
- static void I2C_Tail(void)
- {
- hal_I2C_Stop(); // 发送有效数据结束标志
- I2C_Delay(20000);
- }
-
- void hal_I2C_Write(unsigned short Addrs, unsigned char* pBuf, unsigned short Len)
- {
- unsigned short tmp = 0;
- unsigned short i = 0, j = 0;
- unsigned short page = 0;
- unsigned short size;
-
- if(Addrs%EEPROM_PAGE_SIZE)
- {
- tmp = EEPROM_PAGE_SIZE-(Addrs%EEPROM_PAGE_SIZE); // 拿到当前页还有多少字节可写入
- if(tmp > Len)
- {
- tmp = Len; // 后续写入操作,需要tmp来做循环因子
- }
- }
- // 先将数据写入当前页
- if(tmp)
- {
- I2C_Head(Addrs);
- // 正式写入数据
- for(i = 0; i < tmp; i++)
- {
- I2C_SendByte(pBuf[i]);
- I2C_WaitAck();
- }
- I2C_Tail();
- }
-
- Len -= tmp; // 将已经发送过的数据个数减掉
- Addrs += tmp; // 将写入的地址更新
-
- page = Len/EEPROM_PAGE_SIZE; // int整形除法,只会得到整数
- size = Len%EEPROM_PAGE_SIZE; // 不足一页还有几个字节
-
- for(i = 0; i < page; i++)
- {
- I2C_Head(Addrs);
-
- for(j = 0; j < EEPROM_PAGE_SIZE; j++)
- {
- I2C_SendByte(pBuf[tmp + j]);
- I2C_WaitAck();
- }
- I2C_Tail();
- Addrs += EEPROM_PAGE_SIZE;
- tmp += EEPROM_PAGE_SIZE;
- }
-
- if(size)
- {
- I2C_Head(Addrs);
-
- for(i = 0; i < size; i++)
- {
- I2C_SendByte(pBuf[tmp + i]);
- I2C_WaitAck();
- }
- I2C_Tail();
- }
-
- }
-
- static void I2C_SendByte(unsigned char data)
- {
- unsigned char i = 0;
- for(; i < 8; i++)
- {
- hal_I2C_SCL_SET(0);
- I2C_Delay(1);
- if(data&0x80){
- hal_I2C_SDA_SET(1);
- } else {
- hal_I2C_SDA_SET(0);
- }
- I2C_Delay(1);
- hal_I2C_SCL_SET(1);
- I2C_Delay(1);
- data<<=1;
- }
-
- hal_I2C_SCL_SET(0);
- I2C_Delay(1);
- hal_I2C_SDA_SET(1);
- I2C_Delay(1);
- }
-
-
- static void I2C_ACK(void)
- {
- hal_I2C_SCL_SET(0);
- I2C_Delay(1);
- hal_I2C_SDA_SET(0); // SDA数据线置低,进行数据位应答。
- I2C_Delay(1);
- hal_I2C_SCL_SET(1);
- I2C_Delay(1);
- hal_I2C_SCL_SET(0);
- I2C_Delay(1);
- }
-
-
- static void I2C_NOACK(void)
- {
- hal_I2C_SCL_SET(0);
- I2C_Delay(1);
- hal_I2C_SDA_SET(1); // SDA数据线置高,不进行数据应答。
- I2C_Delay(1);
- hal_I2C_SCL_SET(1);
- I2C_Delay(1);
- hal_I2C_SCL_SET(0);
- I2C_Delay(1);
- }
-
- static void hal_I2C_Start(void)
- {
- hal_I2C_SDA_SET(1);
- I2C_Delay(1);
- hal_I2C_SCL_SET(1);
- I2C_Delay(1);
- hal_I2C_SDA_SET(0);
- I2C_Delay(1);
- }
-
- static void hal_I2C_Stop(void)
- {
- hal_I2C_SDA_SET(0);
- I2C_Delay(1);
- hal_I2C_SCL_SET(1);
- I2C_Delay(1);
- hal_I2C_SDA_SET(1);
- I2C_Delay(1);
- }
-
-
- static void hal_I2C_Config(void)
- {
- GPIO_InitTypeDef GPIO_Struct;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
-
- GPIO_Struct.GPIO_Mode = GPIO_Mode_Out_OD;
- GPIO_Struct.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Struct.GPIO_Pin = I2C_SCL_Pin | I2C_SDA_Pin;
- GPIO_Init(GPIOB, &GPIO_Struct);
-
- hal_I2C_SDA_SET(1);
- hal_I2C_SCL_SET(1);
-
- }
-
-
- void hal_I2C_SDA_IO_SET(unsigned char IOMode)
- {
- if(0 == IOMode) {
- GPIO_InitTypeDef GPIO_Struct;
- GPIO_Struct.GPIO_Mode = GPIO_Mode_Out_OD;
- GPIO_Struct.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Struct.GPIO_Pin = I2C_SDA_Pin;
- GPIO_Init(GPIOB, &GPIO_Struct);
- }
- if(1 == IOMode) {
- GPIO_InitTypeDef GPIO_Struct;
- GPIO_Struct.GPIO_Mode = GPIO_Mode_IPU;
- GPIO_Struct.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Struct.GPIO_Pin = I2C_SDA_Pin;
- GPIO_Init(GPIOB, &GPIO_Struct);
- }
- }
-
-
- static void hal_I2C_SDA_SET(unsigned char i)
- {
- if(i) {
- GPIO_SetBits(I2C_SDA_PORT,I2C_SDA_Pin);
- } else {
- GPIO_ResetBits(I2C_SDA_PORT,I2C_SDA_Pin);
- }
- }
-
-
- static void hal_I2C_SCL_SET(unsigned char i)
- {
- if(i) {
- GPIO_SetBits(I2C_SCL_PORT,I2C_SCL_Pin);
- } else {
- GPIO_ResetBits(I2C_SCL_PORT,I2C_SCL_Pin);
- }
- }
-
- static void I2C_Delay(unsigned short t)
- {
- unsigned short i=50,j,c;
- c = t;
- for(j=0; j<c; j++)
- {
- while(i)
- {
- i--;
- }
- }
- }
-
- unsigned char hal_IC_SDA_INPUT(void)
- {
- return GPIO_ReadInputDataBit(I2C_SDA_PORT, I2C_SDA_Pin);
- }
|