AitendoさんのOLEDをPSoCで制御しましたよ
※今日のブログ大変長いのでご注意を…。
6月30日までお得なaitendoさんの0.95インチOLEDを買ってみました。
実際に手にしてみると、「かなり小さい」というのが正直な感想です。
「OLEDとキャリーボードの2点セット」
http://www.aitendo.co.jp/product/2099
で動かすとこんな感じ
"Welcome to PSoC & DPCM Player"と書いたつもりです。
SPI制御で、3.3V単一電源で駆動できます。(OLEDの下部のフレキ基板にDC-DC昇圧回路がすでに載っています)
PSoCでの制御を記述していますが、他のCPUでも少しの改良で動くはずです。(SPIハードの駆動シーケンスなどを書き換え)
OLEDの駆動はaitendoさんのHPにあるプログラム*1、フォントデータはAN2356を参考にしております。
それって、ただのパクr……(まぁまぁ。
- 3.3V電源以外にOLEDを駆動するのに必要なピン
- MOSI : CPU -> OLED へのデータ通信用
- CLK : クロック
- CS : チップセレクト(Active Low)
- DC :データ/コマンド切り替えピン
- RES :リセット(Active Low)
(MISO端子は必要ありません)
今回上記2点のMOSI,CLKのみをハードウェアSPIで制御しました。
例えばCS端子にLEDライブラリから
OLED_CS というラベルを作り、Active Lowに設定すると、main関数から
OLED_CS_On();
と記述すれば、CS端子がLowにアサートされ、
OLED_CS_Off();
と記述すれば、CS端子がHighにデアサートされます。(Active Highに設定すればその逆になります)
今回はCS,RES端子をActive Low、DC端子をActive Highに設定しています。
PSoC以外のCPUをご使用になる方はご注意ください。
- ソースコード。aitendoさんのソースコードを参考にしてるので、コメントアウトなどが随所ありますがご容赦ください。
- oled_portconfig.h :(変数・関数の宣言)
#ifndef _OLED_PORTCONFIG_H #define _OLED_PORTCONFIG_H //======================IOPortConfig========================= //OLED_RES:Reset pin,low level valid (ACTIVE LOW:Port_2_1) //OLED_CS:Chip selection,low level valid (ACTIVE LOW:Port_2_5) //OLED_DC:Data reg /command reg 0:command 1:data (Port_1_7) //========================================================= #define Dis_X_MAX 96-1 // Max X axial direction in screen #define Dis_Y_MAX 64-1 // Max Y axial direction in screen extern unsigned char X_Witch; //character's width extern unsigned char Y_Witch; //character's height //extern unsigned char Font_Wrod; //how many byte this character's //extern unsigned char __f lash *Char_TAB; //word stock's pointer extern unsigned int Char_Color; //character's color void OLED_RegWrite(unsigned char Command); void OLED_DataWrite(unsigned char Data); void OLED_DataWrite_to(unsigned int Dat); void PortInit(void); void TimeDelay(int Time); void OLED_Init(void); void Full_OLED_Screen(unsigned int Dot); void Draw_Dot(unsigned char x,unsigned char y,unsigned int Color); void ChangeFontColor(unsigned int color); void PutChar(unsigned char x,unsigned char y,unsigned char a); #endif
#include <m8c.h> // part specific constants and macros #include "PSoCAPI.h" // PSoC API definitions for all User Modules //#include "main.h" #include "oled_portconfig.h" #include "small_font.h" unsigned char X_Witch; //character's width unsigned char Y_Witch; //character's height //unsigned char Font_Wrod; //how many byte this character's //unsigned char __f lash *Char_TAB; //word stock's pointer unsigned int Char_Color; //character's color //============================OLED_Driver================ // Illustration: driver // Function:: writer oled command register,intinial oled driver IC etc. // Parameter: Command // Return: Non // Reference: Other book or IC DataSheet // Note: Base your MCU and port conf iger // More: Can refer e.g. //===============write oled command register==================== void OLED_RegWrite(unsigned char Command) { OLED_CS_Off(); OLED_DC_Off(); OLED_CS_On(); SPIM_OLED_SendTxData(Command); while(!(SPIM_OLED_bReadStatus() & SPIM_OLED_SPIM_TX_BUFFER_EMPTY)); OLED_CS_Off(); } //=============================OLED_Driver=============== // Illustration: driver // Function: writer oled data register,intinial oled driver IC etc. // Parameter: Data // Return: Non // Reference: Other book or IC DataSheet // Note: Base your MCU and port conf iger // More: Can refer e.g. //================write oled data register======================= void OLED_DataWrite(unsigned char Data) { OLED_CS_Off(); OLED_DC_On(); OLED_CS_On(); SPIM_OLED_SendTxData(Data); while(!(SPIM_OLED_bReadStatus() & SPIM_OLED_SPIM_TX_BUFFER_EMPTY)); OLED_CS_Off(); } //=============power function================================= // Illustration: Function // Function: writer a point in oled,point color can select yourself // Parameter: Dat // Return: Non // Reference: Other book or IC DataSheet // Note: Base your MCU and port conf iger // More: Can refer e.g. //==============wr ite oled register============================= void OLED_DataWrite_to(unsigned int Dat) { OLED_DataWrite((unsigned char)((Dat >> 8)& 0x00ff)); OLED_DataWrite((unsigned char)(Dat & 0x00ff)); } //=============power function================================= // Illustration: Function // Function: MCU port initial,like port direction,pull-up resistor,input or output etc. // Parameter: Non // Return: Non // Reference: Other book or IC DataSheet // Note: Base your MCU and port conf iger // More: Can refer e.g. //========================================================= void PortInit(void) { OLED_CS_Start(); OLED_DC_Start(); OLED_RES_Start(); SPIM_OLED_Start(SPIM_OLED_SPIM_MODE_0 | SPIM_OLED_SPIM_MSB_FIRST); } //=============power function================================= // Illustration: Function // Function: Delay function // Parameter: Time // Return: Non // Reference: Other book or IC DataSheet // Note: Base your MCU and port conf iger // More: Can refer e.g. //========================================================= void TimeDelay(int Time) { int i; while(Time > 0) { for(i = 0;i < 800;i++) { asm("nop"); } Time --; } } void OLED_Init(void) { PortInit(); OLED_RES_On(); TimeDelay(80); OLED_RES_Off(); TimeDelay(20); OLED_RegWrite(0xae); //OLED display OFF //Row Address OLED_RegWrite(0x75); /* Set Row Address */ OLED_RegWrite(0x00); /* Start = 0 */ OLED_RegWrite(0x3f); /* End = 63 */ OLED_RegWrite(0x15); /* Set Column Address */ OLED_RegWrite(0x00); /* Start = 0 */ OLED_RegWrite(0x5F); /* End = 96 */ //Contrast OLED_RegWrite(0xa0); //Set remap & data format 0111 0000 OLED_RegWrite(0x74); OLED_RegWrite(0xa1); //set display star row RAM OLED_RegWrite(0x00); OLED_RegWrite(0xa2); //set dispaly offset OLED_RegWrite(0x00); OLED_RegWrite(0xa4); //Set Display Mode OLED_RegWrite(0xa8); //Set Multiplex Ratio OLED_RegWrite(0x3f); OLED_RegWrite(0xad); //Set Master Configuration OLED_RegWrite(0x8f); //(External VCC Supply Selected) OLED_RegWrite(0xB0); //Set Power Saving Mode OLED_RegWrite(0x1a); OLED_RegWrite(0xB1); //Set Phase 1 & 2 Period Adjustment OLED_RegWrite(0x74); OLED_RegWrite(0xb3); //Set Display Clock Divide Ratio / Oscillator Frequency OLED_RegWrite(0xd0); OLED_RegWrite(0x8A); //Set Second Pre-charge Speed of Color A OLED_RegWrite(0x81); OLED_RegWrite(0x8B); //Set Second Pre-charge Speed of Color B OLED_RegWrite(0x82); OLED_RegWrite(0x8C); //Set Second Pre-charge Speed of Color C OLED_RegWrite(0x83); OLED_RegWrite(0xBB); //Set Pre-charge Level OLED_RegWrite(0x3e); OLED_RegWrite(0xBE); //Set VCOMH OLED_RegWrite(0x3e); OLED_RegWrite(0x87); //Set Master Current Control OLED_RegWrite(0x0f ); OLED_RegWrite(0x81); //Set Contrast Control for Color “A” OLED_RegWrite(0x80); OLED_RegWrite(0x82); //Set Contrast Control for Color “B” OLED_RegWrite(0x80); OLED_RegWrite(0x83); //Set Contrast Control for Color “C” OLED_RegWrite(0x80); OLED_RegWrite(0xaf); //display ON } //=============power function================================= // Illustration: Function // Function: Fill all oled screen,all of color,e.g.:Dot=0x0000h,black screen // Dot=0x0018h,red screen // Parameter: Dot // Return: Non // Reference: Other book or IC DataSheet // Note: Base your MCU and port configer // More: Can refer e.g. //========================================================= void Full_OLED_Screen(unsigned int Dot) { unsigned char i,j; for(i=0;i<64;i++) { for(j=0;j<96;j++) { //Draw_Dot(j,i,Dot); OLED_DataWrite_to(Dot); } } } //=============power function================================= // Illustration: Function // Function: Write a dot in screen // Parameter: x,y,Color // Return: Non // Reference: Other book or IC DataSheet // Note: Base your MCU and port conf iger // More: Can refer e.g. //========================================================= void Draw_Dot(unsigned char x,unsigned char y,unsigned int Color) { OLED_RegWrite(0x15); OLED_RegWrite(x); OLED_RegWrite(x); OLED_RegWrite(0x75); OLED_RegWrite(y); OLED_RegWrite(y); OLED_DataWrite_to(Color); OLED_DataWrite_to(Color); } void ChangeFontColor(unsigned int color) { Char_Color = color; } //=============power function================================= // Illustration: Function // Function: Input a normal character // Parameter: X:X coordinate,Y:Y coordinate,a:display a character from word stock's offset // Return: Non // Reference: Other book or IC DataSheet // Note: Base your MCU and port conf iger // More: Can refer e.g. //========================================================= void PutChar(unsigned char x,unsigned char y,unsigned char a) { int i,j; // unsigned char __f lash *p_data; unsigned char Temp=0; unsigned char Index=0; X_Witch = 5; Y_Witch = 8; //Char_Color = 0xffff; j = 0; i = 0; if(a < 32)a=32; for(i=0; i<X_Witch; i++) { Temp = FontLookup[a-32][i]; for(j=Y_Witch;j!=0;j--){ if((Temp & 0x80)==0x80){ Draw_Dot(x+i,y+j,Char_Color); }else{ Draw_Dot(x+i,y+j,0); } Temp = Temp << 1; } } }
-
- small_font.h :(5 x 7サイズのフォントデータ:AN2356からそのまま流用)
//-------------------------------------------------------------------------------------------------- // Character generator // This table defines the standard ASCII characters in a 5x7 dot format. //-------------------------------------------------------------------------------------------------- static const char FontLookup [][5] = { { 0x00, 0x00, 0x00, 0x00, 0x00 }, // sp { 0x00, 0x00, 0x2f, 0x00, 0x00 }, // ! { 0x00, 0x07, 0x00, 0x07, 0x00 }, // " { 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // # { 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // $ { 0xc4, 0xc8, 0x10, 0x26, 0x46 }, // % { 0x36, 0x49, 0x55, 0x22, 0x50 }, // & { 0x00, 0x05, 0x03, 0x00, 0x00 }, // ' { 0x00, 0x1c, 0x22, 0x41, 0x00 }, // ( { 0x00, 0x41, 0x22, 0x1c, 0x00 }, // ) { 0x14, 0x08, 0x3E, 0x08, 0x14 }, // * { 0x08, 0x08, 0x3E, 0x08, 0x08 }, // + { 0x00, 0x00, 0x50, 0x30, 0x00 }, // , { 0x10, 0x10, 0x10, 0x10, 0x10 }, // - { 0x00, 0x60, 0x60, 0x00, 0x00 }, // . { 0x20, 0x10, 0x08, 0x04, 0x02 }, // / { 0x3E, 0x51, 0x49, 0x45, 0x3E }, // 0 { 0x00, 0x42, 0x7F, 0x40, 0x00 }, // 1 { 0x42, 0x61, 0x51, 0x49, 0x46 }, // 2 { 0x21, 0x41, 0x45, 0x4B, 0x31 }, // 3 { 0x18, 0x14, 0x12, 0x7F, 0x10 }, // 4 { 0x27, 0x45, 0x45, 0x45, 0x39 }, // 5 { 0x3C, 0x4A, 0x49, 0x49, 0x30 }, // 6 { 0x01, 0x71, 0x09, 0x05, 0x03 }, // 7 { 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8 { 0x06, 0x49, 0x49, 0x29, 0x1E }, // 9 { 0x00, 0x36, 0x36, 0x00, 0x00 }, // : { 0x00, 0x56, 0x36, 0x00, 0x00 }, // ; { 0x08, 0x14, 0x22, 0x41, 0x00 }, // < { 0x14, 0x14, 0x14, 0x14, 0x14 }, // = { 0x00, 0x41, 0x22, 0x14, 0x08 }, // > { 0x02, 0x01, 0x51, 0x09, 0x06 }, // ? { 0x32, 0x49, 0x59, 0x51, 0x3E }, // @ { 0x7E, 0x11, 0x11, 0x11, 0x7E }, // A { 0x7F, 0x49, 0x49, 0x49, 0x36 }, // B { 0x3E, 0x41, 0x41, 0x41, 0x22 }, // C { 0x7F, 0x41, 0x41, 0x22, 0x1C }, // D { 0x7F, 0x49, 0x49, 0x49, 0x41 }, // E { 0x7F, 0x09, 0x09, 0x09, 0x01 }, // F { 0x3E, 0x41, 0x49, 0x49, 0x7A }, // G { 0x7F, 0x08, 0x08, 0x08, 0x7F }, // H { 0x00, 0x41, 0x7F, 0x41, 0x00 }, // I { 0x20, 0x40, 0x41, 0x3F, 0x01 }, // J { 0x7F, 0x08, 0x14, 0x22, 0x41 }, // K { 0x7F, 0x40, 0x40, 0x40, 0x40 }, // L { 0x7F, 0x02, 0x0C, 0x02, 0x7F }, // M { 0x7F, 0x04, 0x08, 0x10, 0x7F }, // N { 0x3E, 0x41, 0x41, 0x41, 0x3E }, // O { 0x7F, 0x09, 0x09, 0x09, 0x06 }, // P { 0x3E, 0x41, 0x51, 0x21, 0x5E }, // Q { 0x7F, 0x09, 0x19, 0x29, 0x46 }, // R { 0x46, 0x49, 0x49, 0x49, 0x31 }, // S { 0x01, 0x01, 0x7F, 0x01, 0x01 }, // T { 0x3F, 0x40, 0x40, 0x40, 0x3F }, // U { 0x1F, 0x20, 0x40, 0x20, 0x1F }, // V { 0x3F, 0x40, 0x38, 0x40, 0x3F }, // W { 0x63, 0x14, 0x08, 0x14, 0x63 }, // X { 0x07, 0x08, 0x70, 0x08, 0x07 }, // Y { 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z { 0x00, 0x7F, 0x41, 0x41, 0x00 }, // [ { 0x55, 0x2A, 0x55, 0x2A, 0x55 }, // 55 { 0x00, 0x41, 0x41, 0x7F, 0x00 }, // ] { 0x04, 0x02, 0x01, 0x02, 0x04 }, // ^ { 0x40, 0x40, 0x40, 0x40, 0x40 }, // _ { 0x00, 0x01, 0x02, 0x04, 0x00 }, // ' { 0x20, 0x54, 0x54, 0x54, 0x78 }, // a { 0x7F, 0x48, 0x44, 0x44, 0x38 }, // b { 0x38, 0x44, 0x44, 0x44, 0x20 }, // c { 0x38, 0x44, 0x44, 0x48, 0x7F }, // d { 0x38, 0x54, 0x54, 0x54, 0x18 }, // e { 0x08, 0x7E, 0x09, 0x01, 0x02 }, // f { 0x0C, 0x52, 0x52, 0x52, 0x3E }, // g { 0x7F, 0x08, 0x04, 0x04, 0x78 }, // h { 0x00, 0x44, 0x7D, 0x40, 0x00 }, // i { 0x20, 0x40, 0x44, 0x3D, 0x00 }, // j { 0x7F, 0x10, 0x28, 0x44, 0x00 }, // k { 0x00, 0x41, 0x7F, 0x40, 0x00 }, // l { 0x7C, 0x04, 0x18, 0x04, 0x78 }, // m { 0x7C, 0x08, 0x04, 0x04, 0x78 }, // n { 0x38, 0x44, 0x44, 0x44, 0x38 }, // o { 0x7C, 0x14, 0x14, 0x14, 0x08 }, // p { 0x08, 0x14, 0x14, 0x18, 0x7C }, // q { 0x7C, 0x08, 0x04, 0x04, 0x08 }, // r { 0x48, 0x54, 0x54, 0x54, 0x20 }, // s { 0x04, 0x3F, 0x44, 0x40, 0x20 }, // t { 0x3C, 0x40, 0x40, 0x20, 0x7C }, // u { 0x1C, 0x20, 0x40, 0x20, 0x1C }, // v { 0x3C, 0x40, 0x30, 0x40, 0x3C }, // w { 0x44, 0x28, 0x10, 0x28, 0x44 }, // x { 0x0C, 0x50, 0x50, 0x50, 0x3C }, // y { 0x44, 0x64, 0x54, 0x4C, 0x44 } // z };
-
- main.c :(メイン)
//---------------------------------------------------------------------------- // C main line //---------------------------------------------------------------------------- #include <m8c.h> // part specific constants and macros #include "PSoCAPI.h" // PSoC API definitions for all User Modules #include "oled_portconfig.h" #include "small_font.h" void main(void) { // Start OLED Port OLED_Init(); Full_OLED_Screen(0x0018); //full red color in OLED Full_OLED_Screen(0x07e0); //full green color in OLED Full_OLED_Screen(0xf800); //full blue color in OLED Full_OLED_Screen(0xffff); //full white color in OLED Full_OLED_Screen(0); //clear OLED ChangeFontColor(0x07e0); PutChar(14,6,'W'); PutChar(19,6,'e'); PutChar(24,6,'l'); PutChar(29,6,'c'); PutChar(34,6,'o'); PutChar(39,6,'m'); PutChar(44,6,'e'); ChangeFontColor(0x80ff); PutChar(34,15,'t'); PutChar(39,15,'o'); ChangeFontColor(0x0018); PutChar(44,24,'P'); PutChar(49,24,'S'); PutChar(54,24,'o'); PutChar(59,24,'C'); ChangeFontColor(0xffff); PutChar(34,33,'&'); ChangeFontColor(0xff00); PutChar(14,42,'D'); PutChar(19,42,'P'); PutChar(24,42,'C'); PutChar(29,42,'M'); PutChar(34,42,' '); PutChar(39,42,'P'); PutChar(44,42,'l'); PutChar(49,42,'a'); PutChar(54,42,'y'); PutChar(59,42,'e'); PutChar(64,42,'r'); // foo........ // bar........ }
ってやれば画面一杯に赤→緑→青→白→の画像が出てきた後、写真のように文字が出てくるはず。
※ PSoC Designer 4.3〜5.1betaでコンパイルする際、Settingsの項目でTreat Const as ROMにしないと、RAMがオーバーフローしたぞゴルァって怒られるので注意
*1:aitendoさんのプログラムにバグがありました。Char_Colorはunsigned int型で宣言しないと65k色の指定が出来ません