找回密码
 立即注册
查看: 195|回复: 5

AiCube生成驱动OLED-12864代码,【SPI,SPI-DMA,I2C,I2C-DMA】,@Ai8051U

[复制链接]
  • 打卡等级:偶尔看看III
  • 打卡总天数:58
  • 最近打卡:2025-06-17 09:13:13

26

主题

1037

回帖

3950

积分

超级版主

积分
3950
发表于 昨天 16:46 | 显示全部楼层 |阅读模式
AiCube 生成驱动 OLED-12864代码SPISPI-DMAI2CI2C-DMA
===4种 通信组合,一网打尽,使用AiCube生成基于Ai8051U的代码

大家可以轻松改到 STC8H8K64U / STC32G12K128 系列

1、认识 OLED-12864 显示屏SPI+I2C2种 通信模式
下图是网络上比较常用的OLED-12864显示屏,通过电阻跳线选择SPI通信接口,还是 I2C通信接口

正面

正面


当需要使用SPI接口时R1、R2、R8不焊,R3、R4焊4.7K电阻,如下图

SPI

SPI


当需要使用I2C接口时,R2、R3、R9不焊,R1、R4焊4.7K电阻,R8焊0欧电阻,如下图

I2C

I2C



2、OLED-12864屏接口
本帖的测试环境使用的是Ai8051U试验箱V1.2,试验箱上的OLED12864接口如下图所示:
截图202506161550401512.jpg
此部分的接口电路图如下:
截图202506161603407967.jpg

SPI使用的是:SS(P3.5), MOSI(P3.4), MISO(P3.3), SCLK(P3.2)这组切换
I2C使用的是:SCL(P3.2), SDA(P3.3)这组切换

试验箱上的OLED接口是8Pin,本帖使用的OLED是7Pin,靠左对齐将屏插到接口上即可,如下图:
截图202506161554091367.jpg

3、使用AiCube生成SPI驱动框架
打开AiCube,新建Ai8051U-32Bit项目


3.1、在图形化I/O配置界面中选择SPI的P3口切换组
截图202506161613339025.jpg
3.2、在图形化I/O配置界面对OLED相关的I/O模式做如下配置
截图202506161616206470.jpg
3.3、在图形化I/O配置界面配置完成后,务必勾选相应的端口,如下图
若不勾选,则AiCube不会生成相应的初始化代码
截图202506161617472276.jpg
3.4、如下图对SPI功能模块进行配置
截图202506161621293668.jpg
3.5、完成上面的配置点击AiCube界面中的“创建Keil项目”按钮即可生成Keil项目框架及相应的代码
截图202506161626215090.jpg

4、完善代码添加OLED驱动代码
4.1、添加OLED驱动代码和数据代码到项目中
打开AiCube自动生成的Keil项目,将OLED驱动代码"oled.c"和图片字库代码"tab.c"添加到项目中
截图202506161631355171.jpg
4.2、使用硬件SPI实现OLED的低层驱动代码(核心代码)
  1. ////////////////////////////////////////
  2. // 复位OLED
  3. // 入口参数: 无
  4. // 函数返回: 无
  5. ////////////////////////////////////////
  6. void OLED_RESET()
  7. {
  8.     OLED_RES = 1; delay_ms(200);
  9.     OLED_RES = 0; delay_ms(200);        //复位
  10.     OLED_RES = 1;
  11. }
  12. ////////////////////////////////////////
  13. // 写OLED命令
  14. // 入口参数: cmd (命令序列)
  15. //           len (命令长度)
  16. // 函数返回: 无
  17. ////////////////////////////////////////
  18. void OLED_WR_CMD(uint8_t *cmd, uint16_t len)
  19. {
  20.     OLED_DC = 0;                        //写命令
  21.     OLED_SendData(cmd, len);
  22. }
  23. ////////////////////////////////////////
  24. // 写OLED数据
  25. // 入口参数: dat (数据序列)
  26. //           len (数据长度)
  27. // 函数返回: 无
  28. ////////////////////////////////////////
  29. void OLED_WR_DAT(uint8_t *dat, uint16_t len)
  30. {
  31.     OLED_DC = 1;                        //写数据
  32.     OLED_SendData(dat, len);
  33. }
  34. ////////////////////////////////////////
  35. // 发送OLED数据
  36. // 入口参数: dat (数据序列)
  37. //           len (数据长度)
  38. // 函数返回: 无
  39. ////////////////////////////////////////
  40. void OLED_SendData(uint8_t *dat, uint16_t len)
  41. {
  42.     OLED_CS = 0;                       //片选使能
  43.     while (len--)
  44.     {
  45.         SPI_SendData(*dat++);             //写数据
  46.         while (!SPI_CheckFlag());          //等待数据发生完成
  47.         SPI_ClearFlag();               //清除完成标志
  48.     }
  49.     OLED_CS = 1;                      //片选禁能
  50. }
