AiCube 图形化程序自动生成【SPI,SPI-DMA,I2C,I2C-DMA】代码,
===驱动 OLED-12864,4种 通信组合,一网打尽
===使用 AiCube 生成基于 Ai8051U 的 I2C / SPI 代码
大家可以轻松改到 STC8H8K64U / STC32G12K128 系列

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

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

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

2、OLED-12864屏接口
本帖的测试环境使用的是Ai8051U试验箱V1.2,试验箱上的OLED12864接口如下图所示:

此部分的接口电路图如下:

SPI使用的是: SS(P3.5), MOSI(P3.4), MISO(P3.3), SCLK(P3.2)这组端口
===但 进行了 MOSI / MISO 切换,也就是 SPI 变成了
                        SS(P3.5), MISO(P3.4), MOSI(P3.3), SCLK(P3.2)
                        强推挽       准双向口         强推挽            强推挽
I2C使用的是:SCL(P3.2), SDA(P3.3)这组端口
                       准双向口      准双向口
                       开漏+上拉   开漏+上拉

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

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


3.1、在图形化I/O配置界面中选择SPI的P3口切换组

3.2、在图形化I/O配置界面对OLED相关的I/O模式做如下配置
(特别说明:为适配Ai8051U试验箱的电路图,本范例的SPI需要交换MISO和MOSI管脚功能,
原本的MISO脚需要当作MOSI功能脚进行配置为强推挽)

3.3、在图形化I/O配置界面配置完成后,务必勾选相应的端口,如下图
若不勾选,则AiCube不会生成相应的初始化代码
 

3.4、如下图对SPI功能模块进行配置

(特别说明:为适配Ai8051U试验箱的电路图,本范例的SPI需要交换MISO和MOSI管脚功能
下图中“交换MISO和MOSI功能脚”项需要配置为“是”)
 


3.5、完成上面的配置点击AiCube界面中的“创建Keil项目”按钮即可生成Keil项目框架及相应的代码

4、完善代码添加OLED驱动代码
4.1、添加OLED驱动代码和数据代码到项目中
打开AiCube自动生成的Keil项目,将OLED驱动代码"oled.c"和图片字库代码"tab.c"添加到项目中

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文件下载到试验箱,即可看到如下效果

演示了使用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的配置
 

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文件下载到试验箱,同样也可看到的效果

演示了使用AiCube生成 硬件 SPI 代码 驱动OLED的流程
演示使用AiCube生成 硬件 I2C 代码 驱动OLED的流程

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

1.1、在图形化I/O配置界面中选择I2C的P3口切换组

1.2、在图形化I/O配置界面对OLED相关的I/O模式做如下配置
 


1.3、在图形化I/O配置界面配置完成后,务必勾选相应的端口,如下图
若不勾选,则AiCube不会生成相应的初始化代码
 


1.4、如下图对I2C功能模块进行配置
 


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. }

演示了使用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的配置
 


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楼的效果

本帖中的图片和字库均使用的是AIapp-ISP软件中的工具生成

 



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



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

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