本帖最后由 沈夜 于 2024-1-2 18:52 编辑
(1)外设介绍
❖ 0.96寸OLED显示屏(驱动芯片:SSD1306 / SSD1315)
[color=rgba(0, 0, 0, 0.87)]0.96寸OLED显示屏是一种小尺寸的有机发光二极管(OLED)显示屏,具有许多优点和特点。以下是对0.96寸OLED显示屏的介绍: - 尺寸:0.96寸指的是显示屏的对角线尺寸,通常为0.96英寸(约24.4毫米),适合小型设备和紧凑空间。
- 分辨率:通常具有128x64像素的分辨率,可以显示清晰的图像和文本。
- 技术:采用OLED技术,每个像素都是自发光的,不需要背光,因此具有更高的对比度和更广的视角。
- 高亮度:OLED显示屏具有较高的亮度,即使在室外或明亮的环境下也能清晰可见。
- 低功耗:相比传统的液晶显示屏,OLED显示屏具有较低的功耗,可以延长电池寿命。
- 快速响应:OLED显示屏具有快速的响应时间,可以实现流畅的图像和动画效果。
- 色彩鲜艳:OLED显示屏可以呈现鲜艳、饱满的颜色,使图像更加生动逼真。
- 视角广:OLED显示屏具有广阔的视角,即使从不同的角度观看,图像仍然清晰可见。
- 薄型轻便:OLED显示屏采用薄型设计,重量轻,适合应用于便携式设备和可穿戴设备。
- 灵活性:某些OLED显示屏采用柔性基板制造,具有弯曲和弯折的能力,适用于柔性显示应用。
- 高对比度:OLED显示屏具有高对比度,黑色显示非常深黑,白色显示非常亮白,使图像更加清晰。
- 高刷新率:OLED显示屏具有高刷新率,可以实现流畅的视频播放和动态图像效果。
(2)外设规格参数
工作电压:3.3V
工作电流:9MA
模块尺寸:27.3 x 27.8 MM
像素大小:128(H) x 64(V)RGB
驱动芯片:SSD1306
通信协议:IIC
管脚数量:4 Pin(2.54mm间距排针)
(3)移植过程(资料介绍、移植至工程、引脚选择)
keil stm32 项目移植。
man.c 事例代码移植
- #include "stm32f10x.h" // Device header
- #include "Delay.h"
- #include "OLED.h"
- int main(void)
- {
- /*OLED初始化*/
- OLED_Init();
-
- /*在(0, 0)位置显示字符'A',字体大小为8*16点阵*/
- OLED_ShowChar(0, 0, 'A', OLED_8X16);
-
- /*在(16, 0)位置显示字符串"Hello World!",字体大小为8*16点阵*/
- OLED_ShowString(16, 0, "Hello World!", OLED_8X16);
-
- /*在(0, 18)位置显示字符'A',字体大小为6*8点阵*/
- OLED_ShowChar(0, 18, 'A', OLED_6X8);
-
- /*在(16, 18)位置显示字符串"Hello World!",字体大小为6*8点阵*/
- OLED_ShowString(16, 18, "Hello World!", OLED_6X8);
-
- /*在(0, 28)位置显示数字12345,长度为5,字体大小为6*8点阵*/
- OLED_ShowNum(0, 28, 12345, 5, OLED_6X8);
-
- /*在(40, 28)位置显示有符号数字-66,长度为2,字体大小为6*8点阵*/
- OLED_ShowSignedNum(40, 28, -66, 2, OLED_6X8);
-
- /*在(70, 28)位置显示十六进制数字0xA5A5,长度为4,字体大小为6*8点阵*/
- OLED_ShowHexNum(70, 28, 0xA5A5, 4, OLED_6X8);
-
- /*在(0, 38)位置显示二进制数字0xA5,长度为8,字体大小为6*8点阵*/
- OLED_ShowBinNum(0, 38, 0xA5, 8, OLED_6X8);
-
- /*在(60, 38)位置显示浮点数字123.45,整数部分长度为3,小数部分长度为2,字体大小为6*8点阵*/
- OLED_ShowFloatNum(60, 38, 123.45, 3, 2, OLED_6X8);
-
- /*在(0, 48)位置显示汉字串"你好,世界。",字体大小为固定的16*16点阵*/
- OLED_ShowChinese(0, 48, "你好,世界。");
-
- /*在(96, 48)位置显示图像,宽16像素,高16像素,图像数据为Diode数组*/
- OLED_ShowImage(96, 48, 16, 16, Diode);
-
- /*在(96, 18)位置打印格式化字符串,字体大小为6*8点阵,格式化字符串为"[%02d]"*/
- OLED_Printf(96, 18, OLED_6X8, "[%02d]", 6);
-
- /*调用OLED_Update函数,将OLED显存数组的内容更新到OLED硬件进行显示*/
- OLED_Update();
-
- /*延时3000ms,观察现象*/
- Delay_ms(3000);
-
- /*清空OLED显存数组*/
- OLED_Clear();
-
- /*在(5, 8)位置画点*/
- OLED_DrawPoint(5, 8);
-
- /*获取(5, 8)位置的点*/
- if (OLED_GetPoint(5, 8))
- {
- /*如果指定点点亮,则在(10, 4)位置显示字符串"YES",字体大小为6*8点阵*/
- OLED_ShowString(10, 4, "YES", OLED_6X8);
- }
- else
- {
- /*如果指定点未点亮,则在(10, 4)位置显示字符串"NO ",字体大小为6*8点阵*/
- OLED_ShowString(10, 4, "NO ", OLED_6X8);
- }
-
- /*在(40, 0)和(127, 15)位置之间画直线*/
- OLED_DrawLine(40, 0, 127, 15);
-
- /*在(40, 15)和(127, 0)位置之间画直线*/
- OLED_DrawLine(40, 15, 127, 0);
-
- /*在(0, 20)位置画矩形,宽12像素,高15像素,未填充*/
- OLED_DrawRectangle(0, 20, 12, 15, OLED_UNFILLED);
-
- /*在(0, 40)位置画矩形,宽12像素,高15像素,填充*/
- OLED_DrawRectangle(0, 40, 12, 15, OLED_FILLED);
-
- /*在(20, 20)、(40, 25)和(30, 35)位置之间画三角形,未填充*/
- OLED_DrawTriangle(20, 20, 40, 25, 30, 35, OLED_UNFILLED);
-
- /*在(20, 40)、(40, 45)和(30, 55)位置之间画三角形,填充*/
- OLED_DrawTriangle(20, 40, 40, 45, 30, 55, OLED_FILLED);
-
- /*在(55, 27)位置画圆,半径8像素,未填充*/
- OLED_DrawCircle(55, 27, 8, OLED_UNFILLED);
-
- /*在(55, 47)位置画圆,半径8像素,填充*/
- OLED_DrawCircle(55, 47, 8, OLED_FILLED);
-
- /*在(82, 27)位置画椭圆,横向半轴12像素,纵向半轴8像素,未填充*/
- OLED_DrawEllipse(82, 27, 12, 8, OLED_UNFILLED);
-
- /*在(82, 47)位置画椭圆,横向半轴12像素,纵向半轴8像素,填充*/
- OLED_DrawEllipse(82, 47, 12, 8, OLED_FILLED);
-
- /*在(110, 18)位置画圆弧,半径15像素,起始角度25度,终止角度125度,未填充*/
- OLED_DrawArc(110, 18, 15, 25, 125, OLED_UNFILLED);
-
- /*在(110, 38)位置画圆弧,半径15像素,起始角度25度,终止角度125度,填充*/
- OLED_DrawArc(110, 38, 15, 25, 125, OLED_FILLED);
-
- /*调用OLED_Update函数,将OLED显存数组的内容更新到OLED硬件进行显示*/
- OLED_Update();
-
- /*延时3000ms,观察现象*/
- Delay_ms(3000);
-
- while (1)
- {
- for (uint8_t i = 0; i < 4; i ++)
- {
- /*将OLED显存数组部分数据取反,从(0, i * 16)位置开始,宽128像素,高16像素*/
- OLED_ReverseArea(0, i * 16, 128, 16);
-
- /*调用OLED_Update函数,将OLED显存数组的内容更新到OLED硬件进行显示*/
- OLED_Update();
-
- /*延时1000ms,观察现象*/
- Delay_ms(1000);
-
- /*把取反的内容翻转回来*/
- OLED_ReverseArea(0, i * 16, 128, 16);
- }
-
- /*将OLED显存数组全部数据取反*/
- OLED_Reverse();
-
- /*调用OLED_Update函数,将OLED显存数组的内容更新到OLED硬件进行显示*/
- OLED_Update();
-
- /*延时1000ms,观察现象*/
- Delay_ms(1000);
- }
- }
复制代码 删除 不用的代码。
#include "stm32f10x.h" // Device header
#include "Delay.h"
确少一个 延时,你以为我要写一个一样的函数?
功能一样直接调用博流的库,可以 手动替换成bflb_mtimer_delay_ms
但是可以根据c语法,[color=rgba(0, 0, 0, 0.87)]在您的代码中添加以下宏定义:
#define Delay_ms(ms) bflb_mtimer_delay_ms(ms)
则无需修改任何代码。
oled.c i2c 移植
可见需要 修改的地方
OLED引脚初始化>>OLED_GPIO_Init,
I2C发送一个字节>>OLED_I2C_SendByte
iOLED写命令>>OLED_WriteCommand
OLED写数据>>OLED_WriteData
修改方法。直接复制 sdk里面的i2c代码即可
- /**
- * 函 数:OLED引脚初始化
- * 参 数:无
- * 返 回 值:无
- * 说 明:当上层函数需要初始化时,此函数会被调用
- * 用户需要将SCL和SDA引脚初始化为开漏模式,并释放引脚
- */
- void OLED_GPIO_Init(void)
- {
- struct bflb_device_s* gpio;
- board_init();
- //board_i2c0_gpio_init();
-
- gpio = bflb_device_get_by_name("gpio");
- /* I2C0_SCL */
- bflb_gpio_init(gpio, GPIO_PIN_0, GPIO_FUNC_I2C0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
- /* I2C0_SDA */
- bflb_gpio_init(gpio, GPIO_PIN_1, GPIO_FUNC_I2C0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
- i2c0 = bflb_device_get_by_name("i2c0");
- bflb_i2c_init(i2c0, 400000);
- //oled_write(OLED_CMD, OLED_init_cmd, sizeof(OLED_init_cmd) / sizeof(unsigned char));
- printf("OLED_Init over\r\n");
- }
复制代码
经过分析。原先工程用的是软件模拟i2c,本次使用的硬件库的。
I2C发送一个字节>>OLED_I2C_SendByte 这个不用移植,直接删掉。
iOLED写命令>>OLED_WriteCommand
OLED写数据>>OLED_WriteData
- /**
- * 函 数:OLED写命令
- * 参 数:Command 要写入的命令值,范围:0x00~0xFF
- * 返 回 值:无
- */
- void OLED_WriteCommand(uint8_t Command)
- {
- OLED_I2C_Start(); //I2C起始
- OLED_I2C_SendByte(0x78); //发送OLED的I2C从机地址
- OLED_I2C_SendByte(0x00); //控制字节,给0x00,表示即将写命令
- OLED_I2C_SendByte(Command); //写入指定的命令
- OLED_I2C_Stop(); //I2C终止
- }
复制代码 分析得来 就是发送从机地址,和命令。
里面的函数都用不到,直接删除。
OLED_I2C_Start(); I2C起始
OLED_I2C_SendByte(0x78);
OLED_I2C_Stop(); //I2C终止
- /**
- * 函 数:OLED写命令
- * 参 数:Command 要写入的命令值,范围:0x00~0xFF
- * 返 回 值:无
- */
- void OLED_WriteCommand(uint8_t Command)
- {
- oled_writea(0x00, &Command, 1);
- }
- /**
- * 函 数:OLED写数据
- * 参 数:Data 要写入数据的起始地址
- * 参 数:Count 要写入数据的数量
- * 返 回 值:无
- */
- void OLED_WriteData(uint8_t *Data, uint8_t Count)
- {
- uint8_t i;
-
- /*循环Count次,进行连续的数据写入*/
- for (i = 0; i < Count; i ++)
- {
- //OLED_I2C_SendByte(Data[i]); //依次发送Data的每一个数据
- oled_writea(0x40, &Data[i], 1);
- }
- //OLED_I2C_Stop(); //I2C终止
- }
复制代码
(4)移植验证
功能齐全 - 支持字符、数字、汉字、图像及各种绘图图形显示 优化大量代码,专业用 功能实现即可。 即使小白也能 简单学习就能使用。带注释。 PS:代码非原创,只是移植到了Ai-M61 代码无任何报错。
快速使用: 解压 修改 Makefile 文件
BL_SDK_BASE ?= D:\test\boliu\bouffalo_sdk/
为自己的sdk路径即可 #include "OLED.h"
/*OLED初始化*/
OLED_Init();
/*在(0, 0)位置显示字符'A',字体大小为8*16点阵*/
OLED_ShowChar(0, 0, 'A', OLED_8X16);
/*调用OLED_Update函数,将OLED显存数组的内容更新到OLED硬件进行显示*/
OLED_Update();
只需要引用一个,就能方便调用了。 高级设置: OLED.c
OLED_GPIO_Init 函 数:OLED引脚初始化
只需要替换
GPIO_PIN_0
GPIO_PIN_1
接可以修改自定义引脚
OLED_Data.c
添加没有的中文字库。 添加图像 都在此。 demo里面有详细的调用过程都非常简单。 取模教程
一:配置软件,点设置然后按照如下设置。
二:生成字模
三:安装他的格式 调整一下就行,删掉多余的,
复制没有的 即可。
效果如下。
(5)常见问题汇总
通过本次移植,复习了很多c语言的知识,真正解决问题。
感谢园长的这次活动
大家也可以看到,移植纯c代码 需要改的地方 并不多,
我甚至原封不动的 复制过来的 man文件,仅仅是添加了文件头
5.1文件找不到
打开CMakeLists.txt
添加文件包含,格式空格 一个文件名
target_sources(app PRIVATE oled.c OLED_Data.c)
5.2 编译器找不到路径
修改 Makefile 文件
BL_SDK_BASE ?= D:\test\boliu\bouffalo_sdk/
也可以 直接修改为sdk的绝对路径,这样你项目的目录 可以随便放在任何地方。
5.3 数据类型找不到。
引入c语言 库
能解决90%
#include <string.h>
#include <math.h>
#include <stdio.h>
#include <stdarg.h>
|
|