HAL STM32 HW I2C DMA + SSD1306/SH1106驱动示例

news2024/9/22 22:41:27

HAL STM32 HW I2C DMA + SSD1306/SH1106驱动示例


  • 📍硬件I2C DMA驱动参考:https://blog.csdn.net/weixin_45065888/article/details/118225993

  • 📌github上的相关项目:https://github.com/taburyak/STM32_OLED_SSD1306_HAL_DMA

  • 🔖本工程基于STM32F103VCT6,驱动程序独立,可以移植到任意STM32型号上使用。

在这里插入图片描述

📑字体大小说明

  • 🌿该驱动程序ASCII字符集类型大小包含:6X8、8X16,12X6 三种。其中6X8和8X16共用一个API函数调用,形参不同。
//针对F6x8、F8X16字体
void OLED_show_char2(uint8_t row, uint8_t col, uint8_t chr, uint8_t size)
{
    uint8_t x ;
    uint8_t y;
    if(size == 8){
		x = col * 6;
        y = row * 8;
		}
    else {
		x = col * 8;
        y = row * 16;		
		}
    uint8_t temp, t, t1;
    uint8_t y0 = y;
    chr = chr - ' ';
    if(size == 16) {
           for(t = 0; t < 8; t++) {
            temp = F8X16[chr*16+t];
            for(t1 = 0; t1 < 8; t1++) {
                if(temp & 0x01)
                    OLED_draw_point(x, y, PEN_WRITE);
                else
                    OLED_draw_point(x, y, PEN_CLEAR);

                temp >>= 1;
                y++;
                if((y - y0) == 8) {
                    y = y0;
                    x++;
                    break;
                }
            }
					}
						for(t = 0; t < 8; t++) {
            temp = F8X16[chr*16+t+8];
            for(t1 = 0; t1 < 8; t1++) {
                if(temp & 0x01)
                    OLED_draw_point(x-8, y+8, PEN_WRITE);
                else
                    OLED_draw_point(x-8, y+8, PEN_CLEAR);

                temp >>= 1;
                y++;
                if((y - y0) == 8) {
                    y = y0;
                    x++;
                    break;
                }
            }
					} 
    
    } else {

        for(t = 0; t < 6; t++) {
            temp = F6x8[chr][t];
            for(t1 = 0; t1 < 8; t1++) {
                if(temp & 0x01)
                    OLED_draw_point(x, y, PEN_WRITE);
                else
                    OLED_draw_point(x, y, PEN_CLEAR);

                temp >>= 1;
                y++;
                if((y - y0) == 8) {
                    y = y0;
                    x++;
                    break;
                }
            }
        }

    }
}
//6X12字体
void OLED_show_char(uint8_t row, uint8_t col, uint8_t chr)
{

    uint8_t x = col * 6;
    uint8_t y = row * 12;
    uint8_t temp, t, t1;
    uint8_t y0 = y;
    chr = chr - ' ';

    for(t = 0; t < 12; t++) {
        temp = asc2_1206[chr][t];

        for(t1 = 0; t1 < 8; t1++) {
            if(temp & 0x80)
                OLED_draw_point(x, y, PEN_WRITE);
            else
                OLED_draw_point(x, y, PEN_CLEAR);

            temp <<= 1;
            y++;
            if((y - y0) == 12) {
                y = y0;
                x++;
                break;
            }
        }
    }
}

🛠 0.96" SSD1306和1.3" SH1106切换,代码调整

void OLED_set_pos(uint8_t x, uint8_t y)
{
    OLED_CMDbuf[y][0] = 0x00;
    OLED_CMDbuf[y][1] = 0xb0 + y;
    OLED_CMDbuf[y][2] = 0x10;
	OLED_CMDbuf[y][3] = 0x00; //ssd1306:0x00;sh1106:0x02

}

🔨STM32CubeMX配置

  • 🌿开启硬件硬件I2C:
    在这里插入图片描述

  • 🌿勾选I2C DMA 发送数据(TX):

在这里插入图片描述

  • 🌿中断(NVIC)列表勾选I2C1 event interrupt,优先级配置,根据个人使用环境配置。
    在这里插入图片描述

📝测试代码

int main(void)
{
    /* USER CODE BEGIN 1 */
//    float num = 3.14;
    /* USER CODE END 1 */

    /* MCU Configuration--------------------------------------------------------*/

    /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
    HAL_Init();

    /* USER CODE BEGIN Init */

    /* USER CODE END Init */

    /* Configure the system clock */
    SystemClock_Config();

    /* USER CODE BEGIN SysInit */

    /* USER CODE END SysInit */

    /* Initialize all configured peripherals */
    MX_GPIO_Init();
    MX_DMA_Init();
    MX_I2C1_Init();
    MX_USART1_UART_Init();
    /* USER CODE BEGIN 2 */

    OLED_init(); //OLED初始化
    OLED_operate_gram(PEN_CLEAR);//清缓存

    /* USER CODE END 2 */

    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while(1) {
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
        OLED_operate_gram(PEN_CLEAR);//清缓存
        OLED_showString(0, 2, (uint8_t*)"China Loong",16);
        OLED_show_string(2, 3, (uint8_t*)"perseverance");

        OLED_refresh_gram();//全局刷新
        HAL_Delay(1500);
        OLED_operate_gram(PEN_CLEAR);//清缓存
        OLED_show_string(3, 3, (uint8_t*)"Hello World");
        OLED_show_string(4, 3, (uint8_t*)"DISPLAY China");
        OLED_refresh_gram();//全局刷新
        HAL_Delay(1500);

		

    }
    /* USER CODE END 3 */
}
📚测试例程
链接:https://pan.baidu.com/s/1jkwfS7BmxVZHrDrhvrBWJw?pwd=h6s3 
提取码:h6s3

