- #include "main.h"
- #include "i2c.h"
- /**
- * PB6 PB7 初始化为I2C1 i2c master 模式
- * PB10 PB11 初始化为I2C2 i2c slaver 模式
- */
- #define I2CT_FLAG_TIMEOUT ((uint32_t)0x1000)
- #define I2CT_LONG_TIMEOUT ((uint32_t)(10 * I2CT_FLAG_TIMEOUT))
- #define I2C_SLAVE_ADDR 0xA0
- static __IO uint32_t I2CTimeout;
- static CommCtrl_t Comm_Flag = C_READY;
- static void CommTimeOut_CallBack(ErrCode_t errcode)
- {
- max_print("...ErrCode:%d\r\n", errcode);
-
- #if (COMM_RECOVER_MODE == MODULE_SELF_RESET)
- IIC_SWReset();
- #elif (COMM_RECOVER_MODE == MODULE_RCC_RESET)
- IIC_RCCReset();
- #elif (COMM_RECOVER_MODE == SYSTEM_NVIC_RESET)
- SystemNVICReset();
- #endif
- }
- static void Delay(uint32_t nCount)
- {
- uint32_t tcnt;
- while (nCount--)
- {
- tcnt = 48000 / 5;
- while (tcnt--){;}
- }
- }
- static void Delay_us(uint32_t nCount)
- {
- uint32_t tcnt;
- while (nCount--)
- {
- tcnt = 48 / 5;
- while (tcnt--){;}
- }
- }
- MI_BOOL i2c1_init(void)
- {
- /** GPIO configuration and clock enable */
- GPIO_InitType GPIO_InitStructure;
- I2C_InitType I2C_InitStructure;
- #if PROCESS_MODE == 1 // interrupt
- NVIC_InitType NVIC_InitStructure;
- #endif
- /** enable peripheral clk*/
- RCC_APB1_Peripheral_Clock_Enable(RCC_APB1_PERIPH_I2C1);
- /* I2C1 Reset */
- RCC_APB1_Peripheral_Reset(RCC_APB1_PERIPH_I2C1);
- RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_GPIOB);
- GPIO_Structure_Initialize(&GPIO_InitStructure);
- GPIO_InitStructure.Pin = GPIO_PIN_6 | GPIO_PIN_7;
- GPIO_InitStructure.GPIO_Slew_Rate = GPIO_SLEW_RATE_SLOW;
- GPIO_InitStructure.GPIO_Mode = GPIO_MODE_AF_OD;
- GPIO_InitStructure.GPIO_Alternate = GPIO_AF2_I2C1;
- GPIO_InitStructure.GPIO_Pull = GPIO_PULL_UP;
- GPIO_Peripheral_Initialize(GPIOB, &GPIO_InitStructure);
- /** I2C periphral configuration */
- RCC_APB1_Peripheral_Reset(RCC_APB1_PERIPH_I2C1);
- I2C_InitStructure.BusMode = I2C_BUSMODE_I2C;
- I2C_InitStructure.DutyCycle = I2C_FMDUTYCYCLE_2;
- I2C_InitStructure.OwnAddr1 = 0xff;
- I2C_InitStructure.AckEnable = I2C_ACKEN;
- I2C_InitStructure.AddrMode = I2C_ADDR_MODE_7BIT;
- I2C_InitStructure.ClkSpeed = 400000; //400K
- I2C_Initializes(I2C1, &I2C_InitStructure);
-
- I2C_ON(I2C1);
- return MI_TRUE;
- }
- /**
- * i2c1 挂着一个AT24C02
- * 我们写入一个字节,读一个字节
- * 验证iic读写的函数即可。
- */
- MI_BOOL i2c_master_send_bytes_by_addr(MI_U8 slave_addr,MI_U8 reg_addr,MI_U8 *w_data,MI_U16 len)
- {
- I2CTimeout = I2CT_LONG_TIMEOUT;
- while (I2C_Flag_Status_Get(I2C1, I2C_FLAG_BUSY))
- {
- if ((I2CTimeout--) == 0)
- CommTimeOut_CallBack(MASTER_BUSY);
- }
- /** Send START condition */
- I2C_Generate_Start_Enable(I2C1);
- /** Test on EV5 and clear it */
- I2CTimeout = I2CT_LONG_TIMEOUT;
- while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_MODE_FLAG)) /*EV5*/
- {
- if ((I2CTimeout--) == 0)
- CommTimeOut_CallBack(MASTER_MODE);
- }
- /** Send slave address for write */
- I2C_7bit_Addr_Send(I2C1, slave_addr, I2C_DIRECTION_SEND);
- /** Test on EV6 and clear it */
- I2CTimeout = I2CT_LONG_TIMEOUT;
- while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_TXMODE_FLAG))
- {
- if ((I2CTimeout--) == 0)
- CommTimeOut_CallBack(MASTER_TXMODE);
- }
- I2C_Data_Send(I2C1, reg_addr);
- /** Test on EV8 and clear it */
- I2CTimeout = I2CT_LONG_TIMEOUT;
- while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_SENDED))
- {
- if ((I2CTimeout--) == 0)
- CommTimeOut_CallBack(MASTER_SENDED);
- }
- /** While there is data to be written */
- while (len--)
- {
- /** Send the current byte */
- I2C_Data_Send(I2C1, *w_data);
- /** Point to the next byte to be written */
- w_data++;
- /** Test on EV8 and clear it */
- I2CTimeout = I2CT_LONG_TIMEOUT;
- while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_SENDED))
- {
- if ((I2CTimeout--) == 0)
- CommTimeOut_CallBack(MASTER_SENDED);
- }
- }
- /** Send STOP condition */
- I2C_Generate_Stop_Enable(I2C1);
- return MI_TRUE;
- }
- MI_BOOL i2c_master_receive_bytes_by_addr(MI_U8 slave_addr,MI_U8 reg_addr,MI_U8 *r_data,MI_U16 len)
- {
- I2CTimeout = I2CT_LONG_TIMEOUT;
- while (I2C_Flag_Status_Get(I2C1, I2C_FLAG_BUSY))
- {
- if ((I2CTimeout--) == 0)
- CommTimeOut_CallBack(MASTER_BUSY);
- }
- I2C_PEC_Position_Set(I2C1, I2C_PEC_POS_CURRENT);
- I2C_Acknowledg_Enable(I2C1);
-
- /** Send START condition */
- I2C_Generate_Start_Enable(I2C1);
- /** Test on EV5 and clear it */
- I2CTimeout = I2CT_LONG_TIMEOUT;
- while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_MODE_FLAG))
- {
- if ((I2CTimeout--) == 0)
- CommTimeOut_CallBack(MASTER_MODE);
- }
- /** Send slave address for write */
- I2C_7bit_Addr_Send(I2C1, slave_addr, I2C_DIRECTION_SEND);
- /** Test on EV6 and clear it */
- I2CTimeout = I2CT_LONG_TIMEOUT;
- while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_TXMODE_FLAG))
- {
- if ((I2CTimeout--) == 0)
- CommTimeOut_CallBack(MASTER_TXMODE);
- }
- I2C_ON(I2C1);
- /** Send the slave's internal address to write to */
- I2C_Data_Send(I2C1, reg_addr);
- /** Test on EV8 and clear it */
- I2CTimeout = I2CT_LONG_TIMEOUT;
- while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_SENDED))
- {
- if ((I2CTimeout--) == 0)
- CommTimeOut_CallBack(MASTER_SENDED);
- }
- I2C_Generate_Stop_Enable(I2C1);
- /** Send STRAT condition a second time */
- I2C_Generate_Start_Enable(I2C1);
- /** Test on EV5 and clear it */
- I2CTimeout = I2CT_LONG_TIMEOUT;
- while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_MODE_FLAG))
- {
- if ((I2CTimeout--) == 0)
- CommTimeOut_CallBack(MASTER_MODE);
- }
- /** Send slave address for read */
- I2C_7bit_Addr_Send(I2C1, slave_addr, I2C_DIRECTION_RECV);
- /* Test on EV6 and clear it */
- I2CTimeout = I2CT_LONG_TIMEOUT;
- while (!I2C_Flag_Status_Get(I2C1, I2C_FLAG_ADDRF)) //EV6
- {
- if ((I2CTimeout--) == 0)
- CommTimeOut_CallBack(MASTER_RECVD);
- }
- /** While there is data to be read */
- if (len == 1)
- {
- /** Disable Acknowledgement */
- I2C_Acknowledg_Disable(I2C1);
- /** clear ADDR */
- (void)(I2C1->STS1);
- (void)(I2C1->STS2);
- /** Generates START condition to close communication */
- I2C_Generate_Start_Enable(I2C1);
- }
- else
- {
- /** clear ADDR */
- (void)(I2C1->STS1);
- (void)(I2C1->STS2);
- }
- while (len)
- {
- if (len <= 2)
- {
- /** One byte */
- if (len == 1)
- {
- /** Wait until RXNE flag is set */
- I2CTimeout = I2CT_LONG_TIMEOUT;
- while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_RECVD_FLAG))
- {
- if ((I2CTimeout--) == 0)
- CommTimeOut_CallBack(MASTER_RECVD);
- }
- /** Read data from DAT */
- *r_data = I2C_Data_Recv(I2C1);
- /** Point to the next location where the byte read will be saved */
- r_data++;
- /** Decrement the read bytes counter */
- len--;
- /** Generates STOP condition to release SCL/SDA line */
- I2C_Generate_Stop_Enable(I2C1);
-
- }
- /** 2 Last bytes */
- else
- {
- /** Wait until RXNE flag is set */
- I2CTimeout = I2CT_LONG_TIMEOUT;
- while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_RECVD_FLAG))
- {
- if ((I2CTimeout--) == 0)
- CommTimeOut_CallBack(MASTER_RECVD);
- }
- /** Disable Acknowledgement */
- I2C_Acknowledg_Disable(I2C1);
-
- /** Read data from DAT */
- *r_data = I2C_Data_Recv(I2C1);
- /** Point to the next location where the byte read will be saved */
- r_data++;
- /** Decrement the read bytes counter */
- len--;
-
- /** Generates START condition to close communication */
- I2C_Generate_Start_Enable(I2C1);
-
- while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_RECVD_FLAG))
- {
- if ((I2CTimeout--) == 0)
- CommTimeOut_CallBack(MASTER_RECVD);
- }
- /** Read data from DAT */
- *r_data = I2C_Data_Recv(I2C1);
- /** Point to the next location where the byte read will be saved */
- r_data++;
- /** Decrement the read bytes counter */
- len--;
-
- /** Generates STOP condition to release SCL/SDA line */
- I2C_Generate_Stop_Enable(I2C1);
- }
- }
- else
- {
- /** Test on EV7 and clear it */
- I2CTimeout = I2CT_LONG_TIMEOUT;
- while (!I2C_Event_Check(I2C1, I2C_EVT_MASTER_DATA_RECVD_FLAG))
- {
- if ((I2CTimeout--) == 0)
- CommTimeOut_CallBack(MASTER_RECVD);
- }
- /** Read a byte from the EEPROM */
- *r_data = I2C_Data_Recv(I2C1);
- /** Point to the next location where the byte read will be saved */
- r_data++;
- /** Decrement the read bytes counter */
- len--;
- if (I2C_Flag_Status_Get(I2C1, I2C_FLAG_BYTEF))
- {
- /** Read a byte from the EEPROM */
- *r_data = I2C_Data_Recv(I2C1);
- /** Point to the next location where the byte read will be saved */
- r_data++;
- /** Decrement the read bytes counter */
- len--;
- }
- }
- }
- return MI_TRUE;
- }
i2c.h
- #ifndef __I2C_H__
- #define __I2C_H__
- #include "type.h"
- #define NON_REENTRANT
- typedef enum
- {
- FAILED = 0,
- PASSED = !FAILED
- } Status;
- typedef enum
- {
- C_READY = 0,
- C_START_BIT,
- C_STOP_BIT
- }CommCtrl_t;
- typedef enum
- {
- MASTER_OK = 0,
- MASTER_BUSY,
- MASTER_MODE,
- MASTER_TXMODE,
- MASTER_RXMODE,
- MASTER_SENDING,
- MASTER_SENDED,
- MASTER_RECVD,
- MASTER_BYTEF,
- MASTER_BUSERR,
- MASTER_UNKNOW,
- SLAVE_OK = 20,
- SLAVE_BUSY,
- SLAVE_MODE,
- SLAVE_BUSERR,
- SLAVE_UNKNOW,
- }ErrCode_t;
- #define MODULE_SELF_RESET 1
- #define MODULE_RCC_RESET 2
- #define SYSTEM_NVIC_RESET 3
- #define COMM_RECOVER_MODE 0
- MI_BOOL i2c1_init(void);
- MI_BOOL i2c_master_send_bytes_by_addr(MI_U8 slave_addr,MI_U8 reg_addr,MI_U8 *w_data,MI_U16 len);
- MI_BOOL i2c_master_receive_bytes_by_addr(MI_U8 slave_addr,MI_U8 reg_addr,MI_U8 *r_data,MI_U16 len);
- #endif
- MI_U8 w_read[5] = {0x50,0x60,0x70,0xf4,0x68};
- SysTick_Delay_Ms(5000);
- i2c1_init();
- i2c_master_send_bytes_by_addr(0xa0,0x00,w_read,5);
- SysTick_Delay_Us(5000);
- MI_U8 r_data[5] = {0};
- i2c_master_receive_bytes_by_addr(0xa0,0x00,r_data,5);