- #include "mpu_i2c.h"
- #include "usart.h"
- //配置i2c端口
- void I2C_GPIO_Config(void)
- {
- //定义结构体
- GPIO_InitTypeDef GPIO_InitStruct;
-
- //打开SDA与SCL端口时钟
- RCC_APB2PeriphClockCmd(I2C_SDA_CLK,ENABLE);
- RCC_APB2PeriphClockCmd(I2C_SCL_CLK,ENABLE);
-
- //配置SDA端口
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;//开漏复用输出
- GPIO_InitStruct.GPIO_Pin = I2C_SDA_Pin;
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(I2C_SDA_PORT,&GPIO_InitStruct);
- //配置SCL端口
- GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;//开漏复用输出
- GPIO_InitStruct.GPIO_Pin = I2C_SCL_Pin;
- GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(I2C_SCL_PORT,&GPIO_InitStruct);
- }
- void I2C_InitConfig(void)
- {
- I2C_GPIO_Config();
- }
- void delay(void)
- {
- uint8_t time = 10;
- while(time--)
- {
- }
- }
- void I2C_START(void)
- {
- SDA_OUT();
- I2C_SDA_1();
- I2C_SCL_1();
- delay();
- I2C_SDA_0();
- delay();
- I2C_SCL_0();
- delay();
- }
- void I2C_STOP(void)
- {
- SDA_OUT();
- I2C_SDA_0();
- I2C_SCL_1();
- delay();
- I2C_SDA_0();
- delay();
- }
- void I2C_Ack(void)
- {
- I2C_SCL_0();
- I2C_SDA_1();
- delay();
- I2C_SDA_1();
- delay();
- I2C_SDA_0();
- delay();
- I2C_SCL_1();
- delay();
- I2C_SCL_0();
- delay();
- I2C_SDA_1();
- }
- void I2C_NACK(void)
- {
- I2C_SCL_0();
- I2C_SDA_0() ;
- delay();
- I2C_SDA_1();
- delay();
- I2C_SCL_1();
- delay();
- I2C_SCL_0();
- delay();
- I2C_SDA_0();
- delay();
- }
- void I2C_Sent_Byte(uint8_t msg)
- {
- uint8_t i;
- SDA_OUT();
- I2C_SCL_0();
- delay();
- /* 先发送字节的高位bit7 */
- for (i = 0; i < 8; i++)
- {
- if (msg & 0x80 ==1)
- {
- I2C_SDA_1();
- }
- else
- {
- I2C_SDA_0();
- }
- delay();
- I2C_SCL_1();
- delay();
- I2C_SCL_0();
- if (i == 7)
- {
- I2C_SDA_1(); // 释放总线
- }
- msg <<= 1; /* 左移一个bit */
- delay();
- }
- I2C_SCL_0();
- }
- uint8_t I2C_Read_Byte(void)
- {
- uint8_t i;
- uint8_t receive = 0;
-
- /* 读到的第一位为数据的7bit位!!!
- 所以每次读取数据时都要将数据左移一位*/
-
- I2C_SCL_1();//锁定SCL线,确保其稳定
- for(i=0;i<8;i++)
- {
- receive <<= 1;
- I2C_SCL_0();//读取数据时拉低SCL
- delay();
- if(I2C_SDA_State() == 1)
- {
- receive++;
- }
- I2C_SCL_0();
- delay();
-
- }
-
- return receive;
- }
- void delay_us(uint8_t i)
- {
- while(i--)
- {
- }
- }
- uint8_t I2C_WaitAck(void)
- {
- uint8_t re;
- I2C_SDA_1(); /* CPU释放SDA总线 */
- delay();
- I2C_SCL_1(); /* CPU驱动SCL = 1, 此时器件会返回ACK应答 */
- delay();
- if (I2C_SDA_State()) /* CPU读取SDA口线状态 */
- {
- re = 1;
- }
- else
- {
- re = 0;
- }
- I2C_SCL_0();
- delay();
- return re;
- }
- uint8_t EEPROM_Byte_Write(uint16_t _usAddress, uint16_t data)
- {
- uint8_t i;
- //开始信号
- I2C_START();
- //发送地址
- I2C_Sent_Byte(Slave_Addr | I2C_Write);
- //检测应答
- //delay();
- //return printf("SDA的状态为:%d\n",I2C_SDA_State());
- if(I2C_WaitAck() != 0)
- {
- return printf("写入失败,未检测到响应1\n");
- }
- //发送从机中的数据地址(起始地址)
- I2C_Sent_Byte(_usAddress);
- //检测应答
- if(I2C_WaitAck() != 0)
- {
- return printf("写入失败,未检测到响应2\n");
- }
-
- for(i=0;i<8;i++)
- {
- I2C_Sent_Byte(data & 0x80);
- I2C_Ack();
- data <<= 1;
- }
- return printf("写入完成!!!\n");
- }
- uint8_t EEPROM_Byte_Read(uint8_t *_pReadBuf, uint16_t _usAddress, uint16_t _usSize)
- {
- uint8_t i;
- //开始信号
-
- //test SDA
- //return printf("开始信号前SDA状态为:%d\n",READ_I2C_SDA());
-
- I2C_START();
- //发送地址
-
- //test SDA
- //return printf("开始信号后SDA状态为:%d\n",READ_I2C_SDA());
-
- I2C_Sent_Byte(Slave_Addr | I2C_Write);
- //test SDA
- //return printf("发送地址后SDA状态为:%d\n",READ_I2C_SDA());
-
- //检测应答
- if(I2C_WaitAck() != 0)
- {
- return printf("读取失败,未检测到响应1\n");
- }
- //发送从机中的数据地址(起始地址)
- I2C_Sent_Byte(_usAddress);
- //检测应答
- if(I2C_WaitAck() != 0)
- {
- return printf("读取失败,未检测到响应2\n");
- }
- //开始信号
- I2C_START();
- //发送地址
- I2C_Sent_Byte(Slave_Addr | I2C_Read);
- //检测应答
- if(I2C_WaitAck() != 0)
- {
- return printf("读取失败,未检测到响应3\n");
- }
-
- //读取数据
- for(i=0;i< _usSize;i++)
- {
- // if(I2C_GetFlagStatus(I2C_Driver,I2C_FLAG_BUSY) == SET)
- // {
- // return printf("他妈的锁死了,读取失败\n");
- // }
-
- _pReadBuf[i] = I2C_Read_Byte();//每次读取一个字节
- if(i != (_usSize-1))
- {
- I2C_Ack();
- }
- else
- {
- I2C_NACK();
- }
- }
-
- //发送停止信号
- I2C_STOP();
-
- return printf("读取完成!\n");
-
- }
复制代码 |