📗基于Github项目例程

  • 📍项目地址:https://github.com/taburyak/STM32_OLED_SSD1306_HAL_DMA
  • 🔖 该项目提供了3种ASCII字符集字体:7x10、11x18、16x26。驱动显示提供了硬件I2C加可选DMA传输方式。屏幕类型执行128X64、128X32类型。
  • ✨该项目需要自行提前通过STM32CubeMX配置好项目,然后将驱动文件拷贝到工程中。
🛠配置方法
  • 🌿STM32CubeMX配置基本工程,如果需要开启DMA需要添加对应的选项。
  • 🌿I2C相关配置参数,ssd1306_defines.h
#define  SCREEN_TYPE   1    //SSD1306_12864:0 ; SH1106_13264:1
//#define USE_DMA					// uncomment if used I2C DMA mode
#define STM32_I2C_PORT		hi2c1 	// I2C port as defined in main generated by CubeMx
#define SSD1306_ADDRESS		0x3C	// I2C address display
#define SSD1306_128X64 				// OR #define SSD1306_128X32
  • 📄驱动显示示例:
			ssd1306_Init();
			ssd1306_FlipScreenVertically(); //垂直翻转显示 内容旋转180			
			ssd1306_Clear();
			ssd1306_SetCursor(0, 0); //显示位置
			ssd1306_SetColor(White); //设置显示字符颜色
			ssd1306_WriteString((char*)"Hello World", Font_7x10); //显示字符串 字体类型
			ssd1306_UpdateScreen();
  • 🔧SSD1306/SH1106补充定义:
  • ssd1306_defines.h添加:
#define  SCREEN_TYPE   1    //SSD1306_12864:0 ; SH1106_13264:1


  • 🔨在ssd1306.c文件中调整:
//
// Get a width and height screen size
//
static  uint16_t width(void)
{
#if(SCREEN_TYPE)
	return (SSD1306_WIDTH + 2);  //sh1106: +2
#else
	return SSD1306_WIDTH;  //SSD1306
	
#endif	
};

//
//	Position the cursor
//
void ssd1306_SetCursor(uint8_t x, uint8_t y)
{
#if(SCREEN_TYPE)
	SSD1306.CurrentX = x|0x02;  //sh1106: x|0x02
#else
	 SSD1306.CurrentX = x;     //ssd1306:  x
#endif	
  SSD1306.CurrentY = y;
}
📓移植到stm32f103驱动工程:
链接:https://pan.baidu.com/s/1pJemQzj9RdLDVsKdlp55OA?pwd=5e5l 
提取码:5e5l

🔖此文章仅作为个人学习探索知识的总结,不作为他人或引用者的理论依据,由于学识所限,难免会出现错误或纰漏,欢迎大家指正。

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

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

相关文章

typescript映射类型

ts映射类型简介 TypeScript中的映射类型&#xff08;Mapped Type&#xff09;是一种高级类型&#xff0c;它允许我们基于现有类型创建新的类型&#xff0c;同时对新类型的每个属性应用一个转换函数。通过使用映射类型&#xff0c;我们可以方便地对对象的属性进行批量操作&…

猫头虎分享已解决Bug || 系统更新失败(System Update Failure):UpdateError, UpgradeFailure

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

nginx详细教程

一、nginx简介 1. 概述 Nginx 是一款轻量级的 Web 服务器/反向代理服务器及电子邮件&#xff08;IMAP/POP3&#xff09;代理服务器&#xff0c;在 BSD-like 协议下发行。其特点是占有内存少&#xff0c;并发能力强&#xff0c;事实上 nginx 的并发能力在同类型的网页服务器中…

VMware连通问题

虚拟机配好后发现竟然到网关都不通做了一系列排查后 最后在真机上查看发现VMware的NAT服务没有开启 WinR输入services.msc&#xff0c;启动VMware NAT Service后问题就解决了&#xff01;

【软件架构】02-复杂度来源

1、性能 1&#xff09;单机 受限于主机的CPU、网络、磁盘读写速度等影响 在多线程的互斥性、并发中的同步数据状态等&#xff1b; 扩展&#xff1a;硬件资源、增大线程池 2&#xff09;集群 微服务化拆分&#xff0c;导致调用链过长&#xff0c;网络传输的消耗过多。 集…

L2 清点代码库----PTA(疑问)

