(五)STM32F407 cubemx IIC驱动OLED(3)软件篇

news2025/2/23 14:28:08

  这篇文章主要是个人的学习经验,想分享出来供大家提供思路,如果其中有不足之处请批评指正哈。
  废话不多说直接开始主题,本人是基于STM32F407VET6芯片,但是意在你看懂这篇文章后,不管是F1,F4,H7等一系列系统硬件IIC配置都能明白如何通过参考手册、数据手册去学习配置。而不是Ctrl c,Ctrl v。这篇文章是对OLED 软件配置方面的介绍,如何参考数据手册编写代码。
  废话不多说,直接开始根据上文的寄存器步骤指示编写代码。

一、CubeMX初始化工作

1)时钟配置
  在这里插入图片描述  本人时钟使用的都是外部晶振,时钟树配置见下图。
  在这里插入图片描述

2)下载器配置
在这里插入图片描述


3)IIC配置
在这里插入图片描述

4)项目地址
在这里插入图片描述5)



5)生成代码
在这里插入图片描述
以上就是工程的大致配置。

二、软件程序编写

1)按照数据手册指示,编写寄存器数据步骤,详见硬件篇
在这里插入图片描述寄存器数组构建

/**********************************************************
 * 初始化命令,根据芯片手册书写,详细步骤见上图以及注意事项
 ***********************************************************/
uint8_t CMD_Data[]={
0xAE, 0xD5, 0x80, 0xA8, 0x3F, 0xD3, 0x00, 0x40,0xA1, 0xC8, 0xDA,

0x12, 0x81, 0xCF, 0xD9, 0xF1, 0xDB, 0x40, 0xA4, 0xA6,0x8D, 0x14,

0xAF};

1.如果Co位设置为逻辑"0",则以下信息的传输将仅包含数据字节。
2.D/C#位决定下一个数据字节是作为命令还是数据。如果D/C#位设置为逻辑"0",则将以下数据字节定义为命令。如果D/C#位被设置为逻辑"1",则其将以下数据字节定义为将被存储在GDDRAM中的数据。GDDRAM列地址指针将在每次数据写入后自动增加1。

  总结:发送命令时地址为0x00,发送数据时地址为0x40而且其会递增,这也是书写代码的关键部分。
详细请参考硬件篇------3)I2C总线时钟信号(SCL)

2)构造IIC发送函数 IIC1,地址0x78,命令格式地址0x00,数据格式地址0x40

//为数组命令发送方式
void WriteCmd(void)
{
	uint8_t i = 0;
	for(i=0; i<23; i++)
	{
		HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,&CMD_Data[i],1,0x100);
	}
}
/**
 * @function: void OLED_WR_CMD(uint8_t cmd)
 * @description: 向设备写控制命令,单字节发送方式
 * @param {uint8_t} cmd 芯片手册规定的命令
 * @return {*}
 */
void OLED_WR_CMD(uint8_t cmd)
{
	HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x00,I2C_MEMADD_SIZE_8BIT,&cmd,1,0x100);
}

/**
 * @function: void OLED_WR_DATA(uint8_t data)
 * @description: 向设备写控制数据
 * @param {uint8_t} data 数据
 * @return {*}
 */
void OLED_WR_DATA(uint8_t data)
{
	HAL_I2C_Mem_Write(&hi2c1 ,0x78,0x40,I2C_MEMADD_SIZE_8BIT,&data,1,0x100);
}

3)显示以及清空
1.设置页寻址模式的较高列起始地址(10 h ~1Fh)此命令指定页寻址模式下显示数据RAM的8位列起始地址的较高半字节。列地址将随着每次数据访问而递增。
2.设置页面寻址模式的页面起始地址(B 0 h ~ B7 h)此命令在页面寻址模式下将GDDRAM中的页面起始地址从0定位到7,不会递增。
在这段代码中,你就要明白寄存器地址0x00对应的是行,而且会不断递增,首先你要明白第一步需要设置页0xb0,然后设置列,从第零列开始0x00,它会自行递增所以只要配一个循环即可,通过写入0xff=1111,1111控制8个位都点亮。

void OLED_On(void)
{
	uint8_t i,n;
	for(i=0;i<8;i++)
	{
		OLED_WR_CMD(0xb0+i);    //设置页地址(0~7)
		OLED_WR_CMD(0x00);      //设置显示位置—列低地址
		OLED_WR_CMD(0x10);      //设置显示位置—列高地址
		for(n=0;n<128;n++)
		OLED_WR_DATA(0xff);
	}
}

