本帖最后由 正点原子运营 于 2024-5-8 17:11 编辑
1)实验平台:正点原子 M144Z-M3 STM32F103最小系统板
2) 章节摘自【正点原子】M144Z-M3最小系统板使用指南——STM32F103版
6)正点原子STM32技术交流QQ群:725095144
本章将介绍使用STM32F103驱动板载的EEPROM进行读写操作。通过本章的学习,读者将学习到使用GPIO模拟IIC时序以及EEPROM的驱动。 本章分为如下几个小节: 40.1 硬件设计 40.2 程序设计 40.3 下载验证
40.1 硬件设计 40.1.1 例程功能 1. 按下WKUP按键可往24C02写入“STM32 IIC TEST” 2. 按下KEY0按键可从24C02读取到“STM32 IIC TEST”,并显示至LCD 3. LED0闪烁,提示程序正在运行
40.1.2 硬件资源 1. LED LED0 - PB5 2. 正点原子2.8/3.5/4.3/7/10寸TFTLCD模块 3. 按键 WKUP - PA0 KEY0 - PE4 4. 24C02 IIC_SCL - PB10 IIC_SDA - PB11
40.1.3 原理图 本章实验使用了板载的24C02芯片,该芯片是一个EEPROM,MCU是通过两个GPIO与该EEPROM进行连接与通信的,该EEPROM与MCU的连接原理图,如下图所示: 图40.1.3.1 EEPROM与MCU的连接原理图 40.2 程序设计 40.2.1 HAL库的GPIO驱动 本章实验通过控制与EEPROM连接的GPIO模拟IIC时序,实现EEPROM的读写操作,对于GPIO,主要涉及GPIO的配置和读写操作,需要一下几个步骤: ①:配置GPIO引脚为通用输出模式、开漏输出和禁止上拉/下拉 ②:在与EEPROM通信时,根据需求控制指定GPIO引脚输出指定电平 ③:在与EEPROM通信时,根据需求读取指定GPIO引脚上的输入电平 在HAL库中对应的驱动函数如下: ①:配置GPIO引脚 请见第10.2.1小节中配置GPIO引脚的相关内容。 ②:设置GPIO引脚输出电平 请见第10.2.1小节中设置GPIO引脚输出电平的相关内容。 ③:读取GPIO引脚输入电平 请见第11.2.1小节中读取GPIO引脚输入电平的相关内容。
40.2.2 IIC驱动 本章实验使用的IIC的软件模拟的IIC,即控制GPIO模拟IIC的时序与外部器件进行通信。IIC驱动主要负责向EEPROM驱动提供IIC操作的各种函数,例如:IIC起始信号、IIC停止信号等。本章实验中,IIC的驱动代码包括myiic.c和myiic.h两个文件。 IIC驱动中,对GPIO相关的宏定义,如下所示: - #define IIC_SCL_GPIO_PORT GPIOB
- #define IIC_SCL_GPIO_PIN GPIO_PIN_10
- #define IIC_SCL_GPIO_CLK_ENABLE() \
- do { \
- __HAL_RCC_GPIOB_CLK_ENABLE(); \
- }while (0)
- #define IIC_SDA_GPIO_PORT GPIOB
- #define IIC_SDA_GPIO_PIN GPIO_PIN_11
- #define IIC_SDA_GPIO_CLK_ENABLE() \
- do { \
- __HAL_RCC_GPIOB_CLK_ENABLE(); \
- }while (0)
- #define IIC_SCL(x) \
- do {(x) ? \
- HAL_GPIO_WritePin(IIC_SCL_GPIO_PORT,IIC_SCL_GPIO_PIN, GPIO_PIN_SET): \
- HAL_GPIO_WritePin(IIC_SCL_GPIO_PORT,IIC_SCL_GPIO_PIN, GPIO_PIN_RESET); \
- }while (0)
- #define IIC_SDA(x) \
- do {(x) ? \
- HAL_GPIO_WritePin(IIC_SDA_GPIO_PORT,IIC_SDA_GPIO_PIN, GPIO_PIN_SET): \
- HAL_GPIO_WritePin(IIC_SDA_GPIO_PORT,IIC_SDA_GPIO_PIN, GPIO_PIN_RESET); \
- }while (0)
- #define IIC_SDA_READ ( \
- (HAL_GPIO_ReadPin(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN) ==GPIO_PIN_RESET) ? \
- 0 : \
- 1)
复制代码IIC驱动中,IIC的初始化函数,如下所示: - /**
- *@brie f初始化IIC
- *@param 无
- *@retval 无
- */
- void iic_init(void)
- {
- GPIO_InitTypeDef gpio_init_struct = {0};
-
- /* 时钟使能 */
- IIC_SCL_GPIO_CLK_ENABLE();
- IIC_SDA_GPIO_CLK_ENABLE();
-
- /* 配置SCL引脚 */
- gpio_init_struct.Pin = IIC_SCL_GPIO_PIN;
- gpio_init_struct.Mode = GPIO_MODE_OUTPUT_OD;
- gpio_init_struct.Pull = GPIO_NOPULL;
- gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;
- HAL_GPIO_Init(IIC_SCL_GPIO_PORT, &gpio_init_struct);
-
- /* 配置SDA引脚 */
- gpio_init_struct.Pin = IIC_SDA_GPIO_PIN;
- gpio_init_struct.Mode = GPIO_MODE_OUTPUT_OD;
- gpio_init_struct.Pull = GPIO_NOPULL;
- gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;
- HAL_GPIO_Init(IIC_SDA_GPIO_PORT, &gpio_init_struct);
-
- iic_stop();
- }
复制代码可以看到,IIC的初始化实际上就是配置IIC时钟与数据信号对应的GPIO引脚。 IIC驱动中对IIC的各种操作,例如产生IIC起始信号、产生IIC停止信号等,请读者结合IIC的时序规定查看本实验的配套实验源码。
40.2.3 EEPROM驱动 本章实验的EEPROM驱动主要负责向应用层提供EEPROM的初始化和读写数据等操作函数。本章实验中,EEPROM的驱动代码包括24cxx.c和24cxx.h两个文件。 EEPROM驱动中,EEPROM的初始化函数,如下所示: - /**
- *@brief 初始化AT24CXX
- *@param 无
- *@retval 无
- */
- void at24cxx_init(void)
- {
- iic_init();
- }
复制代码可以看到,该函数实际上就是初始化了与EEPROM通讯的IIC。 EEPROM驱动中的其他对EEPROM的操作函数,例如:EEPROM的读写函数,请读者结合24C02 EEPROM芯片的数据手册查看本实验的配套实验源码。
40.2.4 实验应用代码 本章实验的应用代码,如下所示: - static const uint8_t g_text_buf[] = {"STM32 IICTEST"};
- #define TEXT_SIZE sizeof(g_text_buf)
- int main(void)
- {
- uint8_t t = 0;
- uint8_t key;
- uint8_t data[TEXT_SIZE];
-
- HAL_Init(); /* 初始化HAL库 */
- sys_stm32_clock_init(RCC_PLL_MUL9); /* 配置时钟,72MHz */
- delay_init(72); /* 初始化延时 */
- usart_init(115200); /* 初始化串口 */
- led_init(); /* 初始化LED */
- key_init(); /* 初始化按键 */
- lcd_init(); /* 初始化LCD */
- at24cxx_init(); /* 初始化AT24CXX */
-
- lcd_show_string(30, 50, 200, 16, 16, "STM32", RED);
- lcd_show_string(30, 70, 200, 16, 16, "IICTEST", RED);
- lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
-
- lcd_show_string(30, 110, 200, 16, 16, "WK_UP:WriteKEY0:Read", RED);
-
- /* 检测AT24CXX是否正常 */
- while (at24cxx_check() != 0)
- {
- lcd_show_string(30, 130, 200, 16, 16, "24C02 CheckFailed!", RED);
- delay_ms(500);
- lcd_show_string(30, 130, 200, 16, 16, "PleaseCheck! ", RED);
- delay_ms(500);
- LED0_TOGGLE();
- }
- lcd_show_string(30, 130, 200, 16, 16, "24C02Ready! ", RED);
-
- while (1)
- {
- key = key_scan(0);
- if (key == WKUP_PRES)
- {
- /* 往AT24CXX写入数据 */
- lcd_fill(0, 150, 239, 319, WHITE);
- lcd_show_string(30, 150, 200, 16, 16, "Start Write24C02....", BLUE);
- at24cxx_write(0, (uint8_t *)g_text_buf, TEXT_SIZE);
- lcd_show_string(30, 150, 200, 16, 16, "24C02 WriteFinished!", BLUE);
- }
- else if (key == KEY0_PRES)
- {
- /* 从AT24CXX读取数据 */
- lcd_show_string(30, 150, 200, 16, 16, "Start Read 24C02....", BLUE);
- at24cxx_read(0, data, TEXT_SIZE);
- lcd_show_string(30, 150, 200, 16, 16, "The DataReaded Is: ", BLUE);
- lcd_show_string(30, 170, 200, 16, 16, (char *)data, BLUE);
- }
-
- if (++t == 20)
- {
- t = 0;
- LED0_TOGGLE();
- }
-
- delay_ms(10);
- }
- }
复制代码从本章实验的应用代码中可以看到,在初始化完EEPROM后,会检测与EEPROM的连接是否正常,若与EEPROM的连接正常,则会不断地等待按键输入,若检测到WKUP按键被按下,则会往EEPROM的指定地址中写入指定的数据,若检测到KEY_0按键被按下,则会从EEPROM的指定地址中读取数据,并在LCD上进行显示。
40.3 下载验证 在完成编译和烧录操作后,若MCU与EEPROM的连接无误,则可以在LCD上看到“24C02 Ready!”的提示信息,此时可以按下WKUP按键往EEPROM的指定地址写入指定数据,然后再按下KEY_0按键从EEPROM的指定地址将写入的数据读回来在LCD上进行显示,此时便可以看到在LCD上显示了“STM32 IIC TEST”的提示信息,该提示信息就是从EEPROM中读回的数据。 |