STM32之OLED显示

一、模块介绍

1、常见的显示设备

LED、数码管、点阵、LCD屏(1602/12864)、OLED屏(消费电子)

2、OLED屏的概述

OLED,即有机发光二极管(Organic Light-Emitting Diode),又称为有机电激光显示(Organic Electroluminesence Display, OELD)。因为具备轻薄、省电等特性,因此从2003 年开始,这种显示设备在 MP3 播放器上得到了广泛应用,而对于同属数码类产品的 DC与手机,此前只是在一些展会上展示过采用 OLED 屏幕的工程样品。自 2007 年后,寿命得到很大提高,具备了许多 LCD 不可比拟的优势

3、特性

型号:SH1106

尺寸:132 * 64个像素点(前两列和最后的两列显示不了东西)

像素点:一帧画面所能表示的最小的显示单位。

分辨率:横向像素点的个数 * 竖向像素点个数

通信方式:

硬线接线四线SPI的通信方式

二、硬件分析

1、引脚分布

A0管脚如果是低电平就是发送命令过去

A0管脚如果是高电平就是发送显示数据过去

OLED_SCL -- 时钟线

(MOSI)OLED_SI -- 输入对于OLED的驱动芯片

OLED_CS -- 片选线

OLED_RES -- 复位管脚

OLED_D/C -- 命令或数据引脚

IO口模拟SPI

使用SPI控制器

三、SPI通信

1、通信特点

4线SPI:同步串行全双工

3线SPI:同步串行半双工

2、通信速度

几十Mhz以上

3、通信模式

MODE0和MODE3:上升沿接收数据,下降沿发送数据

MODE1和MODE2:下降沿接收数据,上升沿发送数据

器件支持MODE0模式也支持MODE3,支持MODE1模式也支持MODE2

4、通讯图

四、软件编写

1、时序图

1. CS线要拉低
2. SPI符合模式0或者模式3,上升沿接收数据,下降沿发送数据
3. A0线拉低代表把刚刚传输过去的八位数据给到命令寄存器里,拉高代表传输到显存

2、OLED相关命令

假如现在想要从第1页开始显示就要把0xB0的指令发送出去

设置列地址分为了高四字节和低四字节

如果要去设置列地址就要分两次命令发送

当前如果要在第1列显示数据:

发送低位的列地址就是00

发送高位的列地址就是10

3、字模提取:

4、图像提取

五、流程

1、初始化GPIO口

复用功能

复用到哪里

PB3 -- SCL -- SPI1_SCL

PB5 -- SI -- SPI1_MOSI

PB13 -- RES -- 推挽输出

PB7 -- CS --  推挽输出

PA15 -- DC --  推挽输出

2、初始化SPI控制器

使用库函数:

先打开外设时钟

找Init函数