在这里插入图片描述

/**
 * @function: OLED_Clear(void)
 * @description: 清屏
 * @return {*}
 */
void OLED_Clear(void)
{
	uint8_t i,n;
	for(i=0;i<8;i++)
	{
		OLED_WR_CMD(0xb0+i);    //设置页地址(0~7)
		OLED_WR_CMD(0x00);      //设置显示位置—列低地址
		//OLED_WR_CMD(0x10);      //设置显示位置—列高地址
		for(n=0;n<128;n++)
		OLED_WR_DATA(0x0);
	}
}

在这里插入图片描述

4)坐标显示代码
  坐标显示就得明白使用的是哪两个寄存器,一个是X坐标寄存器(列指标),一个是Y坐标寄存器(行坐标页)。(00h~1Fh)列坐标x、(B0-B7h)行坐标y。但是x坐标需要注意的是当想要点亮127列时,127=0x7f=0111,1111。0x7f这个数据需要拆分成高位数据以及低位数据。即命令行需要发送0x0f、0x17即可。基于此编写一种分别读取高位数据以及低位数据的算法并分别发送命令行。

OLED_Set_Pos(64,4);  //居中显示函数
/**
 * @function: void OLED_Set_Pos(uint8_t x, uint8_t y)
 * @description: 坐标设置
 * @param {uint8_t} x,y注意x是0-15,y是0-7
 * @return {*}
 */
void OLED_Set_Pos(uint8_t x, uint8_t y)
{
	OLED_WR_CMD(0xb0+y);	//设置页地址(0~7)
	OLED_WR_CMD(((x&0xf0)>>4)|0x10); //设置显示位置—列低地址
	OLED_WR_CMD(x&0x0f);	//设置显示位置—列高地址
	OLED_WR_DATA(0X18);  //00011000中间两个亮
}

在这里插入图片描述
5)显示图片
显示图片函数

/**
 * @function: void OLED_DrawBMP(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t *  BMP,uint8_t Color_Turn)
 * @description: 在OLED特定区域显示BMP图片
 * @param {uint8_t} x0图像开始显示横坐标  x0:0~127
 * @param {uint8_t} y0图像开始显示纵坐标  y0:0~7
 * @param {uint8_t} x1图像结束显示横坐标  x1:1~128
 * @param {uint8_t} y1图像结束显示纵坐标  y1:1~8
 * @param {uint8_t} *BMP待显示的图像数据
 * @param {uint8_t} Color_Turn是否反相显示(1反相、0不反相)
 * @return {*}
 */
void OLED_DrawBMP(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t *  BMP,uint8_t Color_Turn)
{
   uint32_t j = 0;
   uint8_t x = 0, y = 0;

  if(y1%8==0)
		y = y1/8;
  else
		y = y1/8 + 1;
	for(y=y0;y<y1;y++)
	{
		OLED_Set_Pos(x0,y);
    for(x=x0;x<x1;x++)
		{
			if (Color_Turn)
				OLED_WR_DATA(~BMP[j++]);//显示反相图片
			else
				OLED_WR_DATA(BMP[j++]);//显示图片

		}
	}
}

图片字符代码需要使用取模软件编写字符。

显示图片字模软件本人是用的视频中的网址链接此处加个引用符号:

led.baud-dance.com
点不开的话复制一下打开。
页面视图如下图所示
在这里插入图片描述导入图片后,自动生成的字符代码

unsigned char bearData[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x5f, 0x9f, 0xdf, 0xef, 0xef, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, 0x17, 
0xd7, 0xe7, 0x07, 0x0f, 0x9f, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
0xff, 0xff, 0xff, 0x00, 0xfe, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xbf, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xf8, 0xe3, 
0x8f, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x07, 0xf3, 0xfd, 0xec, 0xe7, 0x91, 0x2f, 0x5d, 
0x7c, 0xfc, 0xdc, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x8f, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7c, 0x01, 0x1f, 0xff, 0xff, 0xff, 0xff, 
0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x07, 0x03, 0x01, 0x00, 0x01, 0x03, 0x07, 0x07, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
0x14, 0x0e, 0x1f, 0x1f, 0x1f, 0x0f, 0x07, 0x03, 0x00, 0x00, 0x00, 0x80, 0xc1, 0xe1, 0xff, 0xff, 0xfe, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xf8, 0xf8, 
0xf8, 0xf8, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 
0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
};
//const Image bearImg = {64, 64, bearData};

