STM32-HAL库07-软件SPI驱动0.96寸OLED

STM32-HAL库07-软件SPI驱动0.96寸OLED

一、所用材料:

STM32VGT6自制控制板
STM32CUBEMX(HAL库软件)
MDK5

二、所学内容:

通过HAL库配置四个GPIO输出口,对其进行软件模拟SPI发送规则,进而驱动OLED进行数字或字母显示,暂不设计中文文字显示。

三、CUBEMX配置:

第一步:选取四个模拟GPIO输出引脚

在这里插入图片描述

第二步:配置SYS

在这里插入图片描述

第三步:配置RCC

在这里插入图片描述

第四步:配置时钟

在这里插入图片描述

第五步:文件配置

在这里插入图片描述

四、MDK5程序编写:

1.配置OLED.h文件

#ifndef __OLED_H
#define __OLED_H//========移植的时候,根据所选芯片引入相应的头文件==========,在main.h里面查看
#include "stm32f4xx_hal.h"
#include "gpio.h"//OLED模式设置
//0:4线串行模式
//1:并行8080模式
#define OLED_MODE 0
#define SIZE 16
#define XLevelL		0x00
#define XLevelH		0x10
#define Max_Column	128
#define Max_Row		64
#define	Brightness	0xFF 
#define X_WIDTH 	128
#define Y_WIDTH 	64	  //========移植的时候,根据引脚分配进行修改==========//使用4线串行接口时使用 //RES
#define OLED_RST_Clr() HAL_GPIO_WritePin(OLED_RST_GPIO_Port, OLED_RST_Pin, GPIO_PIN_RESET)	//RES RES => 接RES(RST)引脚
#define OLED_RST_Set() HAL_GPIO_WritePin(OLED_RST_GPIO_Port, OLED_RST_Pin, GPIO_PIN_SET)//DC
#define OLED_DC_Clr() HAL_GPIO_WritePin(OLED_DC_GPIO_Port, OLED_DC_Pin, GPIO_PIN_RESET)
#define OLED_DC_Set() HAL_GPIO_WritePin(OLED_DC_GPIO_Port, OLED_DC_Pin, GPIO_PIN_SET)//SCLK,D0
#define OLED_SCLK_Clr() HAL_GPIO_WritePin(OLED_SCL_GPIO_Port, OLED_SCL_Pin, GPIO_PIN_RESET)
#define OLED_SCLK_Set() HAL_GPIO_WritePin(OLED_SCL_GPIO_Port, OLED_SCL_Pin, GPIO_PIN_SET)//SDIN,D1
#define OLED_SDIN_Clr() HAL_GPIO_WritePin(OLED_SDA_GPIO_Port, OLED_SDA_Pin, GPIO_PIN_RESET)
#define OLED_SDIN_Set() HAL_GPIO_WritePin(OLED_SDA_GPIO_Port, OLED_SDA_Pin, GPIO_PIN_SET)#define OLED_CMD  0	//写命令
#define OLED_DATA 1	//写数据//OLED控制用函数
void OLED_WR_Byte(unsigned char dat,unsigned char cmd);	    
void OLED_Display_On(void);
void OLED_Display_Off(void);	   							   		    
void OLED_Init(void);
void OLED_Clear(void);
void OLED_DrawPoint(unsigned char x,unsigned char y,unsigned char t);
void OLED_Fill(unsigned char x1,unsigned char y1,unsigned char x2,unsigned char y2,unsigned char dot);
void OLED_ShowChar(unsigned char x,unsigned char y,unsigned char chr);
void OLED_ShowNum(unsigned char x,unsigned char y,unsigned long num,unsigned char len,unsigned char size);
void OLED_Showint (unsigned char x,unsigned char y,unsigned long num);
void OLED_ShowString(unsigned char x,unsigned char y, unsigned char *p);	 
void OLED_Set_Pos(unsigned char x, unsigned char y);
void OLED_ShowCHinese(unsigned char x,unsigned char y,unsigned char no);
void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]);
#endif

2.配置OLED.c文件


