0.96寸4针OLED的使用与驱动模块

简单的说下OLED

OLED,即有机发光二极管。LCD 需要背光,而OLED不需要,因为它是自发光的。这样同样的显示OLED效果要来得好一些。OLED分辨率是128*64 供电电压可以是3-5V 支持8600和8080通讯协议,4针是使用IIC协议来控制通讯,关于IIC通讯我就不详细介绍,话不多说,我们直接上代码

下方代码是用stm32f103单片机基于标准库写的

注:如果你要更换到不同型号的单片机上,也只需要修改端口,和引用文件,其余都相同,修改点我在代码中也有标注

OLED_I2C.h

#ifndef __OLED_I2C_H
#define	__OLED_I2C_H

#include "stm32f10x.h"

#define OLED_ADDRESS	0x78 //通过调整0R电阻,屏可以0x78和0x7A两个地址 -- 默认0x78

#define I2C_Speed              400000

/*I2C接口    代码迁移修改点    */
#define OLED_I2C                          I2C1
#define OLED_I2C_CLK                      RCC_APB1Periph_I2C1
#define OLED_I2C_CLK_INIT				  RCC_APB1PeriphClockCmd

#define OLED_I2C_SCL_PIN                  GPIO_Pin_6                 
#define OLED_I2C_SCL_GPIO_PORT            GPIOB                       
#define OLED_I2C_SCL_GPIO_CLK             RCC_APB2Periph_GPIOB
#define OLED_I2C_SCL_SOURCE               GPIO_PinSource6
#define OLED_I2C_SCL_AF                   GPIO_AF_I2C1

#define OLED_I2C_SDA_PIN                  GPIO_Pin_7                  
#define OLED_I2C_SDA_GPIO_PORT            GPIOB                       
#define OLED_I2C_SDA_GPIO_CLK             RCC_APB2Periph_GPIOB
#define OLED_I2C_SDA_SOURCE               GPIO_PinSource7
#define OLED_I2C_SDA_AF                   GPIO_AF_I2C1


void I2C_Configuration(void);
void I2C_WriteByte(uint8_t addr,uint8_t data);
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[]);

#endif

OLED_I2C.c

/*
	* 功能列表:
	*	1. void I2C_Configuration(void) -- 配置CPU的硬件I2C
	* 2. void I2C_WriteByte(uint8_t addr,uint8_t data) -- 向寄存器地址写一个byte的数据
	* 3. void WriteCmd(unsigned char I2C_Command) -- 写命令
	* 4. void WriteDat(unsigned char I2C_Data) -- 写数据
	* 5. void OLED_Init(void) -- OLED屏初始化
	* 6. void OLED_SetPos(unsigned char x, unsigned char y) -- 设置起始点坐标
	* 7. void OLED_Fill(unsigned char fill_Data) -- 全屏填充
	* 8. void OLED_CLS(void) -- 清屏
	* 9. void OLED_ON(void) -- 唤醒
	* 10. void OLED_OFF(void) -- 睡眠
	* 11. void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize) -- 显示字符串(字体大小有6*8和8*16两种)
	* 12. void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N) -- 显示中文(中文需要先取模,然后放到codetab.h中)
	* 13. void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[]) -- BMP图片
	*
  */ 

#include "OLED_I2C.h" //OLED_IIC通讯h文件
#include "codetab.h" //字模h文件
#include "./systick/bsp_SysTick.h" //延时函数h文件

void I2C_Configuration(void) /*    代码迁移修改点   */
{
   
 //开启IIC和IIC端口配置
	I2C_InitTypeDef  I2C_InitStructure;
	GPIO_InitTypeDef  GPIO_InitStructure; 
	/*I2C1外设时钟使能 */
	OLED_I2C_CLK_INIT(OLED_I2C_CLK,ENABLE);	
	/*I2C1外设GPIO时钟使能 */
	RCC_APB2PeriphClockCmd(OLED_I2C_SCL_GPIO_CLK | OLED_I2C_SDA_GPIO_CLK,ENABLE);
	 /* I2C_SCL、I2C_SDA*/
  GPIO_InitStructure.GPIO_Pin = OLED_I2C_SCL_PIN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;	       // 开漏输出
  GPIO_Init(OLED_I2C_SCL_GPIO_PORT, &GPIO_InitStructure);
	
  GPIO_InitStructure.GPIO_Pin = OLED_I2C_SDA_PIN;
  GPIO_Init(OLED_I2C_SDA_GPIO_PORT, &GPIO_InitStructure);		
	/* I2C 配置 */
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;	
  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;	/* 高电平数据稳定,低电平数据变化 SCL 时钟线的占空比 */
  I2C_InitStructure.I2C_OwnAddress1 =OLED_ADDRESS;    //主机的I2C地址
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable ;	
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;	/* I2C的寻址模式 */
  I2C_InitStructure.I2C_ClockSpeed = I2C_Speed;	                            /* 通信速率 */
  
  I2C_Init(OLED_I2C, &I2C_InitStructure);	                                      /* I2C1 初始化 */
	I2C_Cmd(OLED_I2C, ENABLE);  	                                                /* 使能I2C1*/
	
}