复制代码
4.3、其它代码可参考附件中的代码完成
4.4、代码完成代码编写后,将编译生成的HEX文件下载到试验箱,即可看到如下效果


演示程序如下: OLED_SPI_Demo.rar (90.76 KB, 下载次数: 3)


2 喜欢他/她就送朵鲜花吧,赠人玫瑰,手有余香!
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:58
  • 最近打卡:2025-06-17 09:13:13

26

主题

1037

回帖

3950

积分

超级版主

积分
3950
发表于 昨天 16:47 | 显示全部楼层
1楼演示了使用AiCube生成硬件SPI代码驱动OLED的流程
本楼演示使用AiCube生成 硬件 SPI-DMA 代码驱动OLED的流程


1、使用AiCube生成 SPI-DMA驱动框架
打开AiCube,新建Ai8051U-32Bit项目
1.1、I/O口配置可参考1楼的配置方法
1.2、如下图对SPI功能模块进行配置,与1楼的区别是增加了SPI-DMA的配置
截图202506161654135133.jpg
1.3、完成上面的配置生成Keil项目框架及相应的代码


2、完善代码添加OLED驱动代码
2.1、同样将添加OLED驱动代码和数据代码到项目中
2.2、使用硬件SPI-DMA实现OLED的低层驱动代码(核心代码)
  1. ////////////////////////////////////////
  2. // 写OLED命令
  3. // 入口参数: cmd (命令序列)
  4. //           len (命令长度)
  5. // 函数返回: 无
  6. ////////////////////////////////////////
  7. void OLED_WR_CMD(uint8_t *cmd, uint16_t len)
  8. {
  9.     while (fSPIDMABusy);                //等待上一次传输完成
  10.     OLED_DC = 0;                        //写命令
  11.     OLED_SendData(cmd, len);
  12. }
  13. ////////////////////////////////////////
  14. // 写OLED数据
  15. // 入口参数: dat (数据序列)
  16. //           len (数据长度)
  17. // 函数返回: 无
  18. ////////////////////////////////////////
  19. void OLED_WR_DAT(uint8_t *dat, uint16_t len)
  20. {
  21.     while (fSPIDMABusy);                //等待上一次传输完成
  22.     OLED_DC = 1;                        //写数据
  23.     OLED_SendData(dat, len);
  24. }
  25. ////////////////////////////////////////
  26. // 发送OLED数据
  27. // 入口参数: dat (数据序列)
  28. //           len (数据长度)
  29. // 函数返回: 无
  30. ////////////////////////////////////////
  31. void OLED_SendData(uint8_t *dat, uint16_t len)
  32. {
  33.     OLED_CS = 0;                        //片选使能
  34.    
  35.     memcpy(pu8SPIDMATxBuffer, dat, len); //将数据复制到DMA缓冲区
  36.     DMA_SPI_SetAmount(len - 1);         //设置DMA发送字节数
  37.     DMA_SPI_MasterTrigger();            //触发SPI主机DMA
  38.     fSPIDMABusy = 1;                    //设置DMA传输忙标志
  39. }