#include <stdio.h>
#include <stdlib.h>
#include "OLED.h"
#include "OLED_Font.h"//0.96寸OLED 屏幕简称SSD1106
//OLED的显存
//存放格式如下.
//[0]0 1 2 3 ... 127	
//[1]0 1 2 3 ... 127	
//[2]0 1 2 3 ... 127	
//[3]0 1 2 3 ... 127	
//[4]0 1 2 3 ... 127	
//[5]0 1 2 3 ... 127	
//[6]0 1 2 3 ... 127	
//[7]0 1 2 3 ... 127 			   #if OLED_MODE==1
//向SSD1106写入一个字节。
//dat:要写入的数据/命令
//cmd:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(unsigned char dat,unsigned char cmd)
{DATAOUT(dat);	    if(cmd)OLED_DC_Set();else OLED_DC_Clr();		   OLED_WR_Clr();	 OLED_WR_Set();OLED_DC_Set();	 
} 	    	    
#else
//向SSD1106写入一个字节。
//dat:要写入的数据/命令
//cmd:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(unsigned char dat,unsigned char cmd)
{	unsigned char i;			  if(cmd)OLED_DC_Set();else OLED_DC_Clr();		  for(i=0;i<8;i++){			  OLED_SCLK_Clr();if(dat&0x80)OLED_SDIN_Set();else OLED_SDIN_Clr();OLED_SCLK_Set();dat<<=1;   }				 		  OLED_DC_Set();   	  
} 
#endifvoid OLED_Set_Pos(unsigned char x, unsigned char y) 
{ OLED_WR_Byte(0xb0+y,OLED_CMD);OLED_WR_Byte(((x&0xf0)>>4)|0x10,OLED_CMD);OLED_WR_Byte((x&0x0f)|0x01,OLED_CMD); 
}   	  
//开启OLED显示    
void OLED_Display_On(void)
{OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令OLED_WR_Byte(0X14,OLED_CMD);  //DCDC ONOLED_WR_Byte(0XAF,OLED_CMD);  //DISPLAY ON
}
//关闭OLED显示     
void OLED_Display_Off(void)
{OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令OLED_WR_Byte(0X10,OLED_CMD);  //DCDC OFFOLED_WR_Byte(0XAE,OLED_CMD);  //DISPLAY OFF
}		   			 
//清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!	  
void OLED_Clear(void)  
{  unsigned char i,n;		    for(i=0;i<8;i++)  {  OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)OLED_WR_Byte (0x02,OLED_CMD);      //设置显示位置—列低地址OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   for(n=0;n<128;n++)OLED_WR_Byte(0,OLED_DATA); } //更新显示
}//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白显示;1,正常显示				 
//size:选择字体 16/12 
void OLED_ShowChar(unsigned char x,unsigned char y,unsigned char chr)
{      	unsigned char c=0,i=0;	c=chr-' ';//得到偏移后的值			if(x>Max_Column-1){x=0;y=y+2;}if(SIZE ==16){OLED_Set_Pos(x,y);	for(i=0;i<8;i++)OLED_WR_Byte(F8X16[c*16+i],OLED_DATA);OLED_Set_Pos(x,y+1);for(i=0;i<8;i++)OLED_WR_Byte(F8X16[c*16+i+8],OLED_DATA);}else {	OLED_Set_Pos(x,y+1);for(i=0;i<6;i++)OLED_WR_Byte(F6x8[c][i],OLED_DATA);}
}
//m^n函数
unsigned long oled_pow(unsigned char m,unsigned char n)
{unsigned long result=1;	 while(n--)result*=m;    return result;
}				  
//显示2个数字
//x,y :起点坐标	 
//len :数字的位数
//size:字体大小
//mode:模式	0,填充模式;1,叠加模式
//num:数值(0~4294967295);	 		  
void OLED_ShowNum(unsigned char x,unsigned char y,unsigned long num,unsigned char len,unsigned char size)
{         	unsigned char t,temp;unsigned char enshow=0;						   for(t=0;t<len;t++){temp=(num/oled_pow(10,len-t-1))%10;if(enshow==0&&t<(len-1)){if(temp==0){OLED_ShowChar(x+(size/2)*t,y,'0');continue;}else enshow=1; }OLED_ShowChar(x+(size/2)*t,y,temp+'0'); }
} 
void OLED_Showint (unsigned char x,unsigned char y,unsigned long num)
{unsigned long output;output = num/10000;OLED_ShowChar(x+8*0,y,output+'0');num = num % 10000;output = num/1000;OLED_ShowChar(x+8*1,y,output+'0');num = num % 1000;	output = num/100;OLED_ShowChar(x+8*2,y,output+'0');num = num % 100;output = num/10;OLED_ShowChar(x+8*3,y,output+'0');num = num % 10;	output = num;OLED_ShowChar(x+8*4,y,output+'0');
}
/*** @brief   显示一个字符号串* @param   x : uint8_t 起点列坐标 * @param   y : uint8_t 起点行坐标 * @param   chr : uint8_t *字符串指针* @retval  无*/
void OLED_ShowString(unsigned char x,unsigned char y,unsigned char *chr)
{unsigned char j=0;while (chr[j]!='\0'){		OLED_ShowChar(x,y,chr[j]);x+=8;if(x>120){x=0;y+=2;}j++;}
}
//显示汉字
void OLED_ShowCHinese(unsigned char x,unsigned char y,unsigned char no)
{      			    unsigned char t,adder=0;OLED_Set_Pos(x,y);	for(t=0;t<16;t++){OLED_WR_Byte(Hzk[2*no][t],OLED_DATA);adder+=1;}	OLED_Set_Pos(x,y+1);	for(t=0;t<16;t++){	OLED_WR_Byte(Hzk[2*no+1][t],OLED_DATA);adder+=1;}					
}
/***********功能描述:显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7*****************/
void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[])
{ 	unsigned int j=0;unsigned char x,y;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++){      OLED_WR_Byte(BMP[j++],OLED_DATA);	    	}}
} //初始化SH1106					    
void OLED_Init(void)
{OLED_RST_Set();HAL_Delay(100);OLED_RST_Clr();HAL_Delay(100);OLED_RST_Set();OLED_WR_Byte(0xAE,OLED_CMD);//--turn off oled panelOLED_WR_Byte(0x02,OLED_CMD);//---set low column addressOLED_WR_Byte(0x10,OLED_CMD);//---set high column addressOLED_WR_Byte(0x40,OLED_CMD);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)OLED_WR_Byte(0x81,OLED_CMD);//--set contrast control registerOLED_WR_Byte(0xCF,OLED_CMD); // Set SEG Output Current BrightnessOLED_WR_Byte(0xA1,OLED_CMD);//--Set SEG/Column Mapping     0xa0左右反置 0xa1正常OLED_WR_Byte(0xC8,OLED_CMD);//Set COM/Row Scan Direction   0xc0上下反置 0xc8正常OLED_WR_Byte(0xA6,OLED_CMD);//--set normal displayOLED_WR_Byte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)OLED_WR_Byte(0x3f,OLED_CMD);//--1/64 dutyOLED_WR_Byte(0xD3,OLED_CMD);//-set display offset	Shift Mapping RAM Counter (0x00~0x3F)OLED_WR_Byte(0x00,OLED_CMD);//-not offsetOLED_WR_Byte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequencyOLED_WR_Byte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/SecOLED_WR_Byte(0xD9,OLED_CMD);//--set pre-charge periodOLED_WR_Byte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 ClockOLED_WR_Byte(0xDA,OLED_CMD);//--set com pins hardware configurationOLED_WR_Byte(0x12,OLED_CMD);OLED_WR_Byte(0xDB,OLED_CMD);//--set vcomhOLED_WR_Byte(0x40,OLED_CMD);//Set VCOM Deselect LevelOLED_WR_Byte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)OLED_WR_Byte(0x02,OLED_CMD);//OLED_WR_Byte(0x8D,OLED_CMD);//--set Charge Pump enable/disableOLED_WR_Byte(0x14,OLED_CMD);//--set(0x10) disableOLED_WR_Byte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)OLED_WR_Byte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7) OLED_WR_Byte(0xAF,OLED_CMD);//--turn on oled panelOLED_WR_Byte(0xAF,OLED_CMD); /*display ON*/ OLED_Clear();OLED_Set_Pos(0,0); 	
}  

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

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

