/*
128*64点阵的OLED显示屏驱动文件,仅适用于SD1306驱动 模拟SPI通信方式显示屏
OLED屏测试程序-STM32
使用说明:
OLED电源使用3.3V。
----------------
G 电源地
3.3V 接3.3V电源
SCL PB6
SDA PB7
RST PB5
DC PD7
CS PD6
*/
#include "my_include.h"
#define OLED_USER_EA 1
//运行静态函数OLED_SpiWriteByte时是否先屏蔽中断,运行完毕后再打开
//如果定义 OLED_USER_EA 运行时就屏蔽中断,运行完毕后再打开
//一般如果我们的应用要使能EA 则就定义OLED_USER_EA
//否则就 //#define OLED_USER_EA 1
static void OLED_SimulateSpiConfiguration(void); //关于OLED的I2C初始化
static void OLED_SpiWriteByte(u8 dat); //向OLED寄存器地址写一个byte的数据
static void OLED_WriteCmd(u8 I2C_Command); //写命令
static void OLED_WriteDat(u8 I2C_Data); //写数据
///////////////////////////////////////////////////
//初始化OLED
void OLED_Init(void)
{
OLED_SimulateSpiConfiguration();
//从上电到下面开始初始化要有足够的时间,即等待RC复位完毕
OLED_WriteCmd(0xae);//--turn off oled panel
OLED_WriteCmd(0x00);//---set low column address
OLED_WriteCmd(0x10);//---set high column address
OLED_WriteCmd(0x40);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
OLED_WriteCmd(0x81);//--set contrast control register
OLED_WriteCmd(0xcf); // Set SEG Output Current Brightness
OLED_WriteCmd(0xa1);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
OLED_WriteCmd(0xc8);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
OLED_WriteCmd(0xa6);//--set normal display
OLED_WriteCmd(0xa8);//--set multiplex ratio(1 to 64)
OLED_WriteCmd(0x3f);//--1/64 duty
OLED_WriteCmd(0xd3);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
OLED_WriteCmd(0x00);//-not offset
OLED_WriteCmd(0xd5);//--set display clock divide ratio/oscillator frequency
OLED_WriteCmd(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec
OLED_WriteCmd(0xd9);//--set pre-charge period
OLED_WriteCmd(0xf1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
OLED_WriteCmd(0xda);//--set com pins hardware configuration
OLED_WriteCmd(0x12);
OLED_WriteCmd(0xdb);//--set vcomh
OLED_WriteCmd(0x40);//Set VCOM Deselect Level
OLED_WriteCmd(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)
OLED_WriteCmd(0x02);//
OLED_WriteCmd(0x8d);//--set Charge Pump enable/disable
OLED_WriteCmd(0x14);//--set(0x10) disable
OLED_WriteCmd(0xa4);// Disable Entire Display On (0xa4/0xa5)
OLED_WriteCmd(0xa6);// Disable Inverse Display On (0xa6/a7)
OLED_WriteCmd(0xaf);//--turn on oled panel
OLED_CLS(); //初始清屏
OLED_SetPos(0,0); //设置初始坐标(0,0)
}
//////////////////////////////////////////////////////////////////
//填充整个屏幕
//要填充的数据 fill_Data
void OLED_Fill(u8 fill_Data)//全屏填充
{
u8 m,n;
for(m=0;m<8;m++)
{
OLED_WriteCmd(0xb0+m); //page0-page1
OLED_WriteCmd(0x00); //low column start address
OLED_WriteCmd(0x10); //high column start address
for(n=0;n<128;n++)
{
OLED_WriteDat(fill_Data);
}
}
}
//////////////////////////////////////////////////////////////////
//清屏
void OLED_CLS(void)//清屏
{
OLED_Fill(0x00);
}
//////////////////////////////////////////////////////////////////
//全屏点亮
void OLED_BRIGHT(void)//全屏点亮
{
OLED_Fill(0xff);
}
//////////////////////////////////////////////////////////////////
//让OLED休眠 -- 休眠模式下,OLED功耗不到10uA
void OLED_OFF(void)
{
OLED_WriteCmd(0X8D); //设置电荷泵
OLED_WriteCmd(0X10); //关闭电荷泵
OLED_WriteCmd(0XAE); //OLED休眠
}
//////////////////////////////////////////////////////////////////
//将OLED从休眠中唤醒
void OLED_ON(void)
{
OLED_WriteCmd(0X8D); //设置电荷泵
OLED_WriteCmd(0X14); //开启电荷泵
OLED_WriteCmd(0XAF); //OLED唤醒
}
//////////////////////////////////////////////////////////////////
//显示codetab.h中的ASCII字符,有6*8和8*16可选择
//起始点坐标(x:0~127, y:0~7);
//ch[] :- 要显示的字符串;
//TextSize : 字符大小(1:6*8 ; 2:8*16)
//例:cocoguojia_oledShowStr(0,3,(unsigned char*)"Wildfire Tech",1); //测试6*8字符
//例:cocoguojia_oledShowStr(0,4,(unsigned char*)"Hello wildfire",2); //测试8*16字符
void OLED_ShowStr(u8 x, u8 y, u8 ch[], u8 TextSize)
{
u8 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++)
OLED_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++)
OLED_WriteDat(F8X16[c*16+i]);
OLED_SetPos(x,y+1);
for(i=0;i<8;i++)
OLED_WriteDat(F8X16[c*16+i+8]);
x += 8;
j++;
}
}break;
}
}
//////////////////////////////////////////////////////////////////
//显示codetab.h中的汉字,16*16点阵
//x,y: 起始点坐标(x:0~127, y:0~7);
//N:汉字在F16x16中的索引
//例:OLED_ShowCN(0,1,0);
void OLED_ShowCN(u8 x, u8 y, u8 N)
{
u8 wm=0;
unsigned int adder=32*N;
OLED_SetPos(x , y);
for(wm = 0;wm < 16;wm++)
{
OLED_WriteDat(F16x16[adder]);
adder += 1;
}
OLED_SetPos(x,y + 1);
for(wm = 0;wm < 16;wm++)
{
OLED_WriteDat(F16x16[adder]);
adder += 1;
}
}
//////////////////////////////////////////////////////////////////
//显示BMP位图
//x0,y0 :起始点坐标(x0:0~127, y0:0~7);
//x1,y1 : 起点对角线(结束点)的坐标(x1:1~128,y1:1~8)
//例: OLED_DrawBMP(0,0,128,8,(unsigned char *)BMP1);//测试BMP位图显示
void OLED_DrawBMP(u8 x0,u8 y0,u8 x1,u8 y1,u8 BMP[])
{
unsigned int j=0;
u8 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++)
{
OLED_WriteDat(BMP[j++]);
}
}
}
//////////////////////////////////////////////////////////////////
//设置光标位置
//(x,y)光标位置
void OLED_SetPos(u8 x, u8 y) //设置起始点坐标
{
OLED_WriteCmd(0xb0+y);
OLED_WriteCmd(((x&0xf0)>>4)|0x10);
OLED_WriteCmd((x&0x0f)|0x01);
}
//////////////////////////////////////////////////////////////////////////////////////////////
//静态函数
///////////////////////////////////////////////////////////
//函数名: OLED_SimulateSpiConfiguration
//功能: 关于OLED的模拟SPI初始化
static void OLED_SimulateSpiConfiguration(void)
{
OLED_CS_EN;
OLED_SCL_SET;
OLED_RST_EN;
OLED_DC_DAT;
delay_ms(200);
OLED_RST_NO;
}
//////////////////////////////////////////////////////////////////
//向OLED寄存器地址写一个byte的数据
//addr:寄存器地址
//data:要写入的数据
static void OLED_SpiWriteByte(u8 dat)
{
unsigned char i=8;
unsigned char j;
#ifdef OLED_USER_EA
EA=0;//////////////////////////////////
#endif
OLED_SCL_CLR;
j=(MAIN_Fosc/1000000);
while(j--)
{
;
}
while(i--)
{
if(dat&0x80)
{
OLED_SDA_SET;
}
else
{
OLED_SDA_CLR;
}
j=(MAIN_Fosc/1000000);
while(j--)
{
;
}
OLED_SCL_SET;
j=(MAIN_Fosc/1000000);
while(j--)
{
;
}
OLED_SCL_CLR;
dat<<=1;
}
#ifdef OLED_USER_EA
EA=1;//////////////////////////////////
#endif
}
///////////////////////////////////////////////////
//向OLED写入命令
//I2C_Command:命令代码
static void OLED_WriteCmd(u8 I2C_Command)//写命令
{
OLED_DC_COM;
OLED_SpiWriteByte(I2C_Command);
}
///////////////////////////////////////////////////
//向OLED写入数据
//I2C_Data:数据
static void OLED_WriteDat(u8 I2C_Data)//写数据
{
OLED_DC_DAT;
OLED_SpiWriteByte(I2C_Data);
}
///////////////////////////////////////////////////////////
//6x8点阵
u8 code 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, 0x