文章基于适用于STM32F4系列,作者使用STM32F401CCU6开发板。
本文章基于此系列和开发板展开讨论。

本系列以SSD1306为主控芯片的I2C接口的0.96寸OLED屏幕为例介绍
内容较多,分节进行

链接

基础命令和寻址方法
IIC(I2C)协议

  1. OLED初始化,软件I2C实现,基础数据发送
  2. 满屏图像显示
  3. 全屏动画显示
  4. 显示字母和数字,汉字
  5. 画指定的点
  6. 指定两点画线段
  7. 指定圆心和半径画圆
  8. 指定圆心半径角度画圆弧

需求分析

在这一节中我们制作一个动画

动画的本质是一张张的图片间隔指定的时间投放到屏幕上,利用视觉暂留效应即可看到流畅的动画了

  1. 取模
  2. 显示图片
  3. 定时刷新

取模

因为网上没有找到可以批量取模的软件(一个几秒的动画就有几十上百张图片),因此我使用python写了个程序用于批量取模

没有python基础的可以直接使用

import cv2 as cv
import numpy as np
sl=50#数量
h=64#行数
l=128#列数
yz=140#阈值

sl=sl+1
def threshold_image(image,a):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    #cv.imshow('origin', gray)

    ret, binary = cv.threshold(gray, yz, 255, cv.THRESH_BINARY)# 自定义阈值为150,大于150的是白色 小于的是黑色
    #cv.imwrite("./1/"+str(a)+".bmp",binary)#输出
    #cv.imshow('origin',binary)#调试用
    #cv.waitKey(0)
    return binary

for a in range(1,sl):
    src = cv.imread(r"C:\Users\HZ1213825\Desktop\1\ ("+str(a)+").jpg")
    zj=threshold_image(src,str(a))
    tst=np.asarray(zj)
    np.set_printoptions(threshold=np.inf)
    js=0
    txt="\nconst uint8_t t"+str(a)+"[128][8]=\n{"
    # 取反用
    # for i in range(h):
    #     for j in range(l):
    #         if tst[i][j] == 255:
    #             tst[i][j]=0
    #         elif tst[i][j]==0:
    #             tst[i][j]=1

    # 不取反用
    for i in range(h):
        for j in range(l):
            if tst[i][j] == 255:
                tst[i][j]=1
            elif tst[i][j]==0:
                tst[i][j]=0
    t=0
    for i in range(0,h,8):
        for j in range(l):
            js=0
            for z in range(0,8):
                js=js*2+tst[i+7-z][j]
            txt+=str(hex(js))+","
            t+=1
            if t==16:
                txt+="\n"
                t=0
    txt=txt.rstrip(",")
    txt+="};"
    #print(tst)
    with open("1.txt","a") as fp:
        fp.write(txt)
    print("t"+str(a)+',',end="")

需要做一些前期准备,请使用pr将视频剪裁为128 * 64像素,并导出为JPG格式

pr操作

修改大小

导入媒体,双击或拖入都行

在这里插入图片描述

拖入工作区创建序列

在这里插入图片描述

进入序列设置

在这里插入图片描述

更改视频大小

在这里插入图片描述

更改视频位置和缩放

在这里插入图片描述

加入黑白效果(在效果的视频效果的图形设置里)(将这个黑白拖到视频上就行了)

在这里插入图片描述

导出

在这里插入图片描述

设置为导出Jpe序列

在这里插入图片描述

python操作

将导出的图片批量重命名(全选,重命名)

在这里插入图片描述

然后把名字删除,之后回车即可(别删后缀名)

在这里插入图片描述

打开python,将代码复制进去
设置图片序列的地址和名字

在这里插入图片描述

修改数量和阈值

在这里插入图片描述

可以将这两行代码前的#删除(取消注释),来观察阈值是否正确

在这里插入图片描述

这是测试(调阈值)的效果

在这里插入图片描述

在控制台将取模的数组名打印了出来,方便后续操作

在这里插入图片描述

在程序的同级目录有输出文件(1.txt)

在这里插入图片描述

已经将前缀和后缀写入了,直接复制到Keil工程中即可

在这里插入图片描述
这是软件链接:
CSDN

链接:百度网盘
提取码:c95i

显示动画

上文说过,动画就是一帧帧的图片间隔一段时间播放做成的

前期准备

为了更方便的将动画刷新,我建立一个结构体

其内部的参数是二维数组指针

头文件(OLED.H)

typedef struct
{
	uc8 (*TDArray)[128];
} OLED_Animation_Array;

在后面可以申请一个结构体数组

uc8 t1[8][128]={};
uc8 t2[8][128]={};
uc8 t3[8][128]={};
OLED_Animation_Array a[3]={t1,t2,t3};

调用时就可以将其作为数组调用,可以进入循环中使用了,就像这样

for(int i=0;i<3;i++)
a[i].TDArray[2][2]=0;

动画帧发送

发送一张图片的函数只需要稍作修改即可移植过来

C文件(OLED.C)

//动画实现函数 Array:含每帧数据的结构体
void OLED_Animation_Ation(OLED_Animation_Array Array)
{
	//使用水平寻址模式模式
	OLED_Write_Ctrl_Start();
	I2C_SendByte(0x20); //设置寻址模式 (0x00水平/0x01垂直/0x02页)
	I2C_SendByte(0x00); //水平寻址模式
	I2C_SendByte(0x21); //设置列地址
	I2C_SendByte(0x00);
	I2C_SendByte(0x7f);
	I2C_SendByte(0x22); //设置页地址
	I2C_SendByte(0x00);
	I2C_SendByte(0x07);
	I2C_End();

	OLED_Write_Data_Start();
	for (int i = 0; i < 8; i++) //扫描页
	{
		for (int j = 0; j < 128; j++) //扫描列
			I2C_SendByte(Array.TDArray[i][j]);
	}
	I2C_End();
}

动画实现

只需要间隔时间调用上文提到的动画帧发送函数即可,封装为函数

C文件(OLED.C)

//动画刷新函数(有需要修改的值) Time:间隔时间单位ms Num:帧的数量
void OLED_Animation(int Time, int Num)
{
	//这个需要修改,修改数组大小和内部值 将uc8 [128][8]的名字按顺序放入
	OLED_Animation_Array ac[50] = {t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22, t23, t24, t25, t26, t27, t28, t29, t30, t31, t32, t33, t34, t35, t36, t37, t38, t39, t40, t41, t42, t43, t44, t45, t46, t47, t48, t49, t50};
	OLED_Clear();
	for (int i = 1; i <= Num; i++)
	{
		OLED_Animation_Ation(ac[i - 1]);
		Delay_ms(Time);
	}
}

输入间隔时间和帧数量即可

成品

stm32控制OLED屏幕显示动画演示

CSDN

链接:百度网盘
提取码:ierk

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