复制代码
2.3、其它代码可参考附件中的代码完成
2.4、代码完成代码编写后,将编译生成的HEX文件下载到试验箱,同样也可看到如1楼的效果




OLED_SPI_DMA_Demo.rar

91.59 KB, 下载次数: 3

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:58
  • 最近打卡:2025-06-17 09:13:13

26

主题

1037

回帖

3950

积分

超级版主

积分
3950
发表于 昨天 16:47 | 显示全部楼层
1楼演示了使用AiCube生成硬件SPI代码驱动OLED的流程
本楼演示使用AiCube生成硬件I2C代码驱动OLED的流程

1、使用AiCube生成I2C驱动框架
打开AiCube,新建Ai8051U-32Bit项目

1.1、在图形化I/O配置界面中选择I2C的P3口切换组
截图202506161708388151.jpg
1.2、在图形化I/O配置界面对OLED相关的I/O模式做如下配置
截图202506161709364048.jpg
1.3、在图形化I/O配置界面配置完成后,务必勾选相应的端口,如下图
若不勾选,则AiCube不会生成相应的初始化代码
截图202506161710003266.jpg
1.4、如下图对I2C功能模块进行配置
截图202506161710404809.jpg
1.5、完成上面的配置点击AiCube界面中的“创建Keil项目”按钮即可生成Keil项目框架及相应的代码

2、完善代码添加OLED驱动代码
2.1、同样将添加OLED驱动代码和数据代码到项目中
2.2、使用硬件I2C实现OLED的低层驱动代码(核心代码)
  1. ////////////////////////////////////////
  2. // 写OLED命令
  3. // 入口参数: cmd (命令序列)
  4. //           len (命令长度)
  5. // 函数返回: 无
  6. ////////////////////////////////////////
  7. void OLED_WR_CMD(uint8_t *cmd, uint16_t len)
  8. {
  9.     I2C_MasterStart();
  10.     I2C_MasterSendByte(0x78);           //从机地址
  11.     I2C_MasterSendByte(0x00);                    //写命令 (DC = 0)
  12.    
  13.     OLED_SendData(cmd, len);
  14. }
  15. ////////////////////////////////////////
  16. // 写OLED数据
  17. // 入口参数: dat (数据序列)
  18. //           len (数据长度)
  19. // 函数返回: 无
  20. ////////////////////////////////////////
  21. void OLED_WR_DAT(uint8_t *dat, uint16_t len)
  22. {
  23.     I2C_MasterStart();
  24.     I2C_MasterSendByte(0x78);                    //从机地址
  25.     I2C_MasterSendByte(0x40);                    //写数据 (DC = 1)
  26.    
  27.     OLED_SendData(dat, len);
  28. }
  29. ////////////////////////////////////////
  30. // 发送OLED数据
  31. // 入口参数: dat (数据序列)
  32. //           len (数据长度)
  33. // 函数返回: 无
  34. ////////////////////////////////////////
  35. void OLED_SendData(uint8_t *dat, uint16_t len)
  36. {
  37.     while (len--)
  38.         I2C_MasterSendByte(*dat++);
  39.     I2C_MasterStop();
  40. }
复制代码


2.3、其它代码可参考附件中的代码完成
2.4、代码完成代码编写后,将编译生成的HEX文件下载到试验箱,同样也可看到如1楼的效果



OLED_I2C_Demo.rar

90.63 KB, 下载次数: 2

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:58
  • 最近打卡:2025-06-17 09:13:13

26

主题

1037

回帖

3950

积分

超级版主

积分
3950
发表于 昨天 16:48 | 显示全部楼层
3楼演示了使用AiCube生成 硬件I2C 代码驱动OLED12864的流程
本楼演示使用AiCube生成 硬件 I2C-DMA 代码驱动OLED12864的流程


1、使用AiCube生成 SPI-DMA 驱动框架
打开AiCube,新建Ai8051U-32Bit项目
1.1、I/O口配置可参考3楼的配置方法
1.2、如下图对I2C功能模块进行配置,与3楼的区别是增加了I2C-DMA的配置
截图202506161716236333.jpg
1.3、完成上面的配置生成Keil项目框架及相应的代码


