STM32F103C8T6 (HAL库)——0.96寸OLED屏幕显示

1、软件准备

(1)Keil5

(2)CubeMX

2、硬件准备

(1)STM32F103C8T6最小系统板

STM32F103C8T6

(2)oled屏幕模块

在这里插入图片描述

3、关于OLED显示屏

(1)‌介绍

	尺寸与分辨率‌:0.96寸,分辨率为128x64像素,提供清晰显示。
 	技术特点‌:采用OLED技术,无需背光,通过每个像素自发光实现显示。支持SPI和I2C通信,便于与微控制器等设备连接。
	驱动与控制‌:配备SSD1306驱动芯片,控制所有像素的显示。通过简单的引脚配置即可实现与微控制器的通信和数据传输。

(2)接线

	GND  电源地
	VCC  电源正(3~5.5V)
	SCL OLED 的 D0 脚,在 IIC 通信中为时钟管脚,本篇文章中接PB6
	SDA OLED 的 D1 脚,在 IIC 通信中为数据管脚,本篇文章中接PB7

4、CubeMX配置

(1)芯片选择

输入主控的型号后创建我们的工程

(2)RCC、SYS、时钟树的配置

在RCC中选择外部晶振
SYS设置
.时钟设置为自己的芯片对应的频率(c8t6是72Hz)

(3)I2C配置

配置最基础的I2C即可
I2c配置

(4)生成工程

文件的路径不可以有中文
文件的路径不可以有中文
第七步可省略
在这里插入图片描述

5、导入OLED驱动文件

(1)新建存放外设驱动的文件夹

在此文件里面放入我们需要用的外设程序库
在这里插入图片描述
0.96OLED文件夹里面是我们提前写好了的oled驱动函数
在这里插入图片描述
不仅要在工程文件里面添加,还需要在keil工程中添加一遍(文件名一致)
建立存放外设驱动的文件
把oled外设函数放入其中
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
添加完后,还需要将我们oled的路径选好
在这里插入图片描述

编译完成没有错误就代表我们添加的很成功
添加成功

(2)oled.c

#include "oled.h"
#include "ASCll.H"
#include "main.h"
void WriteCmd(unsigned char I2C_Command)//写命令
 {
	HAL_I2C_Mem_Write(&hi2c1,OLED0561_ADD,COM,I2C_MEMADD_SIZE_8BIT,&I2C_Command,1,100);
 }
		