void I2C_WriteByte(uint8_t addr,uint8_t data)
{
   
  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
	
	I2C_GenerateSTART(I2C1, ENABLE);//开启I2C1
	while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));/*EV5,主模式*/

	I2C_Send7bitAddress(I2C1, OLED_ADDRESS, I2C_Direction_Transmitter);//器件地址 -- 默认0x78
	while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

	I2C_SendData(I2C1, addr);//寄存器地址
	while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

	I2C_SendData(I2C1, data);//发送数据
	while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
	
	I2C_GenerateSTOP(I2C1, ENABLE);//关闭I2C1总线
}

void WriteCmd(unsigned char I2C_Command)//写命令
{
   
	I2C_WriteByte(0x00, I2C_Command);
}

void WriteDat(unsigned char I2C_Data)//写数据
{
   
	I2C_WriteByte(0x40, I2C_Data);
}

void OLED_Init(void)
{
   
    //这个延时函数就根据单片机自己构建一个,没准确时间要求,这里我就不提供库文件
	Delay_s(1);		// 1s,这里的延时很重要,上电后延时,没有错误的冗余设计,也就是等待oled工作稳定
	
	WriteCmd(0xAE); //关闭显示
	WriteCmd(0x20);	//设置内存地址模式	
	WriteCmd(0x10);	//00,列地址模式;01,行地址模式;10(默认),页地址模式;11,无效
	WriteCmd(0xb0);	//设置页地址,其中低三位的值对应GRAM地址:B0-B7
	WriteCmd(0xc8);	//设置COM输出扫描方向
	WriteCmd(0x00); //---设置低列地址
	WriteCmd(0x10); //---设置高列地址
	WriteCmd(0x40); //--设置起始行地址
	WriteCmd(0x81); //--设置对比度控制寄存器
	WriteCmd(0xff); //亮度调节 0x00~0xff
	WriteCmd(0xa1); //--将段重新映射0设置为127
	WriteCmd(0xa6); //--设置正常显示
	WriteCmd(0xa8); //--设置多路复用比率(1到64)
	WriteCmd(0x3F); //
	WriteCmd(0xa4); //0xa4,输出跟随RAM内容;0xa5,输出忽略RAM内容
	WriteCmd(0xd3); //-设置显示偏移
	WriteCmd(0x00); //-不抵消
	WriteCmd(0xd5); //--设置显示时钟分频比/振荡器频率
	WriteCmd(0xf0); //--设定分割比率
	WriteCmd(0xd9); //--设定预充电时间
	WriteCmd(0x22); //
	WriteCmd(0xda); //--设置com引脚硬件配置
	WriteCmd(0x12);
	WriteCmd(0xdb); //--set vcomh
	WriteCmd(0x20); //0x20,0.77xVcc
	WriteCmd(0x8d); //--设置DC-DC启用
	WriteCmd(0x14); //
	WriteCmd(0xaf); //--开启显示
}

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) //让OLED休眠
{
   
	WriteCmd(0X8D);  //设置电荷泵
	WriteCmd(0X10);  //关闭电荷泵
	WriteCmd(0XAE);  //OLED休眠
}


 /**
  * @brief  OLED_ShowStr,显示codetab.h中的ASCII字符,有6*8和8*16可选择
  * @param  x,y : 起始点坐标(x:0~127, y:0~7);
	*					ch[] :- 要显示的字符串; 
	*					Size : 字符大小(1:6*8 ; 2:8*16)
	* @retval 无
  */
void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char Size)
{
   
	unsigned char c = 0,i = 0,j = 0;
	switch(Size)
	{
   
		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;
	}
}

 /**
  * @brief  OLED_ShowCN,显示codetab.h中的汉字,16*16点阵
  * @param  x,y: 起始点坐标(x:0~127, y:0~7); 
	*					N:汉字在codetab.h中的索引
	* @retval 无
  */
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</
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值