DSP28335によるOLED四線接続とタッチキー制御の実装

ハードウェア接続構成

DSP端子OLED端子機能キー端子
GPIO32SCLI2CクロックGPIO48
GPIO33SDAI2CデータGPIO49
GPIO34RESリセットGPIO50
GPIO35DCデータ/コマンドGPIO51
GNDGND接地GND
3.3VVCC電源供給3.3V

ジャンパ設定

  • J19-J20接続(I2C電源)
  • R1-R4プルアップ抵抗有効化(10kΩ)

OLEDドライバ(I2Cインターフェース)

I2C初期化(ハードウェアモード)

#define I2C_BASE 0x00
#define I2C_CHANNEL 0

void InitializeI2C() {
    EALLOW;
    GpioCtrlRegs.GPBPUD.bit.GPIO32 = 0;  // プルアップ有効
    GpioCtrlRegs.GPBPUD.bit.GPIO33 = 0;
    GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 1; // I2C機能割当
    GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 1;
    InitI2CPort(I2C_CHANNEL);             // TIライブラリ初期化
    EDIS;
}

OLED制御関数

#define OLED_ADDRESS 0x3C

void SetupOLED() {
    SendI2CCommand(OLED_ADDRESS, 0xAE);  // 表示オフ
    SendI2CCommand(OLED_ADDRESS, 0x20);  // アドレスモード設定
    SendI2CCommand(OLED_ADDRESS, 0xB0);  // ページ開始アドレス
    SendI2CCommand(OLED_ADDRESS, 0xC8);  // COMスキャン方向
    SendI2CCommand(OLED_ADDRESS, 0x00);  // 低位列アドレス
    SendI2CCommand(OLED_ADDRESS, 0x10);  // 高位列アドレス
    SendI2CCommand(OLED_ADDRESS, 0x40);  // 開始行設定
    SendI2CCommand(OLED_ADDRESS, 0x81);  // コントラスト設定
    SendI2CCommand(OLED_ADDRESS, 0xFF);  // 最大コントラスト
    SendI2CCommand(OLED_ADDRESS, 0xA1);  // セグメント再定義
    SendI2CCommand(OLED_ADDRESS, 0xA6);  // 通常表示
    SendI2CCommand(OLED_ADDRESS, 0xA8);  // マルチプレックス比
    SendI2CCommand(OLED_ADDRESS, 0x3F);  // 1/64デューティ
    SendI2CCommand(OLED_ADDRESS, 0xD3);  // 表示オフセット
    SendI2CCommand(OLED_ADDRESS, 0x00);  // オフセット無し
    SendI2CCommand(OLED_ADDRESS, 0xD5);  // クロック分周
    SendI2CCommand(OLED_ADDRESS, 0x80);  // 推奨値
    SendI2CCommand(OLED_ADDRESS, 0xD9);  // プリチャージ周期
    SendI2CCommand(OLED_ADDRESS, 0xF1);  // プリチャージ値
    SendI2CCommand(OLED_ADDRESS, 0xDA);  // COMピン設定
    SendI2CCommand(OLED_ADDRESS, 0x12);  // コンフィグ値
    SendI2CCommand(OLED_ADDRESS, 0xDB);  // VCOMH電圧
    SendI2CCommand(OLED_ADDRESS, 0x40);  // 電圧値
    SendI2CCommand(OLED_ADDRESS, 0x8D);  // チャージポンプ
    SendI2CCommand(OLED_ADDRESS, 0x14);  // ポンプ有効化
    SendI2CCommand(OLED_ADDRESS, 0xAF);  // 表示オン
}

void DisplayText(Uint16 col, Uint16 row, char *text) {
    while(*text) {
        DrawCharacter(col, row, *text++, 16);
        col += 8;
    }
}

タッチキー制御

キー初期化

#define BUTTON_COUNT 4
#define BUTTON_MASK 0x000F

void InitializeButtons() {
    EALLOW;
    GpioCtrlRegs.GPBMUX2.bit.GPIO48 = 0;
    GpioCtrlRegs.GPBMUX2.bit.GPIO49 = 0;
    GpioCtrlRegs.GPBMUX2.bit.GPIO50 = 0;
    GpioCtrlRegs.GPBMUX2.bit.GPIO51 = 0;
    GpioCtrlRegs.GPBPUD.bit.GPIO48 = 1;  // プルアップ有効
    GpioCtrlRegs.GPBPUD.bit.GPIO49 = 1;
    GpioCtrlRegs.GPBPUD.bit.GPIO50 = 1;
    GpioCtrlRegs.GPBPUD.bit.GPIO51 = 1;
    EDIS;
}

Uint16 CheckButtonPress() {
    static Uint16 prev_state = 0;
    Uint16 current_state = GpioDataRegs.GPBDAT.all & BUTTON_MASK;
    
    if(current_state != 0x0F) {
        DELAY_US(20000);  // チャタリング防止
        if((GpioDataRegs.GPBDAT.all & BUTTON_MASK) != 0x0F) {
            prev_state = 1;
            return current_state ^ 0x0F;
        }
    } else {
        prev_state = 0;
    }
    return 0xFF;
}

メインループ実装

#include "DSP2833x_Device.h"
#include "oled_driver.h"
#include "button_driver.h"

void main() {
    InitializeSystemClock();
    InitializeInterruptController();
    InitializeI2C();
    SetupOLED();
    InitializeButtons();
    
    DisplayText(0,0,"タッチキー検証");
    DisplayText(0,2,"1:開始 2:停止");
    
    while(1) {
        Uint16 btn = CheckButtonPress();
        if(btn != 0xFF) {
            switch(btn) {
                case 0x01:  // キー1
                    DisplayText(0,4,"開始押下");
                    break;
                case 0x02:  // キー2
                    DisplayText(0,4,"停止押下");
                    break;
            }
            DELAY_MS(200);
        }
    }
}

長押し検出機能

#define LONG_PRESS_THRESHOLD 1000

Uint16 DetectLongPress() {
    static Uint32 press_start[BUTTON_COUNT] = {0};
    static Uint8 active[BUTTON_COUNT] = {0};
    
    Uint16 btn = CheckButtonPress();
    
    if(btn != 0xFF) {
        if(!active[btn]) {
            press_start[btn] = SysCtrlRegs.TIMER0.TIM;
            active[btn] = 1;
        } else {
            if(SysCtrlRegs.TIMER0.TIM - press_start[btn] > LONG_PRESS_THRESHOLD) {
                active[btn] = 0;
                return btn | 0x80;
            }
        }
    } else {
        active[btn] = 0;
    }
    return btn;
}

性能仕様

項目
I2C通信速度400kHz
キー応答時間<5ms
OLED更新頻度60Hz
消費電流(最大輝度)12mA
動作温度範囲-40℃~+85℃

タグ: DSP28335 OLED I2C タッチキー C2000

6月1日 19:45 投稿