2、完善代码添加OLED驱动代码
2.1、同样将添加OLED12864驱动代码和数据代码到项目中
2.2、使用硬件I2C-DMA实现OLED12864的低层驱动代码(核心代码)
  1. ////////////////////////////////////////
  2. // 写OLED命令
  3. // 入口参数: cmd (命令序列)
  4. //           len (命令长度)
  5. // 函数返回: 无
  6. ////////////////////////////////////////
  7. void OLED_WR_CMD(uint8_t *cmd, uint16_t len)
  8. {
  9.     while (fI2CDMABusy);                //等待上一次传输完成
  10.     pu8I2CDMATxBuffer[0] = 0x78;        //从机地址
  11.     pu8I2CDMATxBuffer[1] = 0x00;            //写命令 (DC = 0)
  12.    
  13.     OLED_SendData(cmd, len);            //发送命令序列
  14. }
  15. ////////////////////////////////////////
  16. // 写OLED数据
  17. // 入口参数: dat (数据序列)
  18. //           len (数据长度)
  19. // 函数返回: 无
  20. ////////////////////////////////////////
  21. void OLED_WR_DAT(uint8_t *dat, uint16_t len)
  22. {
  23.     while (fI2CDMABusy);                //等待上一次传输完成
  24.     pu8I2CDMATxBuffer[0] = 0x78;        //从机地址
  25.     pu8I2CDMATxBuffer[1] = 0x40;            //写数据 (DC = 1)
  26.    
  27.     OLED_SendData(dat, len);            //发送数据序列
  28. }
  29. ////////////////////////////////////////
  30. // 发送OLED数据
  31. // 入口参数: dat (数据序列)
  32. //           len (数据长度)
  33. // 函数返回: 无
  34. ////////////////////////////////////////
  35. void OLED_SendData(uint8_t *dat, uint16_t len)
  36. {
  37.     memcpy(&pu8I2CDMATxBuffer[2], dat, len);
  38.     while (I2C_CheckMasterBusy());      //等待I2C模块退出忙状态
  39.     DMA_I2C_EnableDMA();                //发送DMA命令前,先使能I2C DMA功能
  40.     I2C_StartSendDataRecvACK();         //I2C DMA发送数据必须使用09命令
  41.     DMA_I2C_SetDMAAmount(len + 1);      //使能I2C DMA发送/接收总字节数
  42.     DMA_I2C_SetTxAmount(len + 1);       //设置I2C DMA发送总字节数
  43.     DMA_I2C_TriggerTx();                //触发I2C DMA发送
  44.     fI2CDMABusy = 1;                    //设置DMA传输忙标志
  45. }
复制代码
2.3、其它代码可参考附件中的代码完成
2.4、代码完成代码编写后,将编译生成的HEX文件下载到试验箱,同样也可看到如1楼的效果

OLED_I2C_DMA_Demo.rar

91.63 KB, 下载次数: 1

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:58
  • 最近打卡:2025-06-17 09:13:13

26

主题

1037

回帖

3950

积分

超级版主

积分
3950
发表于 昨天 17:27 | 显示全部楼层
本帖中的图片和字库均使用的是AIapp-ISP软件中的工具生成

截图202506161725442211.jpg

为配合OLED12864的数据存放格式
图片取模工具需要进行如下转换设置

截图202506161723478345.jpg

本帖中的演示字库使用的是16*16的汉字点阵
字库生成工具需要进行如下设置

截图202506161726202159.jpg
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:435
  • 最近打卡:2025-06-17 05:33:44

28

主题

337

回帖

2798

积分

荣誉版主

积分
2798
发表于 昨天 21:13 | 显示全部楼层
学习ing~
能体会到发现一个不理解的现象然后找原因然后要么解决掉问题要么被问题解决掉的那种快乐是我的幸运
回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-6-17 09:22 , Processed in 0.143632 second(s), 77 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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