void WriteDat(unsigned char I2C_Data)//写数据
 {
		HAL_I2C_Mem_Write(&hi2c1,OLED0561_ADD,DAT,I2C_MEMADD_SIZE_8BIT,&I2C_Data,1,100);
  }
	void OLED_Init(void)
{
	HAL_Delay(100); //这里的延时很重要
	
	WriteCmd(0xAE); //display off
	WriteCmd(0x20);	//Set Memory Addressing Mode	
	WriteCmd(0x10);	//00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,Invalid
	WriteCmd(0xb0);	//Set Page Start Address for Page Addressing Mode,0-7
	WriteCmd(0xc8);	//Set COM Output Scan Direction
	WriteCmd(0x00); //---set low column address
	WriteCmd(0x10); //---set high column address
	WriteCmd(0x40); //--set start line address
	WriteCmd(0x81); //--set contrast control register
	WriteCmd(0xff); //亮度调节 0x00~0xff
	WriteCmd(0xa1); //--set segment re-map 0 to 127
	WriteCmd(0xa6); //--set normal display
	WriteCmd(0xa8); //--set multiplex ratio(1 to 64)
	WriteCmd(0x3F); //
	WriteCmd(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
	WriteCmd(0xd3); //-set display offset
	WriteCmd(0x00); //-not offset
	WriteCmd(0xd5); //--set display clock divide ratio/oscillator frequency
	WriteCmd(0xf0); //--set divide ratio
	WriteCmd(0xd9); //--set pre-charge period
	WriteCmd(0x22); //
	WriteCmd(0xda); //--set com pins hardware configuration
	WriteCmd(0x12);
	WriteCmd(0xdb); //--set vcomh
	WriteCmd(0x20); //0x20,0.77xVcc
	WriteCmd(0x8d); //--set DC-DC enable
	WriteCmd(0x14); //
	WriteCmd(0xaf); //--turn on oled panel
}

void OLED_SetPos(unsigned char x, unsigned char y) //设置起始点坐标
{ 
	WriteCmd(0xb0+y);
	WriteCmd(((x&0xf0)>>4)|0x10);
	WriteCmd((x&0x0f)|0x01);
}
void OLED_Fill(unsigned char fill_Data)//全屏填充
{
	unsigned char m,n;
	for(m=0;m<8;m++)
	{
		WriteCmd(0xb0+m);		//page0-page1
		WriteCmd(0x00);		//low column start address
		WriteCmd(0x10);		//high column start address
		for(n=0;n<128;n++)
			{
				WriteDat(fill_Data);
			}
	}
}
void OLED_CLS(void)//清屏
{
	OLED_Fill(0x00);
}
void OLED_ON(void)
{
	WriteCmd(0X8D);  //设置电荷泵
	WriteCmd(0X14);  //开启电荷泵
	WriteCmd(0XAF);  //OLED唤醒
}
void OLED_OFF(void)
{
	WriteCmd(0X8D);  //设置电荷泵
	WriteCmd(0X10);  //关闭电荷泵
	WriteCmd(0XAE);  //OLED休眠
}
// Parameters     : x,y -- 起始点坐标(x:0~127, y:0~7); ch[] -- 要显示的字符串; TextSize -- 字符大小(1:6*8 ; 2:8*16)
// Description    : 显示codetab.h中的ASCII字符,有6*8和8*16可选择
void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize)
{
	unsigned char c = 0,i = 0,j = 0;
	switch(TextSize)
	{
		case 1:
		{
			while(ch[j] != '\0')
			{
				c = ch[j] - 32;
				if(x > 126)
				{
					x = 0;
					y++;
				}
				OLED_SetPos(x,y);
				for(i=0;i<6;i++)
					WriteDat(F6x8[c][i]);
				x += 6;
				j++;
			}
		}break;
		case 2:
		{
			while(ch[j] != '\0')
			{
				c = ch[j] - 32;
				if(x > 120)
				{
					x = 0;
					y++;
				}
				OLED_SetPos(x,y);
				for(i=0;i<8;i++)
					WriteDat(F8X16[c*16+i]);
				OLED_SetPos(x,y+1);
				for(i=0;i<8;i++)
					WriteDat(F8X16[c*16+i+8]);
				x += 8;
				j++;
			}
		}break;
	}
}
// Parameters     : x,y -- 起始点坐标(x:0~127, y:0~7); N:汉字在.h中的索引
// Description    : 显示ASCII_8x16.h中的汉字,16*16点阵
void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
{
	unsigned char wm=0;
	unsigned int  adder=32*N;
	OLED_SetPos(x , y);
	for(wm = 0;wm < 16;wm++)
	{
		WriteDat(F16x16[adder]);
		adder += 1;
	}
	OLED_SetPos(x,y + 1);
	for(wm = 0;wm < 16;wm++)
	{
		WriteDat(F16x16[adder]);
		adder += 1;
	}
}
// 要先把中文字符串“共阴——列行式——逆向输出”取字模后存入ascll.h相应的位置(连续存入)
//传入参数分别为:x:起始横坐标  
//				y:纵坐标(填入0-7)  
//				begin:填入的中文字符串的第一个字在我们ascll.c字库里面的序号  
//              num:我们要填写几个字
// 比如要填“测试”,取完字模存入后这两个字在字库中序号为0,1,横坐标0,纵坐标第二行,就填:x:0,y:2,begin:0,num:2
void OLED_ShowCN_STR(u8 x , u8 y , u8 begin , u8 num)
{
	u8 i;
	for(i=0;i<num;i++){OLED_ShowCN(i*16+x,y,i+begin);}    //OLED显示标题
}
// Parameters     : x0,y0 -- 起始点坐标(x0:0~127, y0:0~7); x1,y1 -- 起点对角线(结束点)的坐标(x1:1~128,y1:1~8)
// Description    : 显示BMP位图
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_SetPos(x0,y);
    for(x=x0;x<x1;x++)
		{
			WriteDat(BMP[j++]);
		}
	}
}
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size)
{      	
	unsigned char c=0,i=0;	
		c=chr-' ';//得到偏移后的值			
		if(x>128-1){x=0;y=y+2;}
		if(Char_Size ==16)
			{
			OLED_SetPos(x,y);	
			for(i=0;i<8;i++)
			WriteDat(F8X16[c*16+i]);
			OLED_SetPos(x,y+1);
			for(i=0;i<8;i++)
			WriteDat(F8X16[c*16+i+8]);
			}
			else {	
				OLED_SetPos(x,y);
				for(i=0;i<6;i++)
				WriteDat(F6x8[c][i]);
				
			}
}
u32 oled_pow(u8 m,u8 n)
{
	u32 result=1;	 
	while(n--)result*=m;    
	return result;
}	
//显示2个数字
//x,y :起点坐标	 
//len :数字的位数
//size:字体大小
//mode:模式	0,填充模式;1,叠加模式
//num:数值(0~4294967295);	 		  
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size2)
{         	
	u8 t,temp;
	u8 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+(size2/2)*t,y,' ',size2);
				continue;
			}else enshow=1; 
		}
	 	OLED_ShowChar(x+(size2/2)*t,y,temp+'0',size2); 
	}
} 