图片显示如下。
在这里插入图片描述

  至此OLED的基本工作原理大致有所了解,如有不足之处请批评指正哈。整体项目代码以及数据手册放在以下链接中了。
链接:https://pan.baidu.com/s/1l9G2n4-04w95X_IeJ7DZgg?pwd=1p8q
提取码:1p8q

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1670312.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Elastic 基于 RAG 的 AI 助手:利用 LLM 和私有 GitHub 问题分析应用程序问题

作者&#xff1a;来自 Elastic Bahubali Shetti 作为 SRE&#xff0c;分析应用程序比以往更加复杂。 你不仅必须确保应用程序以最佳状态运行以确保良好的客户体验&#xff0c;而且还必须了解某些情况下的内部工作原理以帮助排除故障。 分析基于生产的服务中的问题是一项团队运动…

迷宫中离入口最近的出口

题目链接 迷宫中离入口最近的出口 题目描述 注意点 maze[i][j] 要么是 ‘.’ &#xff0c;要么是 ‘’entrance.length 2entrance 一定是空格子出口的含义是 maze 边界上的空格子entrance格子不算出口 解答思路 广度优先遍历找到走i步时所能到达的所有节点位置&#xff0…

趋势交易如何交易?fpmarkets实例分享

通过之前的文章&#xff0c;各位聪明的投资者想必都已经知道什么是趋势交易了 &#xff01;但是趋势交易如何交易呢&#xff1f;其实很简单&#xff0c;只要理解了趋势交易的信号点以及如何获取的信号就能 很快的掌握如何使用趋势交易进行盈利&#xff0c;下面fpmarkets澳福就和…

实验过程演示【计算机网络实验】

前言 这是陈旧已久的草稿2023-05-20 11:23:54 这个是计算机网络的一个实验&#xff0c;现在也不知道这个是啥来着。 现在2024-5-12 22:33:17&#xff0c;发布到[计算机网络实验]专栏中。 实验过程演示 2023-5-18 20:17:45 1&#xff0e;搭建一个多跳网络拓扑&#xff0c;…

ViewModel 完全指南:实践与背后原理全解

一、引言 在现代Android应用开发中&#xff0c;处理UI数据的有效管理和状态保持是开发者面临的重要挑战之一。Google推出的Jetpack组件库中的ViewModel已成为解决这些问题的关键工具。ViewModel旨在以生命周期意识的方式存储和管理界面相关的数据&#xff0c;从而使数据在配置…

腐烂的橘子BFS

题目&#xff1a; 腐烂的橘子 在给定的 m x n 网格 grid 中&#xff0c;每个单元格可以有以下三个值之一&#xff1a; 值 0 代表空单元格&#xff1b; 值 1 代表新鲜橘子&#xff1b; 值 2 代表腐烂的橘子。 每分钟&#xff0c;腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子…

探索大语言模型代理(Agent):研究背景、通用框架与未来展望

引言 近年来&#xff0c;随着人工智能技术的飞速发展&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;在智能代理&#xff08;Agent&#xff09;领域中的应用已成为研究的热点。这些代理不仅能够模拟人类的认知过程&#xff0c;还能在复杂的社会环…

JPA@Entry报错Could not determine recommended JdbcType for Java type

问题很明显&#xff0c;无法自动决定类型&#xff0c;那就手动告诉该字段。 一、直接上解决方案 如果是一对一的关系用 OneToOne 如果是一对多的关系用 OneToMany 如果是多对一的关系用 ManyToOne 二、另一个无空构造函数的问题 使用注解后&#xff0c;注解报错找不到空的…

奇舞周刊第527期:​Virtual DOM(虚拟DOM) 的地位再一次被挑战 !!!

奇舞推荐 ■ ■ ■ Virtual DOM&#xff08;虚拟DOM&#xff09; 的地位再一次被挑战 &#xff01;&#xff01;&#xff01; 最近在前端圈有一个 Github Repo 算是蛮受关注的 - proposal-signals&#xff0c;这是一个由 Daniel Ehrenberg 为主导&#xff0c;向 TC39 提案的项目…

【学习笔记】人群归因分数 PAF 以及combined PAF(更新)

