I2C1 Master的设置 1、将PB6 PB7 初始化为I2C1 的 master 模式,然后往AT24C02里写五个数据,然后读出来。 2、在Common里增加i2c.c i2c.h文件 i2c.c #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);
|
|