(3)oled.h

#ifndef __OLED_H
#define __OLED_H	 
#include "i2c.h"
 #define u8 uint8_t
 #define u32 uint32_t
//    一些使用例子
//	OLED_ShowStr(0, 0, "hello world", 2);//显示字符串
//	OLED_ShowStr(0, 2, "hello world", 1);//显示字符串
//	OLED_ShowCN_STR(0, 4 , 0 , 8);
//	sprintf(num_temp_buffer,"show num:%0.2f",num);
//	OLED_ShowStr(0, 6, num_temp_buffer, 2);//显示字符串
//	OLED_CLS();
//	OLED_DrawBMP(0,0,128,7,BMP2);
#define OLED0561_ADD	0x78  // OLED的I2C地址(禁止修改)
#define COM				0x00  // OLED 指令(禁止修改)
#define DAT 			0x40  // OLED 数据(禁止修改)

void WriteCmd(unsigned char I2C_Command);//写命令
void WriteDat(unsigned char I2C_Data);//写数据
void OLED_Init(void);//初始化
void OLED_SetPos(unsigned char x, unsigned char y);
void OLED_Fill(unsigned char fill_Data);//全屏填充
void OLED_CLS(void);
void OLED_ON(void);
void OLED_OFF(void);
void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize);//显示字串
void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N);//显示汉字
void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[]);//显示图片(取模:阴,列行,逆,输出索引,精简)
void OLED_ShowCN_STR(u8 x , u8 y , u8 begin , u8 num);  //自己写的输出中文字符串
void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 Char_Size);
u32 oled_pow(u8 m,u8 n);
void OLED_ShowNum(u8 x,u8 y,u32 num,u8 len,u8 size2);//size2(16|12)
#endif

展示现象

在这里插入图片描述

### 关于OLED HAL的驱动信息与使用方法 #### OLED HAL 简介 OLED HAL (Hardware Abstraction Layer) 提供了一种抽象层来简化硬件操作,使得开发者能够更方便地控制OLED显示屏。该通常包含了初始化屏幕、显示字符、图形绘制等功能。 对于STM32微控制器而言,HAL提供了针对不同外设的支持,其中包括IIC接口用于连接0.96OLED屏[^1]。为了实现这一目的,需要配置特定GPIO引脚作为IIC通信线路的一部分;例如,PB12至PB15被指定为GPIO输出以支持其他可能的功能需求[^2]。 #### 移植过程概述 当准备移植现有的OLED底层驱动程序时,应按照如下方式处理: - **复制必要的源文件**:将四个主要的驱动文件放置到项目的根目录下,并确保`oled.c`成为编译目标之一。同时,在主应用程序入口处通过`#include "oled.h"`语句引入相应的头文件定义。 - **解决特殊挑战**:如果遇到像`printf()`这样的函数带有可变数量参数的情况,则需查阅有关C99标准下的va_list机制文档来进行适当调整[^3]。 #### 示例代码展示 下面给出一段简单的示例代码片段,展示了如何利用上述提到的方法完成基本的文字打印任务: ```c #include "stm32f1xx_hal.h" #include "oled.h" int main(void){ /* 初始化系统 */ HAL_Init(); /* 初始化OLED并清屏 */ OLEDDISPLAY_init(); OLEDDISPLAY_clear(); while(1){ char str[] = "Hello, World!"; // 显示字符串 OLEDDISPLAY_showString(str); HAL_Delay(1000); // 延迟一秒 // 清除屏幕以便更新新内容 OLEDDISPLAY_clear(); } } ``` 此段代码实现了每隔一秒钟刷新一次屏幕上所呈现的信息的效果。 #### 获取资源链接 想要获取完整的OLED HAL及其配套资料,可以通过访问提供的GitCode仓地址下载整个项目包,其中不仅有详细的说明文档还有丰富的例子可供参考。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

匠芯单片机设计定制

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值