将姓名(拼音)+学号写入EEPROM并在启动时通过串口显示
本篇博客将介绍如何使用STM32F4开发板将姓名(拼音)+学号写入EEPROM,并在启动时通过串口显示。我们将使用核心实现函数EEPROM_WR_Test
来完成这个功能。
准备工作
在开始之前,我们需要准备以下材料:
- STM32F4开发板
- I2C EEPROM(例如24C64)
- 连接线
接下来,按照以下步骤进行连接:
- 将I2C EEPROM的VCC引脚连接到STM32F4开发板的5V引脚。
- 将I2C EEPROM的GND引脚连接到STM32F4开发板的GND引脚。
- 将I2C EEPROM的SCL引脚连接到STM32F4开发板的I2C_SCL引脚。
- 将I2C EEPROM的SDA引脚连接到STM32F4开发板的I2C_SDA引脚。
连接完成后,我们可以开始编写代码。
编写代码
首先,我们需要在代码中包含相应的头文件和定义相关的宏:
原始的例子中是存在
eeprom.c
和eeprom.h
的
eeprom.h
如果你有原始的例子,就不需要添加这个
/* 这是一个EEPROM的头文件,EEPROM的型号是FM24C64-D. */
#ifndef __EEPROM_H
#define __EEPROM_H
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include "stm32f4xx.h"
#include "stm32f4xx_i2c.h"
#define ADDR_EEPROM_24C64 0xA0
#define I2C_Open_FLAG_TIMEOUT ((uint32_t)0x1000)
#define I2C_Open_LONG_TIMEOUT ((uint32_t)(10 * I2C_Open_FLAG_TIMEOUT))
void EEPROM_Config(void);
uint8_t I2C_Read(I2C_TypeDef *I2Cx,uint8_t I2C_Addr,uint16_t addr,uint8_t *buf,uint16_t num);
uint8_t I2C_Write(I2C_TypeDef *I2Cx,uint8_t I2C_Addr,uint16_t addr,uint8_t *buf,uint16_t num);
void Del_EEPROM_Data(uint16_t addr_start,uint16_t datalen);
//void EEPROM_WR_Test( );
#endif
eeprom.c
在原始例子中,你仅需要修改
void EEPROM_WR_Test( )
函数
/* 这是一个EEPROM的驱动文件,EEPROM的型号是FM24C64-D. */
#include "stm32f4xx_rcc.h"
#include "eeprom.h"
#include "usart.h"
#include "user.h"
#include "GWProtocol.h"
#define I2C I2C3
#define I2C_CLK RCC_APB1Periph_I2C3
#define I2C_SDA_PIN GPIO_Pin_9
#define I2C_SDA_GPIO_PORT GPIOC
#define I2C_SDA_GPIO_CLK RCC_AHB1Periph_GPIOC
#define I2C_SDA_SOURCE GPIO_PinSource9
#define I2C_SDA_AF GPIO_AF_I2C3
#define I2C_SCL_PIN GPIO_Pin_8
#define I2C_SCL_GPIO_PORT GPIOA
#define I2C_SCL_GPIO_CLK RCC_AHB1Periph_GPIOA
#define I2C_SCL_SOURCE GPIO_PinSource8
#define I2C_SCL_AF GPIO_AF_I2C3
#define I2C_SPEED 100000
#define I2C_SLAVE_ADDRESS7 0x30
static void I2C_delay(uint16_t cnt);
uint32_t I2C_TIMEOUT_UserCallback(void);
static void I2C_AcknowledgePolling(I2C_TypeDef *I2Cx,uint8_t I2C_Addr);
__IO uint32_t I2CTimeout = I2C_Open_LONG_TIMEOUT;
/*******************************************************************************
* Function Name : EEPROM_Configuration
* Description :
* Input : None
* Output : None
* Return : None
* Attention : None
*******************************************************************************/
void EEPROM_Config(void)
{
I2C_InitTypeDef I2C_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(I2C_SDA_GPIO_CLK | I2C_SCL_GPIO_CLK,ENABLE);
RCC_APB1PeriphClockCmd(I2C_CLK,ENABLE);
GPIO_PinAFConfig(I2C_SDA_GPIO_PORT, I2C_SDA_SOURCE, I2C_SDA_AF);
GPIO_PinAFConfig(I2C_SCL_GPIO_PORT, I2C_SCL_SOURCE, I2C_SCL_AF);
GPIO_InitStructure.GPIO_Pin = I2C_SDA_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
I2C_DeInit(I2C);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = I2C_SLAVE_ADDRESS7;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED;
I2C_Cmd(I2C, ENABLE);
I2C_Init(I2C, &I2C_InitStructure);
I2C_AcknowledgeConfig(I2C, ENABLE);
}
/*******************************************************************************
* Function Name : I2C_delay
* Description :
* Input : None
* Output : None
* Return : None
* Attention : None
*******************************************************************************/
static void I2C_delay(uint16_t cnt)
{
while(cnt--);
}
/**
* @brief Basic management of the timeout situation.
* @param None.
* @retval None.
*/
uint32_t I2C_TIMEOUT_UserCallback(void)
{
/* Block communication and all processes */
printf("\r\n The I2C communication is corrupted \r\n");
while (1)
{
}
}
/*******************************************************************************
* Function Name : I2C_AcknowledgePolling
* Description :
* Input : I2C_TypeDef * , uint8_t
* Output : None
* Return : None
* Attention : None
*******************************************************************************/
static void I2C_AcknowledgePolling(I2C_TypeDef *I2Cx,uint8_t I2C_Addr)
{
vu16 SR1_Tmp;
do
{
I2C_GenerateSTART(I2Cx, ENABLE);
SR1_Tmp = I2C_ReadRegister(I2Cx, I2C_Register_SR1);
I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Transmitter);
}while(!(I2C_ReadRegister(I2Cx, I2C_Register_SR1) & 0x0002));
I2C_ClearFlag(I2Cx, I2C_FLAG_AF);
I2C_GenerateSTOP(I2Cx, ENABLE);
}
/*******************************************************************************
* Function Name : I2C_Read
* Description :
* Input :
* Output :
* Return :
* Attention : None
*******************************************************************************/
uint8_t I2C_Read(I2C_TypeDef *I2Cx,uint8_t I2C_Addr,uint16_t addr,uint8_t *buf,uint16_t num)
{
if(num==0)
return 1;
while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));
I2C_ClearFlag(I2Cx, I2C_FLAG_BUSY);
I2C_AcknowledgeConfig(I2Cx, ENABLE);
I2C_GenerateSTART(I2Cx, ENABLE);
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Transmitter);
while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2Cx, (addr >> 8));
while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2Cx, (addr & 0xFF));
while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTART(I2Cx, ENABLE);
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Receiver);
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
while (num)
{
if(num==1)
{
I2C_AcknowledgeConfig(I2Cx, DISABLE);
I2C_GenerateSTOP(I2Cx, ENABLE);
}
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)); /* EV7 */
*buf = I2C_ReceiveData(I2Cx);
buf++;
/* Decrement the read bytes counter */
num--;
}
I2C_AcknowledgeConfig(I2Cx, ENABLE);
return 0;
}
/*******************************************************************************
* Function Name : I2C_WriteOneByte
* Description :
* Input :
* Output : None
* Return :
* Attention : None
*******************************************************************************/
uint8_t I2C_WriteOneByte(I2C_TypeDef *I2Cx,uint8_t I2C_Addr,uint16_t addr,uint8_t value)
{
addr = addr & 0x1FFF;
I2CTimeout = I2C_Open_LONG_TIMEOUT;
while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY))
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback();
}
I2C_ClearFlag(I2Cx, I2C_FLAG_BUSY);
I2C_GenerateSTART(I2Cx, ENABLE);
I2CTimeout = I2C_FLAG_TIMEOUT;
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT))
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback();
}
I2CTimeout = I2C_FLAG_TIMEOUT;
I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback();
}
I2C_SendData(I2Cx, (addr >> 8));
I2CTimeout = I2C_FLAG_TIMEOUT;
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback();
}
I2C_SendData(I2Cx, (addr & 0xFF));
I2CTimeout = I2C_FLAG_TIMEOUT;
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback();
}
I2C_SendData(I2Cx, value);
I2CTimeout = I2C_FLAG_TIMEOUT;
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
{
if((I2CTimeout--) == 0) return I2C_TIMEOUT_UserCallback();
}
I2C_GenerateSTOP(I2Cx, ENABLE);
I2C_AcknowledgePolling(I2Cx,I2C_Addr);
I2C_delay(1000);
return 0;
}
/*******************************************************************************
* Function Name : I2C_Write
* Description :
* Input :
* Output : None
* Return :
* Attention : None
*******************************************************************************/
uint8_t I2C_Write(I2C_TypeDef *I2Cx,uint8_t I2C_Addr,uint16_t addr,uint8_t *buf,uint16_t num)
{
uint8_t err=0;
while(num--)
{
if(I2C_WriteOneByte(I2Cx, I2C_Addr,addr++,*buf++))
{
Delay_MS(10);
err++;
}
}
if(err)
return 1;
else
return 0;
}
/* EEPROM清除函数. */
void Del_EEPROM_Data(uint16_t addr_start,uint16_t datalen)
{
uint8_t data[TERM_MAX_NUM*GW_TERMINAL_LIST_LEN];
memset(data,0,sizeof(uint8_t)*TERM_MAX_NUM*GW_TERMINAL_LIST_LEN);
I2C_Write(I2C3, ADDR_EEPROM_24C64, addr_start, data, datalen);
}
/***** EEPROM读写测试. *****/
void EEPROM_WR_Test( )
{
uint16_t i;
uint8_t readbuf[500];
uint8_t writebuf[] = {'2','x','x'};
//for( i = 0;i < 100;i++) writebuf[i] = i;
printf(" EEPROM write start....\r\n");
I2C_Write(I2C3,ADDR_EEPROM_24C64,0x0,writebuf,100);
Delay_MS( 1000 );
printf(" EEPROM read start....\r\n");
I2C_Read(I2C3,ADDR_EEPROM_24C64,0x0,readbuf,100);
printf("%s ",readbuf);
/*for(i = 0;i < 100;i++)
{
printf("%02X ",readbuf[i]);
}*/
printf("\r\n");
}
/********************************************* end file *************************************************/
main.c调用函数
#include "eeprom.h"
……初始化
EEPROM_Config( );
……读写测试
EEPROM_WR_Test();