1. CubeMX生成工程
打开CubeMX,设置I2C和USART通信,然后生成工程:
2. keil实现功能
2.1 print重定向usart输出
打开C标准库 :
打开usart.c,添加头文件#include <stdio.h>
重写fputc函数:
int fputc(int ch,FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 1000);
return ch;
}
可以在main函数中printf("hello");测试是否成功。
2.2 I2C写EEPROM
EEPROM的型号为AT24C02,设备地址为0xA0
添加写函数:
/**
* @brief Write some data to EEPROM.
* @param pData Pointer to data buffer
* @param Size Amount of data to be sent
*/
void I2CWriteEEPROM(uint16_t MemAddress,uint8_t *pData, uint16_t Size)
{
//将不对齐字的只提取出来,8字节为1个字
uint16_t headBit=8-MemAddress%8;
uint16_t tmpAddress=MemAddress;
uint16_t remainBit;
uint8_t *ptmpData=pData;
//判断需要写的长度大于地址剩余字节
if(Size>headBit)
{
if(HAL_I2C_Mem_Write(&hi2c1, 0xA0,tmpAddress,I2C_MEMADD_SIZE_8BIT, ptmpData, headBit, 100)==HAL_OK)
HAL_Delay(5);
else
printf("\ntmpAddress=%d,fail",tmpAddress);
ptmpData=ptmpData+headBit;
tmpAddress=tmpAddress+headBit;
remainBit=Size-headBit;
//判断剩余的字节是否小于8
if((remainBit/8)==0)
{
if(HAL_I2C_Mem_Write(&hi2c1, 0xA0,tmpAddress,I2C_MEMADD_SIZE_8BIT, ptmpData, remainBit, 100)==HAL_OK)
HAL_Delay(5);
else
printf("\ntmpAddress=%d,fail",tmpAddress);
}
else
{
//循环写入EEPROM
while((remainBit/8)>0)
{
if(HAL_I2C_Mem_Write(&hi2c1, 0xA0,tmpAddress,I2C_MEMADD_SIZE_8BIT, ptmpData, 8, 100)==HAL_OK)
HAL_Delay(5);
else
printf("\ntmpAddress=%d,fail",tmpAddress);
HAL_Delay(5);
ptmpData=ptmpData+8;
tmpAddress=tmpAddress+8;
remainBit=remainBit-8;
if((remainBit/8)==0 && remainBit>0)
{
if(HAL_I2C_Mem_Write(&hi2c1, 0xA0,tmpAddress,I2C_MEMADD_SIZE_8BIT, ptmpData, remainBit, 100)==HAL_OK)
HAL_Delay(5);
else
printf("\ntmpAddress=%d,fail",tmpAddress);
}
}
}
}
else
{
if(HAL_I2C_Mem_Write(&hi2c1, 0xA0,tmpAddress,I2C_MEMADD_SIZE_8BIT, ptmpData, Size, 100)==HAL_OK)
{}
else
printf("\ntmpAddress=%d,fail",tmpAddress);
}
}
添加读EEPROM函数:
/**
* @brief Read some data from EEPROM.
* @param pData Pointer to data buffer
* @param Size Amount of data to be sent
*/
void I2CReadEEPROM(uint16_t MemAddress,uint8_t *pData, uint16_t Size)
{
HAL_I2C_Mem_Read(&hi2c1, 0xA0,MemAddress,I2C_MEMADD_SIZE_8BIT, pData, Size, 100);
}
在main函数中测试EEPROM是否正确读写:
uint8_t writeData[30];
for(int i=0;i<30;i++)
{
writeData[i]=i+3;
}
I2CWriteEEPROM(10,writeData, 30);
printf("\nwirteData:");
for(int i=0;i<30;i++)
{
printf("%02X ",writeData[i]);
}
uint8_t readData[30];
I2CReadEEPROM(10,readData, 30);
printf("\nreadData:");
for(int i=0;i<30;i++)
{
printf("%02X ",readData[i]);
}
从 串口调试助手中可以看出EEPROM正确的存取数据: