當前位置:首頁 > 芯聞號 > 充電吧
[導讀]STM32 —— 中景園0.96寸OLED? ? OLED,即有機發(fā)光二極管(? Organic Light Emitting Diode )。 OLED 由于同時具備自發(fā)光,不需背光源、對比度高、厚

STM32 —— 中景園0.96寸OLED


? ? OLED,即有機發(fā)光二極管(? Organic Light Emitting Diode )。 OLED 由于同時具備自發(fā)光,不需背光源、對比度高、厚度薄、視角廣、反應速度快、可用于撓曲性面板、使用溫度范圍廣、構造及制程較簡單等優(yōu)異之特性,被認為是下一代的平面顯示器新興應用技術。

????LCD 都需要背光,而 OLED 不需要,因為它是自發(fā)光的。這樣同樣的顯示 OLED 效果要來得好一些。以目前的技術,OLED 的尺寸還難以大型化,但是分辨率確可以做到很高。

? ? 分辨率:128*64

? ? 驅動方式:SPI/IIC,以下程序是IO口模擬IIC通信。

#ifndef?__OLED_H
#define?__OLED_H

typedef???signed???????????char?int8_t;
typedef???signed?short?????int?int16_t;
typedef???signed???????????int?int32_t;
typedef???signed???????__int64?int64_t;


/*?exact-width?unsigned?integer?types?*/
typedef?unsigned???????????char?uint8_t;
typedef?unsigned?short?????int?uint16_t;
typedef?unsigned???????????int?uint32_t;
typedef?unsigned???????????int?size_t;
typedef?unsigned???????__int64?uint64_t;

#define?OLED_SCL_PORT????????GPIOA
#define?OLED_SCL_PIN?????????GPIO_Pin_5
#define?OLED_SCL_CONFIG()????GPIOConfig(OLED_SCL_PORT,?OLED_SCL_PIN,?GPIO_Mode_Out_PP)
#define?OLED_SCL_LOW()???????GPIO_ResetBits(OLED_SCL_PORT,?OLED_SCL_PIN)?//?SCL
#define?OLED_SCL_HIGH()??????GPIO_SetBits(OLED_SCL_PORT,?OLED_SCL_PIN)

#define?OLED_SDA_PORT????????GPIOA
#define?OLED_SDA_PIN?????????GPIO_Pin_7
#define?OLED_SDA_CONFIG()????GPIOConfig(OLED_SDA_PORT,?OLED_SDA_PIN,?GPIO_Mode_Out_PP)
#define?OLED_SDA_LOW()???????GPIO_ResetBits(OLED_SDA_PORT,?OLED_SDA_PIN)?//?SDA
#define?OLED_SDA_HIGH()??????GPIO_SetBits(OLED_SDA_PORT,?OLED_SDA_PIN)

#define?OLED_RES_PORT????????GPIOA
#define?OLED_RES_PIN?????????GPIO_Pin_6
#define?OLED_RES_CONFIG()????GPIOConfig(OLED_RES_PORT,?OLED_RES_PIN,?GPIO_Mode_Out_PP)
#define?OLED_RES_LOW()???????GPIO_ResetBits(OLED_RES_PORT,?OLED_RES_PIN)?//?RES
#define?OLED_RES_HIGH()??????GPIO_SetBits(OLED_RES_PORT,?OLED_RES_PIN)

#define?OLED_MODE?0
#define?SIZE?8
#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	????						??
		?????
#define?OLED_CMD??0	//寫命令
#define?OLED_DATA?1	//寫數(shù)據(jù)

void?IICStart(void);
void?IICStop(void);
void?I2CWriteCmd(uint8_t?cmd);
void?I2CWriteData(uint8_t?data);
void?I2CWriteByte(uint8_t?byte);
void?I2CWaitAck(void);

//OLED控制用函數(shù)
void?OLEDWriteByte(uint8_t?dat,uint8_t?cmd);??
void?OLEDDisplayOn(void);
void?OLEDDisplayOff(void);	???							???		????
void?OLEDInit(void);
void?OLEDClear(void);
void?OLEDDrawPoint(uint8_t?x,uint8_t?y,uint8_t?t);
void?OLEDFill(uint8_t?x1,uint8_t?y1,uint8_t?x2,uint8_t?y2,uint8_t?dot);
void?OLEDShowChar(uint8_t?x,uint8_t?y,uint8_t?chr,uint8_t?Char_Size);
void?OLEDShowNum(uint8_t?x,uint8_t?y,uint32_t?num,uint8_t?len,uint8_t?size);
void?OLEDShowString(uint8_t?x,uint8_t?y,?uint8_t?*p,uint8_t?Char_Size);	?
void?OLEDSetPos(uint8_t?x,?uint8_t?y);
void?OLEDShowCHinese(uint8_t?x,uint8_t?y,uint8_t?no);
void?OLEDDrawBMP(uint8_t?x0,?uint8_t?y0,uint8_t?x1,uint8_t?y1,uint8_t?BMP[]);

#endif
#include?"oled.h"
#include?"stdlib.h"
#include?"oledfont.h"
#include?"target.h"

void?IICStart(void)
{
??OLED_SCL_HIGH()?;
??OLED_SDA_HIGH();
??OLED_SDA_LOW();
??OLED_SCL_LOW();
}

void?IICStop(void)
{
??OLED_SCL_HIGH()?;
??OLED_SDA_LOW();
??OLED_SDA_HIGH();

}

void?I2CWaitAck(void)
{
??OLED_SCL_HIGH()?;
??OLED_SCL_LOW();
}

void?I2CWriteByte(uint8_t?byte)
{
??uint8_t?i;
??uint8_t?m,?data;

??data?=?byte;
??OLED_SCL_LOW();
??for(i?=?0;?i?<?8;?i++)
??{
????m?=?data;
????m?=?m?&?0x80;
????if(m?==?0x80)
????{
??????OLED_SDA_HIGH();
????}
????else
????{
??????OLED_SDA_LOW();
????}
????data?=?data?<<?1;
????OLED_SCL_HIGH();
????OLED_SCL_LOW();
??}
}

void?I2CWriteCmd(uint8_t?cmd)
{
??IICStart();
??I2CWriteByte(0x78);??????//Slave?address,SA0=0
??I2CWaitAck();
??I2CWriteByte(0x00);??????//write?command
??I2CWaitAck();
??I2CWriteByte(cmd);
??I2CWaitAck();
??IICStop();
}

void?I2CWriteData(uint8_t?data)
{
??IICStart();
??I2CWriteByte(0x78);??????//D/C#=0;?R/W#=0
??I2CWaitAck();
??I2CWriteByte(0x40);??????//write?data
??I2CWaitAck();
??I2CWriteByte(data);
??I2CWaitAck();
??IICStop();
}

void?OLEDWriteByte(uint8_t?dat,?uint8_t?cmd)
{
??if(cmd)
??{
????I2CWriteData(dat);
??}
??else
??{
????I2CWriteCmd(dat);
??}
}

//坐標設置

