返回列表 发新帖我要提问本帖赏金: 30.00元(功能说明)

[APM32E0] 【APM32E030R Micro-EVB开发板评测】+ 使用硬件I2C驱动OLED

[复制链接]
884|17
 楼主| gaoyang9992006 发表于 2025-8-7 23:04 | 显示全部楼层 |阅读模式
本帖最后由 gaoyang9992006 于 2025-8-8 10:50 编辑

经过几天的学习,终于掌握了硬件I2C库函数的使用方法,总结如下:
时钟启用,功能映射到引脚,引脚的IO的模式配置,I2C配置与启用。
  1. void I2CInit(void)
  2. {
  3.     GPIO_Config_T gpioConfigStruct;
  4.     I2C_Config_T i2cConfigStruct;
  5.     /* Enable I2C related Clock */
  6.     RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOB);
  7.     RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_I2C1);
  8.     RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG);

  9.     /* Connect I2C to SCL */
  10.     GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_8, GPIO_AF_PIN1);
  11.     /* Connect I2C to SDA */
  12.     GPIO_ConfigPinAF(GPIOB, GPIO_PIN_SOURCE_9, GPIO_AF_PIN1);
  13.     /*  Config I2C1 GPIO */
  14.     gpioConfigStruct.mode = GPIO_MODE_AF;
  15.     gpioConfigStruct.speed = GPIO_SPEED_50MHz;
  16.     gpioConfigStruct.outtype = GPIO_OUT_TYPE_OD;
  17.     gpioConfigStruct.pupd = GPIO_PUPD_NO;
  18.     gpioConfigStruct.pin = GPIO_PIN_8;
  19.     GPIO_Config(GPIOB, &gpioConfigStruct);

  20.     gpioConfigStruct.pin = GPIO_PIN_9;
  21.     GPIO_Config(GPIOB, &gpioConfigStruct);

  22.     /* Config I2C1 */
  23.     I2C_Reset(I2C1);
  24.     RCM_ConfigI2CCLK(RCM_I2C1CLK_SYSCLK);
  25.     i2cConfigStruct.ack = I2C_ACK_ENABLE;
  26.     i2cConfigStruct.ackaddress = I2C_ACK_ADDRESS_7BIT;
  27.     i2cConfigStruct.address1 = 0XA0;
  28.     i2cConfigStruct.analogfilter = I2C_ANALOG_FILTER_ENABLE;
  29.     i2cConfigStruct.digitalfilter = I2C_DIGITAL_FILTER_0;
  30.     i2cConfigStruct.mode = I2C_MODE_I2C;
  31.     i2cConfigStruct.timing = 0x80100103;
  32.     I2C_Config(I2C1, &i2cConfigStruct);

  33.     /* Enable I2Cx */
  34.     I2C_Enable(I2C1);
  35. }


I2C发送函数映射到OLED库的数据命令发送函数。
  1. //发送一个字节
  2. //mode:数据/命令标志 0,表示命令;1,表示数据;
  3. void OLED_WR_Byte(u8 dat,u8 mode)
  4. {
  5.     /* I2C Send Configuration */

  6.    I2C_HandlingTransfer(I2C1, 0x78, 2, I2C_RELOAD_MODE_AUTOEND, I2C_GENERATE_START_WRITE);
  7.         
  8.    if(mode){I2C_TxData(I2C1,0x40);}
  9.    else{I2C_TxData(I2C1,0x00);}        
  10.    while (I2C_ReadStatusFlag(I2C1, I2C_FLAG_TXBE) == RESET);
  11.    I2C_TxData(I2C1, dat);
  12.    while (I2C_ReadStatusFlag(I2C1, I2C_FLAG_TXBE) == RESET);
  13.     /* I2C Generate Stop signal */
  14.    I2C_EnableGenerateStop(I2C1);
  15.    /* I2C Clear Stop Flag */
  16.    I2C_ClearIntFlag(I2C1, I2C_INT_FLAG_STOP);
  17.         
  18. }
更新显存调用库函数
  1. //更新显存到OLED        
  2. void OLED_Refresh(void)
  3. {
  4.         u8 i,n;
  5.         for(i=0;i<8;i++)
  6.         {
  7.                 OLED_WR_Byte(0xb0+i,OLED_CMD); //设置行起始地址
  8.                 OLED_WR_Byte(0x00,OLED_CMD);   //设置低列起始地址
  9.                 OLED_WR_Byte(0x10,OLED_CMD);   //设置高列起始地址
  10.                

  11.                 for(n=0;n<128;n++)
  12.                 {
  13.                         I2C_HandlingTransfer(I2C1, 0x78, 2, I2C_RELOAD_MODE_AUTOEND, I2C_GENERATE_START_WRITE);
  14.                   I2C_TxData(I2C1,0x40);
  15.       while (I2C_ReadStatusFlag(I2C1, I2C_FLAG_TXBE) == RESET);
  16.                         I2C_TxData(I2C1,OLED_GRAM[n][i]);
  17.                         while (I2C_ReadStatusFlag(I2C1, I2C_FLAG_TXBE) == RESET);
  18.                 }
  19.     /* I2C Generate Stop signal */
  20.    I2C_EnableGenerateStop(I2C1);
  21.    /* I2C Clear Stop Flag */
  22.    I2C_ClearIntFlag(I2C1, I2C_INT_FLAG_STOP);
  23.   }
  24. }
