STM32 —— 中景園0.96寸OLED
[導(dǎo)讀]STM32 —— 中景園0.96寸OLED? ? OLED,即有機(jī)發(fā)光二極管(? Organic Light Emitting Diode )。 OLED 由于同時(shí)具備自發(fā)光,不需背光源、對(duì)比度高、厚
STM32 —— 中景園0.96寸OLED
? ? OLED,即有機(jī)發(fā)光二極管(? Organic Light Emitting Diode )。 OLED 由于同時(shí)具備自發(fā)光,不需背光源、對(duì)比度高、厚度薄、視角廣、反應(yīng)速度快、可用于撓曲性面板、使用溫度范圍廣、構(gòu)造及制程較簡(jiǎn)單等優(yōu)異之特性,被認(rèn)為是下一代的平面顯示器新興應(yīng)用技術(shù)。
????LCD 都需要背光,而 OLED 不需要,因?yàn)樗亲园l(fā)光的。這樣同樣的顯示 OLED 效果要來(lái)得好一些。以目前的技術(shù),OLED 的尺寸還難以大型化,但是分辨率確可以做到很高。
? ? 分辨率:128*64
? ? 驅(qū)動(dòng)方式: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);
??}
}
//坐標(biāo)設(shè)置
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);
}
//開(kāi)啟OLED顯示
void?OLEDDisplayOn(void)
{
??OLEDWriteByte(0X8D,?OLED_CMD);?//SET?DCDC命令
??OLEDWriteByte(0X14,?OLED_CMD);?//DCDC?ON
??OLEDWriteByte(0XAF,?OLED_CMD);?//DISPLAY?ON
}
//關(guān)閉OLED顯示
void?OLEDDisplayOff(void)
{
??OLEDWriteByte(0X8D,?OLED_CMD);?//SET?DCDC命令
??OLEDWriteByte(0X10,?OLED_CMD);?//DCDC?OFF
??OLEDWriteByte(0XAE,?OLED_CMD);?//DISPLAY?OFF
}
//清屏函數(shù),清完屏,整個(gè)屏幕是黑色的!和沒(méi)點(diǎn)亮一樣!!!
void?OLEDClear(void)
{
??uint8_t?i,?n;
??for(i?=?0;?i?<?8;?i++)
??{
????OLEDWriteByte?(0xb0?+?i,?OLED_CMD);?//設(shè)置頁(yè)地址(0~7)
????OLEDWriteByte?(0x00,?OLED_CMD);?????//設(shè)置顯示位置—列低地址
????OLEDWriteByte?(0x10,?OLED_CMD);?????//設(shè)置顯示位置—列高地址
????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);?//設(shè)置頁(yè)地址(0~7)
????OLEDWriteByte?(0x00,?OLED_CMD);?????//設(shè)置顯示位置—列低地址
????OLEDWriteByte?(0x10,?OLED_CMD);?????//設(shè)置顯示位置—列高地址
????for(n?=?0;?n?<?128;?n++)
????{
??????OLEDWriteByte(1,?OLED_DATA);
????}
??}?//更新顯示
}
//在指定位置顯示一個(gè)字符,包括部分字符
//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個(gè)數(shù)字
//x,y?:起點(diǎn)坐標(biāo)
//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);
??}
}
//顯示一個(gè)字符號(hào)串
void?OLEDShowString(uint8_t?x,?uint8_t?y,?uint8_t?*chr,?uint8_t?Char_Size)
{
??uint8_t?j?=?0;
??while?(chr[j]?!=?'
