/*********************************************************************************** * メイン・プログラム:aitendo特売品:0.96インチOLEDモジュール [M096P6JK]表示テスト * ASCII文字表示テスト版 * * SOFTWARE SPI * * コントローラ: * Arduino UNO R3 *(MPU:ATmega328P "microchip tec."・クロック周波数:Fc= 16MHz) * * 2025.4.28 N.Ishii ************************************************************************************/ #include "ASCII_font.h" #define SPI_DATA 11 #define SPI_CLK 13 #define SPI_DC 8 #define SPI_CS 10 #define OLED_RESET 9 #define DEBUG_LED 12 #define OLED_WIDTH 128 #define OLED_HEIGHT 64 #define OLED_BANKS (OLED_HEIGHT/8) #define BLACK 0 #define WHITE 1 char MsgStart[] = "Start Test !!"; char MsgNI[] = "by N.Ishii"; unsigned char SegmentBuffer[128][8]; /// プロトタイプ宣言 void OLED_init(void); void OLED_clear(unsigned int len,char color); void OLED_clear_all(char color); void OLED_locate(unsigned char x,unsigned char y); void SPI_tx_byte(unsigned char d,int dc); void OLED_char (unsigned char dat); //void OLED_ROMstr(const char *str); void OLED_ROMstr(char *str); void Waitx1us(int x); //================================================================================================= void setup() { // Serial.begin(9600); // --- SOFTWARE SPI ピン設定 pinMode(SPI_CS, OUTPUT); // SSD1306 Set CS pin as output pinMode(SPI_DC, OUTPUT); // SSD1306 Set Data/Command pin as output pinMode(SPI_CLK, OUTPUT); // SSD1306 Set SCK pin as output pinMode(SPI_DATA, OUTPUT); // SSD1306 Set DATA pin as output pinMode(OLED_RESET, OUTPUT); // SSD1306 Set RESET pin as output pinMode(DEBUG_LED, OUTPUT); // DEBUG_LED Set sck pin as output OLED_init(); // OLED表示器の初期化 } void loop() { unsigned char i,y; //// 文字列(メッセージ)表示-------------------------------------------------------------------------------- OLED_ROMstr("Start Test !!"); // 1stメッセージ OLED_locate(18,2); // x=4キャラ目(横4キャラ目より表示:1キャラ幅5dot+1dot自動スペースで1文字構成=6dot幅 // になるので、4キャラ目のx座標(dot単位)指定= (4-1)*6= 18 になる。) OLED_ROMstr("by N.Ishii"); // 2stメッセージ delay(5000); //// 全キャラクタ表示(192文字)----------------------------------------------------------------------------- /// 1画面目: 168文字表示 OLED_locate(0,0); y=0; for(i=0; i<168; i++) { if((i>20) && (i%21==0)){ y++; OLED_locate(0,y); } OLED_char(i+0x20); } delay(5000); /// 2画面目: 残り24文字表示 OLED_clear_all(BLACK); // 全画面クリア y= 0; for(i=0; i<24; i++) { if((i>20) && (i%21==0)){ y++; OLED_locate(0,y); } OLED_char(i+(0x20+168)); // 0xC8='ne'から } digitalWrite(12, HIGH); //12ピンのDEBUG_LEDLEDを点灯する while(1); } /**************************************************************************** * UG-2864HSWEG01 OLEDモジュール制御IC SSD1306を 初期設定をする *****************************************************************************/ void OLED_init(void) { //// OLED初期設定 digitalWrite(OLED_RESET, LOW); // LCD リセット指令 delay(10); // LCD リセット保持 digitalWrite(OLED_RESET, HIGH); // LCD リセット解除 digitalWrite(SPI_DC, LOW); digitalWrite(SPI_CS, LOW); digitalWrite(SPI_CLK, LOW); /// コマンド・セット SPI_tx_byte(0xAE, 0); // Display Off SPI_tx_byte(0x00, 0); // set low column address SPI_tx_byte(0x10, 0); // set high column address SPI_tx_byte(0x40, 0); // set start line address SPI_tx_byte(0x20, 0); // set memory addressing mode 171019 SPI_tx_byte(0x00, 0); // horizontal addressing mode SPI_tx_byte(0xD5, 0); // set display clock divide ratio/oscillator frequency SPI_tx_byte(0x80, 0); // set divide ratio SPI_tx_byte(0xA8, 0); // set multiplex ratio(1 to 64) SPI_tx_byte(0x3F, 0); // 1/64 duty SPI_tx_byte(0xD3, 0); // set display offset SPI_tx_byte(0x00, 0); // not offset SPI_tx_byte(0x8D, 0); // set Charge Pump SPI_tx_byte(0x14, 0); // VCC Generated by Internal DC/DC Circuit SPI_tx_byte(0xA1, 0); // set segment re-map 95 to 0 SPI_tx_byte(0xC8, 0); // Set COM Output Scan Direction SPI_tx_byte(0xDA, 0); // set com pins hardware configuration SPI_tx_byte(0x12, 0); SPI_tx_byte(0xDA, 0); // set com pins hardware configuration SPI_tx_byte(0x12, 0); SPI_tx_byte(0x81, 0); // set contrast control register SPI_tx_byte(0xCF, 0); SPI_tx_byte(0xD9, 0); // set pre-charge period SPI_tx_byte(0xF1, 0); SPI_tx_byte(0xDB, 0); // set vcomh SPI_tx_byte(0x40, 0); SPI_tx_byte(0xA4, 0); // set entire display on/off SPI_tx_byte(0xA6, 0); // set normal display /// 全画面(表示RAM)クリア+表示ON OLED_clear_all(BLACK); // 全画面クリア SPI_tx_byte(0xAF, 0); // Display On } /**************************************************************************** * 現在の書き込み位置から指定バイトの表示クリア *---------------------------------------------------------------------------- * 入力: unsigned int len * char color * 出力: 無し *---------------------------------------------------------------------------- * 備考: このコマンドはlenの回数分x位置を増やしながら横へ * 1バンク分クリアする *****************************************************************************/ void OLED_clear(unsigned int len,char color) { for (;len>0;len--){ if(color == BLACK) SPI_tx_byte(0, 1); else SPI_tx_byte(0xFF, 1); } } /**************************************************************************** * 全画面クリア *---------------------------------------------------------------------------- * 入力: char color * 出力: 無し *---------------------------------------------------------------------------- * 備考: VRAM全エリアを指定色で塗りつぶす *****************************************************************************/ void OLED_clear_all(char color) { unsigned char i,j; unsigned char clear_data; OLED_locate(0,0); // 原点位置に、セット OLED_clear(OLED_WIDTH * OLED_BANKS,color); // 128x64全エリア・クリア // SRAM上のセグメントバッファ オールクリア if(color == BLACK) clear_data = 0x00; else clear_data = 0xFF; for(i=0; i<128; i++){ for(j=0; j<8; j++){ SegmentBuffer[i][j] = clear_data; } } } /**************************************************************************** * Data/Command を指定して、LCDに1バイトを送信 *---------------------------------------------------------------------------- * 入力: unsigned char d,int dc * 出力: 無し *---------------------------------------------------------------------------- * 備考: dc = 0 : Command, dc = 1 : Data *****************************************************************************/ void SPI_tx_byte(unsigned char d,int dc) { char Loop; digitalWrite(SPI_CS, LOW); if (dc) { digitalWrite(SPI_DC, HIGH); } else { digitalWrite(SPI_DC, LOW); } for (Loop=0;Loop<8;Loop++){ digitalWrite(SPI_DATA, LOW); if ((d & (unsigned char)0x80) != 0){ digitalWrite(SPI_DATA, HIGH); } Waitx1us(3); digitalWrite(SPI_CLK, HIGH); d <<= 1; Waitx1us(6); digitalWrite(SPI_CLK, LOW); } digitalWrite(SPI_CS, HIGH); } /********************************* * OLEDに一文字表示する * 追加関数:N.Ishii **********************************/ void OLED_char (unsigned char dat){ unsigned char i,chptn; dat -= 0x20; //配列アドレスを計算→ フォントテーブルのトップ[0][5]からスペースコードの20hが格納されている for(i=0; i<5; i++) { //コラムデータを順に取得して、GDDRAMに転送 chptn = chrom[dat][i]; SPI_tx_byte(chptn, 1); //コラムデータを転送 } SPI_tx_byte(0, 1); //文字間隔を空ける } /****************************** * Rom 文字列出力 * 追加関数:N.Ishii *******************************/ void OLED_ROMstr(char *str){ while(*str != 0x00){ // 文字列の終わり判定 // Serial.println(*str); OLED_char(*str); // 文字列1文字出力 str++; // ポインタ+1 } } /**************************************************************************** * OLEDの書き込み位置を X、Y に設定する *---------------------------------------------------------------------------- * 入力: unsigned char x,unsigned char y * 出力: 無し *---------------------------------------------------------------------------- * 備考: 0 <= x <= 127, 0 <= y <= 7 *    左上が原点。 *****************************************************************************/ void OLED_locate(unsigned char x,unsigned char y) { SPI_tx_byte(0x21, 0); // set column address register SPI_tx_byte(x, 0); // set x (column strat address) SPI_tx_byte(127, 0); // set column end address= 127→ これが無いと正しくロケートされない。 SPI_tx_byte(0x22, 0); // set page address register SPI_tx_byte(y, 0); // set y (page strat address) SPI_tx_byte(7, 0); // set page end address= 0→ これが無いと正しくロケートされない。 } /**************************** * 1uS単位の遅延関数 ****************************/ void Waitx1us(int x) // Td = 1uS * x { int i; for(i = 0 ; i < x ; ++i) { /// Td=1000nS(62.5nS x 16) asm("nop \n"); //Td=62.5nS asm("nop \n"); asm("nop \n"); asm("nop \n"); asm("nop \n"); asm("nop \n"); asm("nop \n"); asm("nop \n"); asm("nop \n"); asm("nop \n"); asm("nop \n"); asm("nop \n"); asm("nop \n"); asm("nop \n"); asm("nop \n"); asm("nop \n"); } }