资讯详情

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

简单的说下OLED

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

使用下面的代码stm32f基于标准库的103单片机

注:如果要更换不同型号的单片机,只需修改端口,与引用文件相同。我还在代码中标记了修改点

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(F16x16[adder]);

		adder += 1;
	}
}



 /** * @brief OLED_DrawBMP,显示BMP位图 * @param x0,y0 :起始点坐标(x0:0~127, y0:0~7); * x1,y1 : 起点对角线(结束点)的坐标(x1:1~128,y1:1~8) * @retval 无 */
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++]);
		}
	}
}

codetab.h

#ifndef __CODETAB_H
#define __CODETAB_H


/***************************16*16的点阵字体取模方式:共阴——列行式——逆向输出*********/
unsigned char F16x16[] =
{ 
        	
0x00,0x40,0x40,0x5F,0xF5,0x55,0x55,0x55,0x55,0x55,0xF5,0x5F,0x40,0x40,0x00,0x00,
0x09,0x09,0x85,0x45,0x2B,0x51,0x81,0x7D,0x01,0x11,0x2B,0x45,0x85,0x09,0x09,0x00,/*"暴",0*/
	
0x10,0xEC,0x27,0xE4,0x34,0xEC,0x00,0xFE,0x92,0x92,0xFE,0x92,0x92,0xFE,0x00,0x00,
0x40,0xCF,0x49,0x2F,0x29,0x2F,0x40,0x44,0x44,0x44,0x7F,0x44,0x44,0x44,0x40,0x00,/*"鲤",1*/
	
0x40,0x20,0xF0,0x28,0x24,0x27,0x24,0xE4,0x24,0x34,0x2C,0x20,0xE0,0x00,0x00,0x00,
0x40,0x40,0x4F,0x49,0x49,0x49,0x49,0x4F,0x49,0x49,0x49,0x49,0x4F,0x40,0x40,0x00,/*"鱼",2*/
};

/************************************6*8的点阵************************************/
const unsigned char F6x8[][6] =
{ 
        
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// sp
	0x00, 0x00, 0x00, 0x2f, 0x00, 0x00,// !
	0x00, 0x00, 0x07, 0x00, 0x07, 0x00,// "
	0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14,// #
	0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12,// $
	0x00, 0x62, 0x64, 0x08, 0x13, 0x23,
        标签: 二极管sp0402u7a3二极管

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台