OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 618|回复: 0

《M144Z-M3最小系统板使用指南——STM32F103版》第四十章 IIC实验

[复制链接]

1117

主题

1128

帖子

2

精华

超级版主

Rank: 8Rank: 8

积分
4667
金钱
4667
注册时间
2019-5-8
在线时间
1224 小时
发表于 2024-5-9 16:16:43 | 显示全部楼层 |阅读模式
本帖最后由 正点原子运营 于 2024-5-8 17:11 编辑

第四十章 IIC实验
1)实验平台:正点原子 M144Z-M3 STM32F103最小系统板

2) 章节摘自【正点原子】M144Z-M3最小系统板使用指南——STM32F103版


4)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boar ... _mini_sysboard.html

5)正点原子官方B站:https://space.bilibili.com/394620890

6)正点原子STM32技术交流QQ群:725095144

155537c2odj87vz1z9vj6l.jpg

155537nfqovl2gg9faaol9.png

本章将介绍使用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的连接原理图,如下图所示:                        
11.png
图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相关的宏定义,如下所示:
  1. #define IIC_SCL_GPIO_PORT  GPIOB
  2. #define IIC_SCL_GPIO_PIN   GPIO_PIN_10
  3. #define IIC_SCL_GPIO_CLK_ENABLE()      \
  4.     do {                                \
  5.          __HAL_RCC_GPIOB_CLK_ENABLE();  \
  6.     }while (0)
  7. #define IIC_SDA_GPIO_PORT  GPIOB
  8. #define IIC_SDA_GPIO_PIN   GPIO_PIN_11
  9. #define IIC_SDA_GPIO_CLK_ENABLE()      \
  10.     do {                                \
  11.          __HAL_RCC_GPIOB_CLK_ENABLE();  \
  12.     }while (0)
  13. #define IIC_SCL(x)                                                             \
  14.     do {(x) ?                                                                  \
  15.          HAL_GPIO_WritePin(IIC_SCL_GPIO_PORT,IIC_SCL_GPIO_PIN, GPIO_PIN_SET): \
  16.          HAL_GPIO_WritePin(IIC_SCL_GPIO_PORT,IIC_SCL_GPIO_PIN, GPIO_PIN_RESET); \
  17.     }while (0)
  18. #define IIC_SDA(x)                                                             \
  19.     do {(x) ?                                                                  \
  20.          HAL_GPIO_WritePin(IIC_SDA_GPIO_PORT,IIC_SDA_GPIO_PIN, GPIO_PIN_SET): \
  21.          HAL_GPIO_WritePin(IIC_SDA_GPIO_PORT,IIC_SDA_GPIO_PIN, GPIO_PIN_RESET); \
  22.     }while (0)
  23. #define IIC_SDA_READ (                                                         \
  24.    (HAL_GPIO_ReadPin(IIC_SDA_GPIO_PORT, IIC_SDA_GPIO_PIN) ==GPIO_PIN_RESET) ? \
  25.     0 :                                                                         \
  26.     1)
复制代码
IIC驱动中,IIC的初始化函数,如下所示:
  1. /**
  2. *@brie    f初始化IIC
  3. *@param   无
  4. *@retval  无
  5. */
  6. void iic_init(void)
  7. {
  8.    GPIO_InitTypeDef gpio_init_struct = {0};
  9.    
  10.     /* 时钟使能 */
  11.    IIC_SCL_GPIO_CLK_ENABLE();
  12.    IIC_SDA_GPIO_CLK_ENABLE();
  13.    
  14.     /* 配置SCL引脚 */
  15.    gpio_init_struct.Pin = IIC_SCL_GPIO_PIN;
  16.    gpio_init_struct.Mode = GPIO_MODE_OUTPUT_OD;
  17.    gpio_init_struct.Pull = GPIO_NOPULL;
  18.    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;
  19.    HAL_GPIO_Init(IIC_SCL_GPIO_PORT, &gpio_init_struct);
  20.    
  21.     /* 配置SDA引脚 */
  22.    gpio_init_struct.Pin = IIC_SDA_GPIO_PIN;
  23.    gpio_init_struct.Mode = GPIO_MODE_OUTPUT_OD;
  24.    gpio_init_struct.Pull = GPIO_NOPULL;
  25.    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;
  26.    HAL_GPIO_Init(IIC_SDA_GPIO_PORT, &gpio_init_struct);
  27.    
  28.    iic_stop();
  29. }
