main.c
#include "stm32f10x.h"
#include "bsp_usart.h"
#include "bsp_i2c.h"
//1.初始化IIC相关的GPIO
//2.配置IIC外设的工作模式
//3.编写IIC写入EEPROM的Byte Write函数
//4.编写IIC读取EEPROM Read函数
//5.使用read函数及write函数进行校验
//6.编写page write 及seq read函数并校验
uint8_t readData[10]={0};
int main(void)
{
/*初始化USART 配置模式为 115200 8-N-1,中断接收*/
USART_Config();
printf("这是一个IIC通讯实验\n");
//初始化IIC
I2C_EE_Config();
//写入一个字节
EEPROM_Byte_Write(11,0x55);
EEPROM_WaitForWriteEnd();
EEPROM_Byte_Write(12,0x52);
//等待写入操作完成
EEPROM_WaitForWriteEnd();
//读取数据
EEPROM_Read(11,readData,2);
printf("\r\n接收到的数据为0x%x,0x%x\r\n",readData[0],readData[1]);
while(1)
{
}
}
结果
bsp_i2c.c
#include "bsp_i2c.h"
/**
* @brief i2c EEPROM(AT24C02)配置,工作参数配置 应用函数bsp
*/
void I2C_EE_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
// 打开IIC GPIO的时钟
EEPROM_I2C_GPIO_APBxClkCmd(EEPROM_I2C_SCL_GPIO_CLK|EEPROM_I2C_SDA_GPIO_CLK, ENABLE);
// 打开IIC 外设的时钟
EEPROM_I2C_APBxClkCmd(EEPROM_I2C_CLK, ENABLE);
// 将IIC SCL的GPIO配置为推挽复用模式
GPIO_InitStructure.GPIO_Pin = EEPROM_I2C_SCL_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(EEPROM_I2C_SCL_GPIO_PORT, &GPIO_InitStructure);
// 将IIC SDA的GPIO配置为浮空输入模式
GPIO_InitStructure.GPIO_Pin = EEPROM_I2C_SDA_GPIO_PIN;
GPIO_Init(EEPROM_I2C_SDA_GPIO_PORT, &GPIO_InitStructure);
// 配置IIC的工作参数
I2C_InitStructure.I2C_Ack =I2C_Ack_Enable ; //使能应答
I2C_InitStructure.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit;//使用7位地址模式
I2C_InitStructure.I2C_ClockSpeed=EEPROM_I2C_BAUDRATE; //配置SCL时钟频率
I2C_InitStructure.I2C_DutyCycle =I2C_DutyCycle_2 ;
I2C_InitStructure.I2C_Mode =I2C_Mode_I2C;
I2C_InitStructure.I2C_OwnAddress1=STM32_I2C_OWN_ADDR;//这是STM32 IIC自身设备地址,只要是总线上唯一即可
I2C_Init(EEPROM_I2C, &I2C_InitStructure);
// 使能串口
I2C_Cmd(EEPROM_I2C, ENABLE);
}
//向EEPROM写入一个字节
void EEPROM_Byte_Write(uint8_t addr,uint8_t data)
{
//产生起始信号
I2C_GenerateSTART(EEPROM_I2C, ENABLE);
while (I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_MODE_SELECT)==ERROR);
//EV5事件被检测到,发送设备地址
I2C_Send7bitAddress(EEPROM_I2C,EEPROM_ADDR,I2C_Direction_Transmitter);
while (I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED )==ERROR);
//EV6事件被检测到,发送要操作的存储单元地址
I2C_SendData( EEPROM_I2C,addr);
while (I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_BYTE_TRANSMITTING)==ERROR);
//EV8事件被检测到,发送要操作的数据
I2C_SendData( EEPROM_I2C,data);
while (I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_BYTE_TRANSMITTED)==ERROR);
//数据传输完成
I2C_GenerateSTOP(EEPROM_I2C,ENABLE);
}
//向EEPROM读取数据
void EEPROM_Read(uint8_t addr,uint8_t* data,uint8_t numByteToRead)
{
//产生起始信号
I2C_GenerateSTART(EEPROM_I2C, ENABLE);
while (I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_MODE_SELECT)==ERROR);
//EV5事件被检测到,发送设备地址
I2C_Send7bitAddress(EEPROM_I2C,EEPROM_ADDR,I2C_Direction_Transmitter);
while (I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED )==ERROR);
//EV6事件被检测到,发送要操作的存储单元地址
I2C_SendData( EEPROM_I2C,addr);
while (I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_BYTE_TRANSMITTING)==ERROR);
//第二次起始信号
//产生起始信号
I2C_GenerateSTART(EEPROM_I2C, ENABLE);
while (I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_MODE_SELECT)==ERROR);
//EV5事件被检测到,发送设备地址
I2C_Send7bitAddress(EEPROM_I2C,EEPROM_ADDR,I2C_Direction_Receiver );
while (I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED )==ERROR);
while(numByteToRead)
{
if(numByteToRead=1)
{
//如果为最后一个字节
I2C_AcknowledgeConfig(EEPROM_I2C,DISABLE);
}
//EV7事件被检测到,发送要操作的存储单元地址
while (I2C_CheckEvent(EEPROM_I2C,I2C_EVENT_MASTER_BYTE_RECEIVED)==ERROR);
//EV7事件被检测到,即数据寄存器有新的有效数据
* data = I2C_ReceiveData(EEPROM_I2C);
data++;
numByteToRead--;
}
//数据传输完成
I2C_GenerateSTOP(EEPROM_I2C,ENABLE);
//重新配置ACK使能,以便下次通讯
I2C_AcknowledgeConfig(EEPROM_I2C,ENABLE);
}
//等待EEPROM内部时序完成
void EEPROM_WaitForWriteEnd(void)
{
do
{
//产生起始信号
I2C_GenerateSTART(EEPROM_I2C, ENABLE);
while (I2C_GetFlagStatus(EEPROM_I2C,I2C_FLAG_SB)==RESET);
//EV5事件被检测到,发送设备地址
I2C_Send7bitAddress(EEPROM_I2C,EEPROM_ADDR,I2C_Direction_Transmitter);
}
while (I2C_GetFlagStatus(EEPROM_I2C,I2C_FLAG_ADDR )==RESET);
//EEPROM内部时序完成传输完成
I2C_GenerateSTOP(EEPROM_I2C,ENABLE);
} |
|