相关文章

Eclipse 安装串口终端工具

Eclipse已集成串口终端显示&#xff0c;只需要我们自己下载安装即可使用。使用SSH连接也差不多。 查看eclipse版本信息 help->About Eclipse 查看version&#xff0c;我的是4.7.3a&#xff0c;记住代号&#xff0c;我的是“Oxygen”,下面有用。 安装eclipse自带的“Termin…

小白备战大厂算法笔试(六)——堆

文章目录 堆常用操作堆的实现存储与表示访问堆顶元素元素入堆元素出堆 常见应用建堆操作自上而下构建自下而上构建 TOP-K问题遍历选择排序堆 堆 堆是一种满足特定条件的完全二叉树&#xff0c;主要可分为下图所示的两种类型。 大顶堆&#xff1a;任意节点的值 ≥ 其子节点的值…

智能合约安全分析,假充值攻击如何突破交易所的防御?

智能合约安全分析&#xff0c;假充值攻击如何突破交易所的防御&#xff1f; 引言 假充值攻击&#xff0c;是指攻击者通过利用交易所在处理充值过程中的漏洞或系统错误&#xff0c;发送伪造的交易信息到交易所钱包地址&#xff0c;这些伪造的交易信息被交易所误认为是真实的充值…

年轻人为何热衷于副业?工作不饱和,这是对年轻人的侮辱