复制代码
可以看到,IIC的初始化实际上就是配置IIC时钟与数据信号对应的GPIO引脚。
IIC驱动中对IIC的各种操作,例如产生IIC起始信号、产生IIC停止信号等,请读者结合IIC的时序规定查看本实验的配套实验源码。

40.2.3 EEPROM驱动
本章实验的EEPROM驱动主要负责向应用层提供EEPROM的初始化和读写数据等操作函数。本章实验中,EEPROM的驱动代码包括24cxx.c和24cxx.h两个文件。
EEPROM驱动中,EEPROM的初始化函数,如下所示:
  1. /**
  2. *@brief   初始化AT24CXX
  3. *@param   无
  4. *@retval  无
  5. */
  6. void at24cxx_init(void)
  7. {
  8.    iic_init();
  9. }
复制代码
可以看到,该函数实际上就是初始化了与EEPROM通讯的IIC。
EEPROM驱动中的其他对EEPROM的操作函数,例如:EEPROM的读写函数,请读者结合24C02 EEPROM芯片的数据手册查看本实验的配套实验源码。

40.2.4 实验应用代码
本章实验的应用代码,如下所示:
  1. static const uint8_t g_text_buf[] = {"STM32 IICTEST"};
  2. #define TEXT_SIZE sizeof(g_text_buf)
  3. int main(void)
  4. {
  5.     uint8_t t = 0;
  6.     uint8_t key;
  7.     uint8_t data[TEXT_SIZE];
  8.    
  9.    HAL_Init();                         /* 初始化HAL库 */
  10.    sys_stm32_clock_init(RCC_PLL_MUL9); /* 配置时钟,72MHz */
  11.    delay_init(72);                     /* 初始化延时 */
  12.    usart_init(115200);                 /* 初始化串口 */
  13.    led_init();                         /* 初始化LED */
  14.    key_init();                         /* 初始化按键 */
  15.    lcd_init();                         /* 初始化LCD */
  16.    at24cxx_init();                     /* 初始化AT24CXX */
  17.    
  18.    lcd_show_string(30, 50, 200, 16, 16, "STM32", RED);
  19.    lcd_show_string(30, 70, 200, 16, 16, "IICTEST", RED);
  20.    lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
  21.    
  22.    lcd_show_string(30, 110, 200, 16, 16, "WK_UP:WriteKEY0:Read", RED);
  23.    
  24.     /* 检测AT24CXX是否正常 */
  25.     while (at24cxx_check() != 0)
  26.     {
  27.          lcd_show_string(30, 130, 200, 16, 16, "24C02 CheckFailed!", RED);
  28.          delay_ms(500);
  29.          lcd_show_string(30, 130, 200, 16, 16, "PleaseCheck!      ", RED);
  30.          delay_ms(500);
  31.          LED0_TOGGLE();
  32.     }
  33.    lcd_show_string(30, 130, 200, 16, 16, "24C02Ready!       ", RED);
  34.    
  35.     while (1)
  36.     {
  37.          key = key_scan(0);
  38.          if (key == WKUP_PRES)
  39.          {
  40.              /* 往AT24CXX写入数据 */
  41.              lcd_fill(0, 150, 239, 319, WHITE);
  42.              lcd_show_string(30, 150, 200, 16, 16, "Start Write24C02....", BLUE);
  43.              at24cxx_write(0, (uint8_t *)g_text_buf, TEXT_SIZE);
  44.              lcd_show_string(30, 150, 200, 16, 16, "24C02 WriteFinished!", BLUE);
  45.          }
  46.          else if (key == KEY0_PRES)
  47.          {
  48.              /* 从AT24CXX读取数据 */
  49.              lcd_show_string(30, 150, 200, 16, 16, "Start Read 24C02....", BLUE);
  50.              at24cxx_read(0, data, TEXT_SIZE);
  51.              lcd_show_string(30, 150, 200, 16, 16, "The DataReaded Is:  ", BLUE);
  52.              lcd_show_string(30, 170, 200, 16, 16, (char *)data, BLUE);
  53.          }
  54.          
  55.          if (++t == 20)
  56.          {
  57.              t = 0;
  58.              LED0_TOGGLE();
  59.          }
  60.          
  61.          delay_ms(10);
  62.     }
  63. }
复制代码
从本章实验的应用代码中可以看到,在初始化完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中读回的数据。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 23:34

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表