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的底层驱动代码(核心代码)
////////////////////////////////////////
////////////////////////////////////////
// 复位OLED
// 入口参数: 无
// 函数返回: 无
////////////////////////////////////////
void OLED_RESET()
{
OLED_RES = 1; delay_ms(200);
OLED_RES = 0; delay_ms(200); //复位
OLED_RES = 1;
}
////////////////////////////////////////
// 写OLED命令
// 入口参数: cmd (命令序列)
// len (命令长度)
// 函数返回: 无
////////////////////////////////////////
void OLED_WR_CMD(uint8_t *cmd, uint16_t len)
{
OLED_DC = 0; //写命令
OLED_SendData(cmd, len);
}
////////////////////////////////////////
// 写OLED数据
// 入口参数: dat (数据序列)
// len (数据长度)
// 函数返回: 无
////////////////////////////////////////
void OLED_WR_DAT(uint8_t *dat, uint16_t len)
{
OLED_DC = 1; //写数据
OLED_SendData(dat, len);
}
////////////////////////////////////////
// 发送OLED数据
// 入口参数: dat (数据序列)
// len (数据长度)
// 函数返回: 无
////////////////////////////////////////
void OLED_SendData(uint8_t *dat, uint16_t len)
{
OLED_CS = 0; //片选使能
while (len--)
{
SPI_SendData(*dat++); //写数据
while (!SPI_CheckFlag()); //等待数据发生完成
SPI_ClearFlag(); //清除完成标志
}
OLED_CS = 1; //片选禁能
}