一、作业目的:
1、了解I2C协议的基本原理和时序协议;
2、掌握0.96寸OLED屏的工作原理,汉字点阵显示原理;
3、掌握开源GUI库U82G在stm32上的移植编译方法,以及图形界面可视化技术。
二、具体过程
1、利用stm32f103的GPIO管脚、VCC和GND连接 OLED屏的I2C接口,采用cubemx设计一个HAL库程序框架,然后下载U82G源码,针对stm32f103和 0.96寸的I2C接口OLED屏,进行代码裁剪,然后移植到HAL程序程序中,完成OLED的各种显示,包括:
1)U82G的demo例程; 2)显示你自己的学号和名字(或网名昵称);3)掌握上下、左右滑动显示方法;4)显示一个图案(比如你的头像肖像),最好有动态效果。
- 如果使用Keil的虚拟逻辑分析仪去采集 I2C 引脚SDA的波形,是什么样子的? 如果无法采集到真实的I2C协议,你觉得可改用什么方法?
引脚连接:
OLED模块:
VCC --> 3.3V
GND --> GND
SCL --> PB10
SDA --> PB11
一、CubexMX配置
1、RCC配置外部高速晶振(精度更高)——HSE;

2、SYS配置:Debug设置成Serial Wire(否则可能导致芯片自锁);

3、I2C2配置:作为OLED的通讯方式;

4、TIM1配置:U8g2图形库需要us级延迟推动(U8g2的心跳)

5、时钟树配置:

6、工程配置

三、U8g2移植
3.1 准备U8g2库文件
移植U8g2图像库需要准备好,U8g2的源码是在GitHub上开源的。
U8g2下载地址: https://github.com/olikraus/u8g2

3.2 精简U8g2库文件
U8g2支持多种显示驱动的屏幕,因为源码中也包含了各个驱动对应的文件。
这里我们主要关注的是U8g2库文件中的csrc文件。

3.2.1 去掉无用的驱动文件
这些驱动文件通常是u8x8_d_xxx.c,xxx包括驱动的型号和屏幕分辨率。ssd1306驱动芯片的OLED,使用u8x8_ssd1306_128x64_noname.c这个文件,其它的屏幕驱动和分辨率的文件可以删掉。
3.2.2 精简u8g2_d_setup.c
由于笔者的OLED是IIC接口,只留一个本次要用到u8g2_Setup_ssd1306_i2c_128x64_noname_f就好(如果是SPI接口,需要使用u8g2_Setup_ssd1306_128x64_noname_f这个函数),其它的可以删掉或注释掉。


3.2.3 精简u8g2_d_memory.c
由于用到的u8g2_Setup_ssd1306_i2c_128x64_noname_f函数中,只调用了u8g2_m_16_8_f这个函数,所以留下这个函数


3.3 将精简后的U8g2库添加至Keil
左侧Keil工程目录添加自己精简后U8g2库文件中的csrc文件,然后再添加U8g2的头文件搜寻目录


四、代码
(1)U8g2 demo例程运行
直接调用U8g2库自带的测试函数,验证移植正确性:
void u8g2Demo(u8g2_t *u8g2) {
u8g2_FirstPage(u8g2);
do {
u8g2_SetFont(u8g2, u8g2_font_ncenB12_tf);
u8g2_DrawStr(u8g2, 10, 20, "U8g2 Demo");
u8g2_DrawFrame(u8g2, 5, 30, 118, 30); // 绘制矩形框
u8g2_DrawCircle(u8g2, 64, 45, 10); // 绘制圆形
} while (u8g2_NextPage(u8g2));
HAL_Delay(3000);
}
(2)学号显示
写入stm_u8g2.c文件,并在stm_u8g2.h文件中声明函数,最后在main.c开头#include"stm_u8g2.h",主程序就能调用这些函数了:
void displayIdName(u8g2_t *u8g2) {
u8g2_ClearBuffer(u8g2);
// 显示学号
u8g2_SetFont(u8g2, u8g2_font_ncenB12_tf);
u8g2_DrawStr(u8g2, 5, 20, "ID: 632307030231");
u8g2_SendBuffer(u8g2);
HAL_Delay(3000);
}
(3)上下/左右滑动显示
通过循环更新文本坐标偏移量,实现滑动效果:
// 左右滑动
void slideLeftRight(u8g2_t *u8g2) {
int x_offset = 128;
while (x_offset > -120) {
u8g2_ClearBuffer(u8g2);
u8g2_SetFont(u8g2, u8g2_font_ncenB14_tf);
u8g2_DrawStr(u8g2, x_offset, 32, "滑动测试");
u8g2_SendBuffer(u8g2);
x_offset -= 2;
HAL_Delay(20);
}
}
// 上下滑动
void slideUpDown(u8g2_t *u8g2) {
int y_offset = 64;
while (y_offset > -30) {
u8g2_ClearBuffer(u8g2);
u8g2_SetFont(u8g2, u8g2_font_ncenB14_tf);
u8g2_DrawStr(u8g2, 20, y_offset, "上下滑动");
u8g2_SendBuffer(u8g2);
y_offset -= 2;
HAL_Delay(20);
}
}
- main函数整合
在main.c中初始化硬件和U8g2库,按顺序调用各功能函数:
#include "main.h"
#include "i2c.h"
#include "tim.h"
#include "gpio.h"
#include "u8g2.h"
#include "stm32_u8g2.h"
int main(void) {
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_I2C2_Init();
u8g2_t u8g2;
u8g2Init(&u8g2); // U8g2初始化
while (1) {
u8g2Demo(&u8g2); // 1. demo例程
displayIdName(&u8g2); // 2. 学号
slideLeftRight(&u8g2); // 3. 左右滑动
slideUpDown(&u8g2); // 3. 上下滑动
}
}
五、实验效果
U8g2 demo例程:OLED屏成功显示“U8g2 Demo”文本、矩形框和圆形,验证了U8g2库移植正确。

学号显示:学号“632307030127”清晰显示,无乱码。

滑动显示:文本从屏幕边缘平滑滑入、滑出,左右和上下滑动效果流畅,速度均匀。
2万+

被折叠的 条评论
为什么被折叠?