void?OLEDSetPos(uint8_t?x,?uint8_t?y)
{
??OLEDWriteByte(0xb0?+?y,?OLED_CMD);
??OLEDWriteByte(((x?&?0xf0)?>>?4)?|?0x10,?OLED_CMD);
??OLEDWriteByte((x?&?0x0f),?OLED_CMD);
}
//開啟OLED顯示
void?OLEDDisplayOn(void)
{
??OLEDWriteByte(0X8D,?OLED_CMD);?//SET?DCDC命令
??OLEDWriteByte(0X14,?OLED_CMD);?//DCDC?ON
??OLEDWriteByte(0XAF,?OLED_CMD);?//DISPLAY?ON
}
//關閉OLED顯示
void?OLEDDisplayOff(void)
{
??OLEDWriteByte(0X8D,?OLED_CMD);?//SET?DCDC命令
??OLEDWriteByte(0X10,?OLED_CMD);?//DCDC?OFF
??OLEDWriteByte(0XAE,?OLED_CMD);?//DISPLAY?OFF
}
//清屏函數(shù),清完屏,整個屏幕是黑色的!和沒點亮一樣!!!
void?OLEDClear(void)
{
??uint8_t?i,?n;

??for(i?=?0;?i?<?8;?i++)
??{
????OLEDWriteByte?(0xb0?+?i,?OLED_CMD);?//設置頁地址(0~7)
????OLEDWriteByte?(0x00,?OLED_CMD);?????//設置顯示位置—列低地址
????OLEDWriteByte?(0x10,?OLED_CMD);?????//設置顯示位置—列高地址
????for(n?=?0;?n?<?128;?n++)
????{
??????OLEDWriteByte(0,?OLED_DATA);
????}
??}?//更新顯示
}
void?OLED_On(void)
{
??uint8_t?i,?n;

??for(i?=?0;?i?<?8;?i++)
??{
????OLEDWriteByte?(0xb0?+?i,?OLED_CMD);?//設置頁地址(0~7)
????OLEDWriteByte?(0x00,?OLED_CMD);?????//設置顯示位置—列低地址
????OLEDWriteByte?(0x10,?OLED_CMD);?????//設置顯示位置—列高地址
????for(n?=?0;?n?<?128;?n++)
????{
??????OLEDWriteByte(1,?OLED_DATA);
????}
??}?//更新顯示
}
//在指定位置顯示一個字符,包括部分字符
//x:0~127
//y:0~63
//mode:0,反白顯示;1,正常顯示
//size:選擇字體?16/12
void?OLEDShowChar(uint8_t?x,?uint8_t?y,?uint8_t?chr,?uint8_t?Char_Size)
{
??uint8_t?c?=?0,?i?=?0;
??c?=?chr?-?'?';?//得到偏移后的值
??if(x?>?Max_Column?-?1)
??{
????x?=?0;
????y?=?y?+?2;
??}
??if(Char_Size?==?16)
??{
????OLEDSetPos(x,?y);
????for(i?=?0;?i?<?8;?i++)
????{
??????OLEDWriteByte(F8X16[c?*?16?+?i],?OLED_DATA);
????}
????OLEDSetPos(x,?y?+?1);
????for(i?=?0;?i?<?8;?i++)
????{
??????OLEDWriteByte(F8X16[c?*?16?+?i?+?8],?OLED_DATA);
????}
??}
??else
??{
????OLEDSetPos(x,?y);
????for(i?=?0;?i?<?6;?i++)
????{
??????OLEDWriteByte(F6x8[c][i],?OLED_DATA);
????}

??}
}

//m^n函數(shù)
uint32_t?oled_pow(uint8_t?m,?uint8_t?n)
{
??uint32_t?result?=?1;
??while(n--)
??{
????result?*=?m;
??}
??return?result;
}
//顯示2個數(shù)字
//x,y?:起點坐標
//len?:數(shù)字的位數(shù)
//size:字體大小
//mode:模式?0,填充模式;1,疊加模式
//num:數(shù)值(0~4294967295);
void?OLEDShowNum(uint8_t?x,?uint8_t?y,?uint32_t?num,?uint8_t?len,?uint8_t?size2)
{
??uint8_t?t,?temp;
??uint8_t?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)
??????{
????????OLEDShowChar(x?+?(size2?/?2)*t,?y,?'?',?size2);
????????continue;
??????}
??????else
??????{
????????enshow?=?1;
??????}

????}
????OLEDShowChar(x?+?(size2?/?2)*t,?y,?temp?+?'0',?size2);
??}
}
//顯示一個字符號串
void?OLEDShowString(uint8_t?x,?uint8_t?y,?uint8_t?*chr,?uint8_t?Char_Size)
{
??uint8_t?j?=?0;

??while?(chr[j]?!=?'