[導讀]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]?!=?'