经过了上述的映射后,OLED的库函数就可以使用硬件I2C来驱动OLED屏幕了。

因为是没有焊接OLED的飞线,手头上找不到足够的杜邦线,都是用手捏着测试的,不方便拍照。先不放图了,等我找到足够多的杜邦线再来补图。
附录是该项目的工程文件源代码,供大家参考测试用。
游客,如果您要查看本帖隐藏内容请回复

补充图片

微信图片_20250808105054.jpg

打赏榜单

21ic小管家 打赏了 30.00 元 2025-09-12
理由:极海评测活动奖励

yangxiaor520 发表于 2025-8-8 07:55 来自手机 | 显示全部楼层
看看,刷新频率咋样?
 楼主| gaoyang9992006 发表于 2025-8-8 11:48 | 显示全部楼层
yangxiaor520 发表于 2025-8-8 07:55
看看,刷新频率咋样?

看刷新率需要开启定时器了,等下一个学习视频发了就上刷新率测试。通过定时器计时来计算刷新率。比如定时器1秒,然后计数刷新了多少次,定时器中断里读取出来并将计数器清零。
CloudKiss 发表于 2025-8-8 14:28 | 显示全部楼层
这回还真飞线处理了。
看来,还是要继续向楼主学习啊
海洋凝视 发表于 2025-8-14 18:49 | 显示全部楼层
这颗小MCU的I2C中断处理程序如何?
我看楼主使用的是查询的方式
 楼主| gaoyang9992006 发表于 2025-8-15 08:45 | 显示全部楼层
海洋凝视 发表于 2025-8-14 18:49
这颗小MCU的I2C中断处理程序如何?
我看楼主使用的是查询的方式

用中断还不如用DMA
 楼主| gaoyang9992006 发表于 2025-8-15 08:46 | 显示全部楼层
CloudKiss 发表于 2025-8-8 14:28
这回还真飞线处理了。
看来,还是要继续向楼主学习啊

引脚排列顺序厂家没考虑好插外设这种事情,其实应该提供方便接UART,I2C,SPI的接口。调整下现在的引脚顺序就行了。
海洋凝视 发表于 2025-8-15 10:05 | 显示全部楼层

嗯嗯,我也认为DMA好用。
但我的同事们觉得DMA好难!他们也不学习
spirit.qiu 发表于 2025-8-18 11:42 | 显示全部楼层
水之呢喃 发表于 2025-8-27 19:46 | 显示全部楼层
我怎么觉得楼主根本就没有焊接呢
 楼主| gaoyang9992006 发表于 2025-8-28 12:39 | 显示全部楼层
水之呢喃 发表于 2025-8-27 19:46
我怎么觉得楼主根本就没有焊接呢

你是说对了,没焊接,没那么多排针。
CloudKiss 发表于 2025-8-30 14:49 | 显示全部楼层
这个核心板的GPIO排列应该是设计引出怎么方便怎么来的吧
估计也是建议大家拿到后,自己再做一个适配的外设扩展板
霜咬回响 发表于 2025-8-30 15:13 | 显示全部楼层
楼主有尝试过将I2C引脚配置为PP模式吗?
水之呢喃 发表于 2025-9-10 11:22 | 显示全部楼层
gaoyang9992006 发表于 2025-8-28 12:39
你是说对了,没焊接,没那么多排针。

高老师 您这是不是说笑了
 楼主| gaoyang9992006 发表于 2025-9-10 19:55 | 显示全部楼层
水之呢喃 发表于 2025-9-10 11:22
高老师 您这是不是说笑了

凑合凑合看出来效果就行了。
神话编织者 发表于 2025-9-12 17:34 | 显示全部楼层
硬件I2C还是靠谱的
彩虹捕手 发表于 2025-9-15 10:14 | 显示全部楼层
I2C的配置和使用一直是我比较头疼的部分
复古留声机 发表于 2025-9-23 11:30 | 显示全部楼层
代码看起来逻辑清晰,配置I2C和OLED通信的部分都很详细,赞一个。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:如果你觉得我的分享或者答复还可以,请给我点赞,谢谢。

2052

主题

16403

帖子

222

粉丝
快速回复 在线客服 返回列表 返回顶部