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

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);elseOLED_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);elseOLED_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);elseOLED_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);elseOLED_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
#elsereturn 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
#elseSSD1306.CurrentX = x;     //ssd1306:  x
#endif	SSD1306.CurrentY = y;
}
📓移植到stm32f103驱动工程:
链接:https://pan.baidu.com/s/1pJemQzj9RdLDVsKdlp55OA?pwd=5e5l 
提取码:5e5l

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

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用单一ASM-HEMT模型实现从X波段到Ka波段精确的GaN HEMT非线性仿真

来源&#xff1a;Accurate Nonlinear GaN HEMT Simulations from X- to Ka-Band using a Single ASM-HEMT Model 摘要&#xff1a;本文首次研究了ASM-HEMT模型在宽频带范围内的大信号准确性。在10、20和30 GHz的频率下&#xff0c;通过测量和模拟功率扫描进行了比较。在相同的频…

【进程概念】

目录 什么是在计算机运行的程序这么多运行的程序计算机是如何管理的先描述再组织 什么是在计算机运行的程序 对于一个在磁盘可执行的二进制文件&#xff0c;也可叫做可执行程序。对于一个可执行的程序&#xff0c;程序有自己的代码和数据。一旦运行起来&#xff0c;就会在计算…

【无标题】学习Markdown

https://shadows.brumm.af 欢迎使用Markdown编辑器 你好&#xff01; 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章&#xff0c;了解一下Markdown的基本语法知识。 新的改变 我们对Markdown编辑器进行了一些…

2.22 作业

顺序表 运行结果 fun.c #include "fun.h" seq_p create_seq_list() {seq_p L (seq_p)malloc(sizeof(seq_list));if(LNULL){printf("空间申请失败\n");return NULL;}L->len 0; bzero(L,sizeof(L->data)); return L; } int seq_empty(seq_p L) {i…

LaWGPT—基于中文法律知识的大模型

文章目录 LaWGPT&#xff1a;基于中文法律知识的大语言模型数据构建模型及训练步骤两个阶段二次训练流程指令精调步骤计算资源 项目结构模型部署及推理 LawGPT_zh&#xff1a;中文法律大模型&#xff08;獬豸&#xff09;数据构建知识问答模型推理训练步骤 LaWGPT&#xff1a;基…

深入理解C语言(5):程序环境和预处理详解

文章主题&#xff1a;程序环境和预处理详解&#x1f30f;所属专栏&#xff1a;深入理解C语言&#x1f4d4;作者简介&#xff1a;更新有关深入理解C语言知识的博主一枚&#xff0c;记录分享自己对C语言的深入解读。&#x1f606;个人主页&#xff1a;[₽]的个人主页&#x1f3c4…

【MySQL】数据库索引详解 | 聚簇索引 | 最左匹配原则 | 索引的优缺点

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;c系列专栏&#xff1a;C/C零基础到精通 &#x1f525; 给大…

mysql 2-22

变量 查看系统变量 修改 用户变量 赋值 定义处理程序 流程控制 IF CASE LOOP语句 WHILE循环 REPEAT leave ITERATE 游标 使用步骤 全局系统变量持久化 触发器 查看触发器 优点 MYSQL8的新特性 移除的旧特性 窗口函数 公用表表达式 JDBC 存储引擎 MYISAM存储引擎 InnoDB存储引擎…

【Redis】理论进阶篇------浅谈Redis的缓存穿透和雪崩原理

一、缓存穿透 1、概念 缓存穿透&#xff08;查不到数据&#xff09;&#xff0c;是指当用户想要查询数据的时候&#xff0c;会先去Redis中取命中&#xff0c;如果Redis中没有该数据&#xff0c;那么就会向数据库中去查找数据。如果数据库中也没有&#xff0c;则该次查询结果失…

Linux之信号

首先我们来了解一下信号的概念! 我们可以以上红框中的4个特点。 进程分为前台和后台进程,前台进程只有一个,后台进程可以有多个!(并且后台进程不能用ctrl+c中止,只能用kill -9去杀掉) jobs可以看作业标识号! (ctrl+z可以暂停进程,不能暂停前台进程,如果暂停就会被…

Eclipse中Working Sets是用来做什么的?

当Eclipse中创建了太多的project&#xff0c;太多了&#xff0c;看的眼花缭乱&#xff0c;不好管理,也不想更换工作空间&#xff0c;Eclipse中 Java Working Set 工作集&#xff0c;可以将这些project分组&#xff0c;就像文件夹分类存放文件一样。 多说一句&#xff0c;感觉E…

C++ Primer 笔记(总结,摘要,概括)——第2章 变量和基本类型

目录 2.1 基本内置变量 2.1.1 算术类型 2.1.2 类型转换 2.1.3 字面值常量 2.2 变量 2.2.1 变量定义 2.2.2 变量声明和定义的关系 2.2.3 标识符 2.2.4 名字的作用域 2.3 复合类型 2.3.1 引用 2.3.2 指针 2.3.3 理解复合类型的声明 2.4 const限定符 2.4.1 const的引用 2.4.2…