#include "spi.h"/****************************
函数功能:SPI管脚初始化
函数形参:u32 nms
函数返回值:void
函数说明:
PB3 -- SCL -- SPI1_SCL
PB5 -- SI -- SPI1_MOSI
PB13 -- RES -- 推挽输出
PB7 -- CS --  推挽输出
PA15 -- DC --  推挽输出
****************************/
void Spi_Port_Init(void)
{GPIO_InitTypeDef  GPIO_InitStruct;//定义了一个结构体变量SPI_InitTypeDef   SPI_InitStruct;  //1. 打开GPIOA的时钟RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//2. 配置GPIO口功能GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;//配置输出模式GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;//配置为推挽GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_13;//选择7号管脚GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;//无上下拉GPIO_InitStruct.GPIO_Speed = GPIO_Fast_Speed;//低速GPIO_Init(GPIOB, &GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_15;//选择15号管脚GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;//配置复用模式GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_5;//选择3和5号管脚GPIO_Init(GPIOB, &GPIO_InitStruct); //3.复用到哪里GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_SPI1);GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_SPI1);//4.SPI控制器初始化RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;//选择二分频SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;//前沿采集SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;//空闲时为低电平SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;//8位数据为一帧SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//选择全双工SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;//高位先发SPI_InitStruct.SPI_Mode = SPI_Mode_Master;//主模式SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;//软件从模式管理SPI_Init(SPI1,&SPI_InitStruct);SPI_Cmd(SPI1,ENABLE);//使能SPI1}/****************************
函数功能:SPI发送一个字节数据
函数形参:u8 data
函数返回值:void
函数说明:****************************/
void Spi_SendByte(u8 data)
{while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE) == RESET)//当前发送缓冲区为空才能跳出循环{}SPI_I2S_SendData(SPI1,data);//发送数据while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE) == RESET)//当前接收缓冲区为空才能跳出循环{}SPI_I2S_ReceiveData(SPI1);//接收数据}
#include "oled.h"/**********************************************************************************************************
* 函数名    :   OLED_writeByte
* 功能描述  :   oled字节写,向SH1106写入一个字节。 
* 参数说明  :   dat:要写入的数据/命令
* cmd:数据/命令标志 0,表示命令;1,表示数据;
* 返回值说明:   none
* 修改记录  : 
* 其他      :
**********************************************************************************************************/
void OLED_writeByte(u8 dat, u8 cmd)
{	cmd ? OLED_DC_SET() : OLED_DC_CLR();	OLED_select();		 Spi_SendByte(dat);OLED_deSelect();
} /**********************************************************************************************************
* 函数名    :   OLED_clear
* 功能描述  :   清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!	 
* 参数说明  :   none
* 返回值说明:   none
* 修改记录  : 
* 其他      :OLED;8页,每页132字节,
清屏:首先清除第1页,从第一个字节开始2
前面 & 后面 4列 因边框问题不处理
**********************************************************************************************************/
void OLED_clear(void)  
{  u8 i,n;		    for(i=0;i<8;i++)  //8页{  OLED_writeByte (0xb0+i,OLED_CMD);    //设置页地址(0~7)//从第2列(0x02)开始OLED_writeByte (0x02,OLED_CMD);      //设置显示位置—列低地址OLED_writeByte (0x10,OLED_CMD);      //设置显示位置—列高地址   for(n=0; n<130; n++)//到第130列{OLED_writeByte(0,OLED_DATA);   //息屏整个屏幕是黑色的!和没点亮一样!!!	}} //更新显示
}   /**********************************************************************************************************
* 函数名    :   Oled_init
* 功能描述  :   oled初始化 
* 参数说明  :   none
* 返回值说明:   none
* 修改记录  : 
* 其他      :
**********************************************************************************************************/void Oled_init(void)
{ Spi_Port_Init();	//管脚初始化OLED_RES_L;Delay_ms(100);OLED_RES_H;OLED_writeByte(0xAE,OLED_CMD);//--turn off oled panelOLED_writeByte(0x02,OLED_CMD);//---SET low column addressOLED_writeByte(0x10,OLED_CMD);//---SET high column addressOLED_writeByte(0x40,OLED_CMD);//--SET start line address  SET Mapping RAM Display Start Line (0x00~0x3F)OLED_writeByte(0x81,OLED_CMD);//--SET contrast control registerOLED_writeByte(0xCF,OLED_CMD); // SET SEG Output Current BrightnessOLED_writeByte(0xA1,OLED_CMD);//--SET SEG/Column Mapping     0xa0左右反置 0xa1正常OLED_writeByte(0xC8,OLED_CMD);//SET COM/Row Scan Direction   0xc0上下反置 0xc8正常OLED_writeByte(0xA6,OLED_CMD);//--SET normal displayOLED_writeByte(0xA8,OLED_CMD);//--SET multiplex ratio(1 to 64)OLED_writeByte(0x3f,OLED_CMD);//--1/64 dutyOLED_writeByte(0xD3,OLED_CMD);//-SET display offSET	Shift Mapping RAM Counter (0x00~0x3F)OLED_writeByte(0x00,OLED_CMD);//-not offSETOLED_writeByte(0xd5,OLED_CMD);//--SET display clock divide ratio/oscillator frequencyOLED_writeByte(0x80,OLED_CMD);//--SET divide ratio, SET Clock as 100 Frames/SecOLED_writeByte(0xD9,OLED_CMD);//--SET pre-charge periodOLED_writeByte(0xF1,OLED_CMD);//SET Pre-Charge as 15 Clocks & Discharge as 1 ClockOLED_writeByte(0xDA,OLED_CMD);//--SET com pins hardware configurationOLED_writeByte(0x12,OLED_CMD);OLED_writeByte(0xDB,OLED_CMD);//--SET vcomhOLED_writeByte(0x40,OLED_CMD);//SET VCOM Deselect LevelOLED_writeByte(0x20,OLED_CMD);//-SET Page Addressing Mode (0x00/0x01/0x02)OLED_writeByte(0x02,OLED_CMD);//OLED_writeByte(0x8D,OLED_CMD);//--SET Charge Pump enable/disableOLED_writeByte(0x14,OLED_CMD);//--SET(0x10) disableOLED_writeByte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)OLED_writeByte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7) OLED_writeByte(0xAF,OLED_CMD);//--turn on oled panelOLED_writeByte(0xAF,OLED_CMD); /*display ON*/ OLED_clear();	
}  /**********************************************************************************************************
* 函数名    :   OLED_setPos
* 功能描述  :   
* 参数说明  :  X: 列坐标  0----131Y: 页坐标  0----7列总共由8个位组成
* 返回值说明:   none
* 修改记录  : 
* 其他      :  **********************************************************************************************************/
void OLED_setPos(unsigned char x, unsigned char y) //34 - 0010 0010
{ x += 2;//SSH1106 要加这个y &= 7;//保证页的地址不超OLED_writeByte(0xb0+y,OLED_CMD); //设置页地址OLED_writeByte(((x&0xf0)>>4)|0x10, OLED_CMD);//设置显示位置—列高地址//0010 0010 & 1111 0000//0010 0000 >> 4 -- 0000 0010OLED_writeByte((x&0x0f),OLED_CMD); //0010 0010 & 0000 1111 -- 0000 0010
}  /**********************************************************************************************************
* 函数名    :   Show_Signal_Word
* 功能描述  :   显示单个字符
* 参数说明  :   u8 page, u8 col, u8 ch
* 返回值说明:   none
* 修改记录  : 
* 其他      :
**********************************************************************************************************/
void Show_Signal_Word(u8 page, u8 col, u8 ch)//'a' -- 97
{u8 i;u8 n;u8 index = ch - ' ';//得到当前这个字符在ASCII_816的位置,97 - 32 = 65if(col > 120){col = 0;page += 2;}OLED_setPos(col,page);//由于一页只有八行,一个字符有16行,所以需要换两页for(i = 0; i < 2; i++){//由于一个字符只有8列for(n=0; n< 8; n++)//到第130列{OLED_writeByte(ASCII_816[index*16 + i*8 + n],OLED_DATA);   //息屏整个屏幕是黑色的!和没点亮一样!!!	}OLED_setPos(col,page+1);}
}/**********************************************************************************************************
* 函数名    :   Show_String
* 功能描述  :   显示字符串
* 参数说明  :   u8 page, u8 col, u8 *str, u8 num
* 返回值说明:   none
* 修改记录  : 
* 其他      :
**********************************************************************************************************/
void Show_String(u8 page, u8 col, u8 *str, u8 num)//"sakdjfhjk",0
{u8 i;OLED_setPos(col,page);for(i = 0; i < num; i++){Show_Signal_Word(page,col,*str);str++;col += 8;//为了保证下一个字符和前一个字符不重合,根据字体大小所以+8if(col > 120){col = 0;page += 2;}OLED_setPos(col,page);}
}/**********************************************************************************************************
* 函数名    :   Show_Chinese
* 功能描述  :   显示字符串
* 参数说明  :   u8 page, u8 col, u8 *str, u8 num
* 返回值说明:   none
* 修改记录  : 
* 其他      :
**********************************************************************************************************/
void Show_Chinese( u8 page, u8 col, u8 *str, u8 num)
{u8 i,j;u8 n;if(col > 112){col = 0;page += 2;}OLED_setPos(col,page);for(j = 0; j < num; j++){for(i = 0; i < 2; i++){//由于一个字符只有8列for(n=0; n < 16; n++)//代表有16列的数据{OLED_writeByte(str[j *32 + i*16 + n],OLED_DATA);   //息屏整个屏幕是黑色的!和没点亮一样!!!	}OLED_setPos(col,page+1);}col += 16;if(col > 112){col = 0;page += 2;}OLED_setPos(col,page);}
}/**********************************************************************************************************
* 函数名    :   Show_Pic
* 功能描述  :   显示图片
* 参数说明  :   u8 page, u8 col, u8 *pic
* 返回值说明:   none
* 修改记录  : 
* 其他      :
**********************************************************************************************************/
void Show_Pic(u8 page, u8 col, u8 *pic)
{u8 weight = pic[2];u8 height = pic[4];u8 i,j;pic += 6;//先偏移掉数据头的数据if(weight > 129 - col){col = 0;page += 2;}OLED_setPos(col,page);for(i = 0; i < height / 8; i++){for(j = 0;j < weight; j++){OLED_writeByte(*pic,OLED_DATA);pic++;}page += 1;OLED_setPos(col,page);}}

STM32之SPI总线-CSDN博客

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

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

相关文章

SAP PI/PO 运行ESR报错:无法验证证书,将不执行该应用程序

java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: OCSP 运行ESR报错 解决方案&#xff1a; 1. 打开控制面板&#xff0c;找到JAVA 这个时候就可以正常打开ESR了

如何在CentOS 7 中搭建Python 3.0 环境

1、下载 通过https://www.python.org/ftp/python/下载Python安装包&#xff0c;这里下载Python-3.10.9.tgz&#xff1b; 2、上传 借助MobaXterm等工具将Python安装包上传至/opt目录&#xff1b; 3、解压 将JDK压缩文件解压至/opt目录&#xff1a;tar -xvf /opt/Python-3.1…

2024年第二届“华数杯”国际大学生数学建模竞赛 (A题 MCM)| 废水扩散分析 |数学建模完整代码+建模过程全解全析

当大家面临着复杂的数学建模问题时&#xff0c;你是否曾经感到茫然无措&#xff1f;作为2022年美国大学生数学建模比赛的O奖得主&#xff0c;我为大家提供了一套优秀的解题思路&#xff0c;让你轻松应对各种难题。 让我们来看看华数杯的A题&#xff01; 完整内容可以在文章末…

机器学习算法 - 马尔可夫链

马尔可夫链&#xff08;Markov Chain&#xff09;可以说是机器学习和人工智能的基石&#xff0c;在强化学习、自然语言处理、金融领域、天气预测、语音识别方面都有着极其广泛的应用 > The future is independent of the past given the present 未来独立于过去&#xff…

java SECS管理系统 将逐步推出 SECS 客户端(Passive) 管理系统 SECS快速开发平台 springboot secs开发平台

SECS管理系统 这是一套SECS客户端(Passive)&#xff0c;可以直接连接PLC设备,支持Modbus、三菱MC、欧姆龙Fine、OPC-UA、西门子S7设备等通信。 企业已经有了EAP软件&#xff0c;但是设备没有SECS通信功能&#xff0c;这时候可以使用这套框架&#xff0c;直接连接设备&#xff…

GEE使用

【GEE】Google Earth Engine&#xff08;GEE&#xff09;注册详细教程&无需教育邮箱-CSDN博客 数据下载代码 // Map the function over 3 months of data and take the median. // Load Landsat-8 surface reflectance data.var landsat8 ee.ImageCollection("LAND…

使用composer生成的DMG和PKG格式软件包有何区别

在使用Composer从包源构建软件包时候&#xff0c;有两种不同类型的包&#xff1a;PKG和DMG。你知道两者之间的区别吗? 以及如何选取吗&#xff1f; 每种格式都有各自的优势具体取决于软件包的预期用途以及用于部署软件包的工具。下面我们来了解一下PKG和DMG格式的区别和用途。…

Python密码本连接wifi

有时候我们会忘记自己的Wi-Fi密码&#xff0c;或者需要连接某个Wi-Fi网络以满足合法需求。本文将介绍如何使用Python编程语言编写一个简单的连接Wi-Fi的程序。 一、密码本准备 在进行wifi猜测时&#xff0c;其实就是列出各种可能的密码&#xff0c;用来尝试去访问目标wifi&…

Vue + JS + tauri 开发一个简单的PC端桌面应用程序

Vue JS tauri 开发一个简单的PC端桌面应用程序 文章目录 Vue JS tauri 开发一个简单的PC端桌面应用程序1. 环境准备1.1 安装 Microsoft Visual Studio C 生成工具[^2]1.2 安装 Rust[^3] 2. 使用 vite 打包工具创建一个 vue 应用2.1 使用Vite创建前端Vue项目2.2 更改Vite打包…

计算机毕业设计 基于Java的美食信息推荐系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

vi/vim 编辑器 --基本命令

1 vi/vim编辑器介绍 vi 是visual interface 的简称&#xff0c;是Linux中最经典的文本编辑器 vim是vi的加强版。兼容了vi的所有指令&#xff0c;不仅能编辑文本&#xff0c;而且具有shell程序编辑的功能&#xff0c;可以通过不同颜色的字体辨别语法的正确性&#xff0c;极大…

轻松识别Midjourney等AI生成图片,开源GenImage

AIGC时代&#xff0c;人人都可以使用Midjourney、Stable Diffusion等AI产品生成高质量图片&#xff0c;其逼真程度肉眼难以区分真假。这种虚假照片有时会对社会产生不良影响&#xff0c;例如&#xff0c;生成公众人物不雅图片用于散播谣言&#xff1b;合成虚假图片用于金融欺诈…

支持华为GaussDB数据库的免费开源ERP:人力资源管理解决方案概述

开源智造所推出的Odoo SuperPeople数字化解决方案将HR和薪资数据与财务、项目规划、预算和采购流程连接起来&#xff0c;消除了多套系统给企业带来的信息孤岛问题。 ——复星集团 人力资源中心 高经理 一种更具吸引力、更有洞察力的人员管理方式 什么是开源智造Odoo的人力资源…

【Vue】后端返回文件流,前端预览文件

let date;request({url: this.$route.query.url,method: get,responseType: blob,}).then(resp > {date respthis.path window.URL.createObjectURL(new Blob([resp], {type: "application/pdf"}))}).catch((e) > {//旧版本浏览器下的blob创建对象window.Blo…

中产医学产康AI智慧云发布会暨中产学院2024年度盛典圆满成功

【向光而行】中国医学产康AI智慧云服务平台发布会暨中产学院2024年度盛典 前言 开新局&#xff0c;迈新步&#xff0c;谋新篇&#xff0c;创新绩。中产医学产康AI智慧云服务平台发布会 暨中产学院2024年度盛典于2024年1月10日在郑州.涵唐酒店成功举办。本次年会以“【向光而行…

跟着cherno手搓游戏引擎【7】Input轮询

在引擎程序中任何时间&#xff0c;任何位置都能知道按键是否按下、鼠标的位置等等信息。 与事件系统的区别&#xff1a;事件系统是在按下时调用并传递按键状态&#xff1b;轮询是每时每刻都能获取按键状态 创建基类&#xff1a; YOTO/Input.h&#xff1a;名如其意 #pragma …

php反序列化之pop链构造(基于重庆橙子科技靶场)

常见魔术方法的触发 __construct() //创建类对象时调用 __destruct() //对象被销毁时触发 __call() //在对象中调用不可访问的方法时触发 __callStatic() //在静态方式中调用不可访问的方法时触发 __get() //调用类中不存在变量时触发&#xff08;找有连续箭头的…

wins安装paddle框架

一、安装 https://www.paddlepaddle.org.cn/install/quick?docurl/documentation/docs/zh/install/pip/windows-pip.html 装包&#xff08;python 的版本是否满足要求&#xff1a; 3.8/3.9/3.10/3.11/3.12&#xff0c; pip 版本为 20.2.2 或更高版本 &#xff09; CPU 版:…

用VSCode玩STM32的烧录工具 CooCox Cortex Flash Programmer

一、下载软件 经热心兄弟推荐的版本&#xff0c;不知道有没有版权&#xff0c;如有版权问题&#xff0c;请通知删除。 CSDN - 0积分下载&#xff1a;https://download.csdn.net/download/qq_49053936/88744187 二、生成bin文件 插件不同&#xff0c;方法有所不同&#xff0c;各…

编写RedisUtil来操作Redis

目录 ​编辑 Redis中文网 第一步&#xff1a;建springboot项目 第二步&#xff1a;导依赖 第三步&#xff1a;启动类 第四步&#xff1a;yml 第五步&#xff1a;Redis配置类 第六步&#xff1a;测试类 第七步&#xff1a;编写工具类 RedisUtil 第八步&#xff1a;编写…