上图转自新浪微博&#xff1a;“阿里代码库有几亿行代码&#xff0c;但其中有很多功能重复的代码&#xff0c;比如单单快排就被重写了几百遍。请设计一个程序&#xff0c;能够将代码库中所有功能重复的代码找出。各位大佬有啥想法&#xff0c;我当时就懵了&#xff0c;然后就挂…

基于SpringBoot+MyBatis-Plus的教务管理系统

基于SpringBootMyBatis-Plus的教务管理系统 教务管理系统开发技术功能模块代码结构数据库设计运行截图源码获取 教务管理系统 欢迎访问此博客&#xff0c;是否为自己的毕业设计而担忧呢&#xff1f;是否感觉自己的时间不够做毕业设计呢&#xff1f;那你不妨看一下下面的文章&a…

QFileDialog文件选择对话框

QFileDialog 类是 Qt 框架中用于处理文件对话框的一个类&#xff0c;它继承自 QDialog。QFileDialog 提供了标准的文件选择对话框&#xff0c;使用户能够选择文件或目录。这个类可以用于打开或保存文件&#xff0c;也可以用来选择目录。 主要功能 打开和保存文件&#xff1a;…

什么是测试?测试测什么?

笔者是软件测试方向的硕士研究生。作为应届生拿下了20余个软件测试、测试开发的offer。 《校招生如何准备测试》系列会将我的测试理论体系与大家分享、探讨和学习。本期主要串联一下什么是测试、软件测试测什么&#xff08;测试类型&#xff09;。 Q&#xff1a;什么是软件测…

华清远见嵌入式学习——驱动开发——DAY8

作业要求&#xff1a; 1.使用GPIO子系统编写LED灯驱动&#xff0c;应用程序测试 2.注册三个按键的中断&#xff0c;只需要写内核代码 需要发布到CSDN 作业答案&#xff1a; GPIO子系统&#xff1a; 代码效果&#xff1a; 应用程序&#xff1a; #include<stdlib.h> …

【MySQL】学习连接查询和案例演示

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-vycqHoIbdg9sSKEo {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

收单外包机构备案2023年回顾和2024年展望

孟凡富 本文原标题为聚合支付深度复盘与展望&#xff0c;首发于《支付百科》公众号&#xff01; 收单外包服务机构在我国支付收单市场中占据着举足轻重的地位&#xff0c;其规模在政策引导和市场需求驱动下不断扩大。同时&#xff0c;随着行业自律管理体系的持续发展和完善&a…

Debezium发布历史139

原文地址&#xff1a; https://debezium.io/blog/2023/02/04/ddd-aggregates-via-cdc-cqrs-pipeline-using-kafka-and-debezium/ 欢迎关注留言&#xff0c;我是收集整理小能手&#xff0c;工具翻译&#xff0c;仅供参考&#xff0c;笔芯笔芯. DDD Aggregates via CDC-CQRS Pi…

大数据揭秘:Hadoop短视频流量分析实战

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

Mybatis速成(二)

文章目录 1. Mybatis基础操作1.1 需求1.2 准备1.3 删除1.3.1 功能实现1.3.2 日志输入1.3.3 预编译SQL1.3.3.1 介绍1.3.3.2 SQL注入1.3.3.3 参数占位符 1.4 新增1.4.1 基本新增1.4.2 主键返回 1.5 更新1.6 查询1.6.1 根据ID查询1.6.2 数据封装1.6.3 条件查询1.6.4 参数名说明 2.…

相机图像质量研究(25)常见问题总结:CMOS期间对成像的影响--过曝、欠曝

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结&#xff1a;光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结&#xff1a;光学结构对成…

HTTP REST 方式调用WebService接口(wsdl)

一、WebService接口正常使用SOAP协议调用&#xff0c;测试时常采用SoapUI软件调用&#xff0c;具体如下&#xff1a; 二、由于目前主流web服务逐渐转换为RESTful的形式&#xff0c;且SOAP协议的实现也是基于HTTP协议&#xff0c;故存在通过HTTP调用WebService接口的可能 2.1 …

第一个Qt程序中的秘密

创建第一个程序 首先我们打开Qt Creator 打开文件->New Projects... 菜单&#xff0c;创建我们的第一个Qt项目 选择 Qt Widgets Application&#xff0c;点击选择...按钮 之后&#xff0c;输入项目名称QtLearning&#xff0c;并选择创建路径&#xff0c; 在build system中选…

ClickHouse--11--ClickHouse API操作

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.Java 读写 ClickHouse API1.1 首先需要加入 maven 依赖1.2 Java 读取 ClickHouse 集群表数据JDBC--01--简介 ClickHouse java代码 1.3 Java 向 ClickHouse 表中写…

1分钟带你了解Python数据类型

1.Python 3 主要有6种标准数据类型 Number&#xff08;数字&#xff09; String&#xff08;字符串&#xff09; List&#xff08;列表&#xff09; Tuple&#xff08;元组&#xff09; Set&#xff08;集合&#xff09; Dictionary&#xff08;字典&#xff09; 2.Numb…