在此推荐2篇发表在lancet以及jama子刊上的paf文章&#xff0c;这两篇文章套路是一样的&#xff0c;只是在不同国家进行。 在计算combined PAF或者说weighted PAF的时候&#xff0c;先建立了相关矩阵&#xff0c;再做主成分分析&#xff0c;得到communality。详细信息大家可翻阅…

C语言之指针初阶

目录 前言 一、内存与地址的关系 二、指针变量 三、野指针 四、const 五、传值调用与传址调用 总结 前言 本文主要介绍C语言指针的一些基础知识&#xff0c;为后面深入理解指针打下基础&#xff0c;因此本文内容主要包括内存与地址的关系&#xff0c;指针的基本语法&…

Pycharm使用Anaconda虚拟环境

一、前置 安装 Pychram安装 Anaconda&#xff0c;并配置虚拟环境 参考&#xff1a; Anaconda虚拟环境 anaconda虚拟环境pytorch安装 二、在Pycharm中使用Anaconda的虚拟环境 打开 Pycharm的命令行可以看到 Anaconda 的虚拟环境已经启动。 三、问题集合 &#xff08;1&…

都是免费的SSL证书,有什么区别

国内做SSL证书的服务商还是比较多&#xff0c;但也不是所有服务商都提供免费的SSL证书&#xff0c;一般只有少数几家提供免费SSL证书。那么&#xff0c;同样都是免费的SSL证书&#xff0c;有哪些不一样的地方呢&#xff1f; 1、验证类型&#xff1a;免费SSL证书通常只提供域名…

什么是透明加密?如何用透明加密保护数据安全?

透明加密技术是近年来针对企业文件保密需求应运而生的一种文件加密技术。它的特点是对于使用者来说是“未知”或“透明”的&#xff0c;即在打开或编辑指定文件时&#xff0c;系统会自动对未加密的文件进行加密&#xff0c;对已加密的文件自动解密。文件在硬盘上以密文形式存在…

力扣HOT100 - 45. 跳跃游戏 II

解题思路&#xff1a; 贪心 class Solution {public int jump(int[] nums) {int end 0;int maxPosition 0;int steps 0;for (int i 0; i < nums.length - 1; i) {maxPosition Math.max(maxPosition, i nums[i]);if (i end) {end maxPosition;steps;}}return steps;…

跨镜动线分析全新升级,用AI发掘店内客流密码,助力精准营销

作为零售门店的管理者&#xff0c;你对消费者的喜好真的了解吗&#xff1f;你是否想过&#xff0c;有些你认为的冷门商品可能并非真的冷门&#xff0c;只是摆放的区域不合适。 在实际运营中&#xff0c;只有对门店商品、顾客喜好足够了解才能不断优化运营&#xff0c;提升业绩。…

六西格玛管理培训公司:事业进阶的充电站,助你冲破职场天花板!

六西格玛&#xff0c;源于制造业&#xff0c;却不仅仅局限于制造业。它是一种以数据为基础、以顾客为中心、以流程优化为手段的全面质量管理方法。通过六西格玛管理&#xff0c;企业可以系统性地识别并解决运营过程中的问题&#xff0c;提高产品和服务的质量&#xff0c;降低成…

Linux服务升级:OpenResty 升级1.25.3.1版本

目录 一、实验 1.环境 2.Windows 安装 Termius 3.Linux 部署 OpenResty 4.Linux 使用 OpenResty 实现内容展示&#xff08;content_by_lua&#xff09; 5.Linux 使用 OpenResty 实现重定向 &#xff08;rewrite_by_lua&#xff09; 6.Linux 使用 OpenResty 实现请求体&…

利用matplotlib和KNeighborsClassifier,进行DBSACN聚类算法

代码&#xff1a; # -*- coding: utf-8 -*- """ Created on Sat May 11 10:23:50 2024author: admin """ # 调用库 import numpy as np import matplotlib.pyplot as plt # 调用人工智能模型库 from sklearn.neighbors import KNeighborsClassi…

JVM 类的加载过程详解

文章目录 1. 哪些类需要加载2. 类加载步骤2.1 装载2.1.1 这个过程都做了什么事2.1.2 类的模板对象2.1.3 二进制流获取方式2.1.4 Class 实例的位置2.1.5 数组类的加载有什么不同 2.2 链接2.2.1 验证2.2.2 准备2.2.3 解析 2.3 初始化 1. 哪些类需要加载 在 Java 中数据类型分为 …