昨天在知乎上看到一个问题&#xff1a;为什么现在的年轻人都开始忙着搞副业&#xff0c;工作不饱和还是赚钱太少&#xff1f; 着实没忍住&#xff0c;所以&#xff0c;发表了一下自己的看法。 「都」开始忙着搞副业&#xff0c;这里的「都」&#xff0c;有准确数据吗&#xff1…

自动驾驶——估计预瞄轨迹YawRate

1.Introduction 在ADAS控制系统中&#xff0c;通常根据预瞄距离x去估计横向距离y&#xff0c;有如下关系&#xff1a; y a0 a1 x a2 * x^2 a3 * x^3 &#xff0c;那么现在有个需求&#xff0c;希望根据上述x和y的关系&#xff0c;去估计规划预瞄轨迹yawRate 2.How to es…

从软件工程师角度聊聊 Kubernetes

作为软件工程师&#xff0c;我们应该熟悉 K8s&#xff0c;尽管它有点像 DevOps&#xff0c;但它能让我们更好地了解幕后发生的事情&#xff0c;让我们与部署工作更密切相关&#xff0c;更有责任感。本文将从软件工程师的角度探讨 Kubernetes (K8s)&#xff0c;我们将介绍其动机…

LLM - 批量加载 dataset 并合并

目录 一.引言 二.Dataset 生成 1.数据样式 2.批量加载 ◆ 主函数调用 ◆ 基础变量定义 ◆ 多数据集加载 3.数据集合并 ◆ Concat ◆ interleave ◆ stopping_strategy ◆ interleave_probs 三.总结 一.引言 LLM 模型基于 transformer 进行训练&#xff0c;需要先…

SpringMvc增删改查

SpringMvc增删改查 一、前期准备二、逆向生成增删改查2.2.aspect切面层2.3.Mybatis generator逆向生成2.4.根据生成代码编写Biz层与实现类 三、controller层代码编写四、前台代码与分页代码五、案例测试 一、前期准备 1.2.导入pom.xml依赖 <?xml version"1.0" …

智慧工地可视化解决方案-智慧工地源码

智慧工地是指运用信息化手段&#xff0c;围绕施工过程管理&#xff0c;建立互联协同、智能生产、科学管理的施工项目信息化生态圈&#xff0c;并将此数据在虚拟现实环境下与物联网采集到的工程信息进行数据挖掘分析&#xff0c;提供过程趋势预测及专家预案&#xff0c;实现工程…

【MySQL】表的增删改查

目录 MySQL表的增删查改 Create 单行数据全列插入 多行数据指定列插入 插入否则更新 替换数据 Retrieve SELECT 列 全列查询 指定列查询 查询字段为表达式 为查询结果指定别名 结果去重 WHERE 条件 查询英语不及格的同学及其英语成绩 查询语文成绩在80到90分的…

如何在 Ubuntu 上安装 Nagios?

Nagios 的功能 Nagios 的一些关键功能包括&#xff1a; 主机和服务监控&#xff1a; Nagios 允许您使用提供实时状态数据的插件来监控主机&#xff08;可以是物理机或虚拟机&#xff09;以及 HTTP、SSH 和 SMTP 等服务。此功能使您能够全面了解整个基础设施的运行状况和可用性…

9.11作业

实现一个对数组求和的函数&#xff0c;数组通过实参传递给函数 sum0 arr(11 22 33 44 55) Sum() {for i in ${arr[*]}do$((sumi))donereturn $sum } Sum ${arr[*]} var$? echo $var写一个函数&#xff0c;输出当前用户的uid和gid&#xff0c;并使用变量接收结果 Sum() {aid -…