« 山梨県南都留郡道志村(鳥井立)移動 | トップページ | FT680 周波数ステップが変わらない »

2014/06/02

IC732 内蔵OLED表示器

ローカルさんから相談を受けて、IC732の劣化したLCDの代替えにするOLED表示器を製作しました。(なんだかこのパターンが多いような気がする。。。)

既に同様のものを製作しているJA2LDRさん、JH3MHIさんのブログを参考にしました。お二人の情報なしでは1週間かそこいらではこんなもの作れません。

上カバーを閉めてませんが、完成状態です。iPhoneのカメラの都合で実際よりも青みが抜けて白っぽく写っています。 OLEDは共立で扱っているWEH001602ABPP5N00000 _です。

Gaikan

基板の回路図はこんな感じです。例によってPSoCを使っています。
元々の表示r回路であるサンヨー(ってもうないんだっけ)製のLCDコントローラに行くクロック同期シリアル信号を横から観察して表示データを取得し、OLEDまたはLCDに表示します。
回路図の右側にあるリレーは電源投入時にXFCボタンをを押した状態を作るためのものです。PSoCがシリアル信号を受信可能になる前に表示データが送られているため、普通にやると何か操作するまで何も表示できません。これを解決するためにPSoCがシリアル信号を受信可能になった時点でリレーを使ってXFCボタンの接点を接続した状態を擬似的に作り出しています。(フォトカプラか何かで十分なのですが、安く買ったリレーの在庫が10個くらいあったので使いました。)

Ic732dispkairozu

デバッグ中の様子です。リレーはまだ基板に実装していません。
以前CI-V表示器を作成した時、なぜかデバッグ中にLCDを壊しまくったので、OLEDよりは安価なLCDを使っています。OLEDとLCDの制御仕様がほぼ同じなのでこのようなことができます。
Pcb_lcd

一応PSoC版の表示ソフトを貼っておきます。

OLED_Init()関数はデジットのサイトにあったOLEDの初期化シーケンスに相当します。これがないと表示が真っ黒でした。

//----------------------------------------------------------------------------
// C main line
//----------------------------------------------------------------------------

#include <m8c.h>        // part specific constants and macros
#include "PSoCAPI.h"    // PSoC API definitions for all User Modules
#include "stdlib.h"
#include "string.h"

#define CE0X    (PRT2DR & 0x04)
#define CE1X    (PRT2DR & 0x01)

#define buf_size 16
unsigned char recv_buf1[buf_size] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
unsigned char recv_buf2[buf_size] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
unsigned char buf_pos1 = 0;
unsigned char buf_pos2 = 0;

unsigned char disp_buf1[] = "                ";
unsigned char disp_buf2[] = "                ";

unsigned char updtF = 0;


void wait(LONG l){while(l--);}


unsigned char Seg2Ascii(unsigned char x)
{
    switch(x & 0xfe){
        case 0x00 :{return ' ';};   
        case 0xFA :{return '0';};   
        case 0x0a :{return '1';};   
        case 0x76 :{return '2';};   
        case 0x5e :{return '3';};   
        case 0x8e :{return '4';};   
        case 0xdc :{return '5';};   
        case 0xfc :{return '6';};   
        case 0x4a :{return '7';};   
        case 0xfe :{return '8';};   
        case 0xde :{return '9';};   
        case 0xee :{return 'A';};   
        case 0xbc :{return 'b';};   
        case 0xf0 :{return 'C';};   
        case 0x3e :{return 'd';};   
        case 0xf4 :{return 'E';};   
        case 0xE4 :{return 'F';};   
        case 0xB0 :{return 'L';};   
        case 0x3c :{return 'o';};   
        case 0xe6 :{return 'P';};   
        case 0x24 :{return 'r';};   
        case 0xae :{return 'H';};   
        case 0xa0 :{return 'i';};   
        case 0x2c :{return 'n';};   
        case 0xb4 :{return 't';};   
        case 0xba :{return 'U';};   
        case 0xce :{return 'q';};   
        case 0x04 :{return '-';};   
        case 0x38 :{return 'u';};   
        default   :{return '?';};       
    };
}

#pragma interrupt_handler INT_SPI_1
void INT_SPI_1(void){
    unsigned char X;
    if (SPIS_1_bReadStatus() & SPIS_1_SPIS_SPI_COMPLETE){
        X = SPIS_1_bReadRxData();
    };
    SPIS_1_SetupTxData(0x00);

    if (CE0X){
        if (buf_pos1 < 0x10){
            recv_buf1[buf_pos1++] = X;
            updtF = 1;
        };
    } else if (CE1X){
        if (buf_pos2 < 0x10){
            recv_buf2[buf_pos2++] = X;
            updtF = 1;
        };
    }else {
        buf_pos1 = 0;
        buf_pos2 = 0;
    };
}

void OLD_Nibble_Write(unsigned char X)
{
    unsigned char Y;
    Y = (X >> 4) & 0x0f;
    PRT0DR = Y;
    wait(100L);
    PRT0DR = Y + 0x10;
    wait(100L);
    PRT0DR = Y;
    wait(100L);
    Y = X & 0x0f;
    PRT0DR = Y;
    wait(100L);   
    PRT0DR = Y + 0x10;
    wait(100L);
    PRT0DR = Y;
    wait(100L);
}

void OLD_Init(void)
{
    OLD_Nibble_Write(0x0c);        //
    OLD_Nibble_Write(0x13);        //
    OLD_Nibble_Write(0x00);        //
    OLD_Nibble_Write(0x00);        //
    OLD_Nibble_Write(0x02);        //
    OLD_Nibble_Write(0x28);        //
//    OLD_Nibble_Write(0x0e);        //
    OLD_Nibble_Write(0x0c);        //
    OLD_Nibble_Write(0x06);        //
    OLD_Nibble_Write(0x01);        //
    OLD_Nibble_Write(0x17);        //
}

void main(void)
{
    // M8C_EnableGInt ; // Uncomment this line to enable Global Interrupts
    // Insert your main routine code here.
    LCD_Start();
    SPIS_1_Start(SPIS_1_SPIS_MODE_3 | SPIS_1_SPIS_LSB_FIRST);
    SPIS_1_EnableInt();
    SPIS_1_EnableSS();
    XFC_Start();
    M8C_EnableGInt;

    wait(50000L);
    OLD_Init();
    XFC_On();
    wait(10000L);
    XFC_Off();
       
    while(1){
        while (!updtF){};
        wait(1000L);
        //Line 0
        //disp VFO-MEM
        if (recv_buf2[10] & 0x08){
            disp_buf1[ 0] = 'A';
        }else if (recv_buf2[10] & 0x02){
            disp_buf1[ 0] = 'B';
        }else {
            disp_buf1[ 0] = 'M';
        };
       
        //disp freq
        disp_buf1[ 3] = Seg2Ascii(recv_buf1[9]);
        disp_buf1[ 4] = Seg2Ascii(recv_buf1[8]);
        disp_buf1[ 5] = '.';
        disp_buf1[ 6] = Seg2Ascii(recv_buf1[7]);
        disp_buf1[ 7] = Seg2Ascii(recv_buf1[5]);
        disp_buf1[ 8] = Seg2Ascii(recv_buf1[4]);
        disp_buf1[ 9] = '.';
        disp_buf1[10] = Seg2Ascii(recv_buf1[3]);
        disp_buf1[11] = Seg2Ascii(recv_buf1[2]);

        //disp mode
        if (recv_buf1[10] & 0x02){
            disp_buf1[13] = 'U';
            disp_buf1[14] = 'S';
            disp_buf1[15] = 'B';
        }else if (recv_buf1[10] & 0x08){
            disp_buf1[13] = 'L';
            disp_buf1[14] = 'S';
            disp_buf1[15] = 'B';
        }else if (recv_buf1[10] & 0x01){
            disp_buf1[13] = 'C';
            disp_buf1[14] = 'W';
            if (recv_buf1[9] &0x01){   
                disp_buf1[15] = 'n';
            }else {
                disp_buf1[15] = ' ';
            };
        }else if (recv_buf1[ 7] & 0x01){
            disp_buf1[13] = 'A';
            disp_buf1[14] = 'M';
            disp_buf1[15] = ' ';
        }else if (recv_buf1[ 3] & 0x01){
            disp_buf1[13] = 'F';
            disp_buf1[14] = 'M';
            if (recv_buf1[2] & 0x01){
                disp_buf1[15] = 'T';
            } else {
                disp_buf1[15] = ' ';
            };
        };
       
        //Line 1
        //disp mem
        disp_buf2[0] = Seg2Ascii(recv_buf2[1]);
        disp_buf2[1] = Seg2Ascii(recv_buf2[0]);

        if (!(recv_buf2[ 9] & 0x01)){
            disp_buf2[ 9] = '.';
        } else {
            disp_buf2[ 9] = ' ';
        };
            
        disp_buf2[10] = Seg2Ascii(recv_buf2[3]);
        disp_buf2[11] = Seg2Ascii(recv_buf2[2]);

        //disp freq
        //disp Split
        if (recv_buf2[5] & 0x01){
            disp_buf2[ 3] = Seg2Ascii(recv_buf2[9]);
            disp_buf2[ 4] = Seg2Ascii(recv_buf2[8]);
            disp_buf2[ 5] = '.';
            disp_buf2[ 6] = Seg2Ascii(recv_buf2[7]);
            disp_buf2[ 7] = Seg2Ascii(recv_buf2[5]);
            disp_buf2[ 8] = Seg2Ascii(recv_buf2[4]);
            disp_buf2[ 9] = '.';
            disp_buf2[10] = Seg2Ascii(recv_buf2[3]);
            disp_buf2[11] = Seg2Ascii(recv_buf2[2]);
            disp_buf2[13] = 'S';
        //RIT DeltaTx
        }else if ((recv_buf2[ 7] & 0x01) || (recv_buf2[ 9] & 0x01)) {
            disp_buf2[ 3] = ' ';
            if (recv_buf2[ 7] & 0x01){
                disp_buf2[ 4] = 'T';
            } else {
                disp_buf2[ 4] = ' ';
            };
            if (recv_buf2[ 9] & 0x01){
                disp_buf2[ 5] = 'R';
            }else {
                disp_buf2[ 5] = ' ';
            };
            disp_buf2[ 6] = ' ';
            disp_buf2[ 7] = Seg2Ascii(recv_buf2[9]);
            disp_buf2[ 8] = Seg2Ascii(recv_buf2[8]);
            disp_buf2[ 9] = '.';
            disp_buf2[10] = Seg2Ascii(recv_buf2[7]);
            disp_buf2[11] = Seg2Ascii(recv_buf2[5]);
            disp_buf2[13] = ' ';
               
        }else{
            disp_buf2[ 3] = ' ';
            disp_buf2[ 4] = ' ';
            disp_buf2[ 5] = ' ';
            disp_buf2[ 6] = ' ';
            disp_buf2[ 7] = ' ';
            disp_buf2[ 8] = ' ';
            disp_buf2[ 9] = ' ';
            disp_buf2[10] = ' ';
            disp_buf2[11] = ' ';
            disp_buf2[12] = ' ';
            disp_buf2[13] = ' ';
        };

        //disp lock
        if (recv_buf1[10] & 0x40){
            disp_buf2[15] = 'L';
        }else {
            disp_buf2[15] = ' ';
        };
       
        LCD_Position(0,0);
        LCD_PrString(disp_buf1);
        LCD_Position(1,0);   
        LCD_PrString(disp_buf2);
        updtF = 0;
    }
}

« 山梨県南都留郡道志村(鳥井立)移動 | トップページ | FT680 周波数ステップが変わらない »

自作」カテゴリの記事

コメント

こんばんは、JA2LDRです。初訪問となります、よろしくです。
いいものが出来ましたね。

そうですね、受信レディになる前にデータが来てしまいすよね。当局は、アセンブラで
(・・しか使えません)出来る限り早く、受信割り込み許可となるようプログラミングしました。
OLEDの初期化はそっちのけで。
通常パワーオンは頭から受信できますが、セットアップ画面がきついですね。30%くらいが受信取りこぼしとなります。まあ、1MHz UP/DWキー操作でOKとなりますのでこのままです。

OLEDももっと色んな品種が入手できるといいですね。
ただ今ストロベリーリナックスのグラフィックOLEDでCI-V表示器をこしらえました。自前で作ったFONTは決してきれいな文字ではありませんが。

今後とも色々教えてください。         FB DX 73! de JA2LDR


こんばんは。
訪問ありがとうございました。このタイミングで参考にさせていただた方からコメントいただけるなんてちょっとびっくりしています。
自分で使うのであれば画面に「Hit any KEY!!」でも表示して済ませるところですが、ローカルから頼まれてやっていたことと、あれこれ考えるの面倒だったので部品箱にあったリレーの登場となりました。最初は「フォトカプラでも・・・」と考えたのですが、買いに行くのが面倒だったのでオーバースペックを承知でリレーにしています。

今回OLEDを始めて使いましたが、みやすさの点ではかなりいいと思いました。
高価な点と扱っている業者が少ない点から供給に不安があります。OMがお使いになっている20桁タイプのものがよかったのですが、品切れなのか入手できませんでした。

自作のフォントといえば、昨年製作したグリッドロケータ表示器が自作フォントを使用しました。使えるドット数が多いとかえってデザインの善し悪しが出てしまって苦労しました。

こんにちは、 うろうろしてたらたどり着きました。
当局の ic-732は、ほったらかしです。^^;

to JH3MHI

参考にさせていただいた両OMからコメントをいただいて感激しております。

表示はなんとかなったのですが、一緒に頼まれていたPLLまわりの調整で難儀してます。(人のリグのPLLを再調整する前に練習がてらと着手した自分のFT680がサービスマニュアルどおりにやったつもりが訳わからない状態になってしまいました。)

私のレベルではPLL回路は触らない方が無難なようです。

またよろしくです。

こんばんは
LDRさんがコメントしてたので、ついコメントしました^^;
732は まだほとんどいじってませんが、736と中身はだいぶ違いますね。729に近いかと思ってます。
PLL周りは、トリマーが逝かれている事が多いですが半田クラックも多々あります・・・^^。

また、お邪魔します。

トリマとハンダのクラックですね。情報ありがとうございます。注意しながら進めます。

Hello!
My name is Ramon and my call is DU1FV. I read your article. I have an old Kenwood TRC-70 with a bad LCD display. I am thinking of using your techinique to convert the Kenwood to OLED. It uses the same LCD controller LC7582. What do you think? 73 Ramon

Hi Ramon-san,

I think It is possible but difficult.
If you make it yourself, I support you.

1. Make same circuit on this page.(use PSoC)
2. Huck display data.
about code XX mean charctor Y, and Byte order nn is degit M, etc.,
3. Design LCD/OLED layout..
4. Modify program.
5 Write Binary data to Device.
6. Test and return to 5. (^ ^;

Thank you and 73!!

Hello Kojima-san!
Thank you for your prompt reply!
Yes, I will study your suggestions. I hope to report to you when I get some progress!
Domo arigato gozaimashita!

Hi, Ramon-san,

It is same prduct.
it is necessary that Kit contains Mini-Prog (Programer).
You stepped first step. I am very happy!!

40 Dollers? It is very nice price.

I upload Project files. Please check here.

http://7l1wrk-1.cocolog-nifty.com/blog/2015/11/oledlcd-display.html

コジマさん、こんばんは
IC-736の液晶つぶれでネット検索したらたどり着きました
コンテストばかりですが何度かQSOさせて頂いております。

736は思い出深いリグで再開局の際使いこんでいましたが御多分に漏れず
液晶がつぶれたり10W機から100W化したりとハマッテ居ます
1台の液晶はICOM最後の在庫で自分で交換、直しましたが今回「2個一」にと手に入れた
736がありそこだけ直せればと欲が出てしまい(笑)
JA2LDRさん、JH6HHKさんのblogを見ながらもがいています。

今、私の技術力はこの段階
https://blogs.yahoo.co.jp/alucky777/9788893.html

参考にさせていただきます。
勝手ながら今後ともよろしくお願いします

コメントありがとうございます。
むしろ全部ハードで処理するというのもすごいのではないかと思います。
各セグメント駆動信号をデコードするという発想はありませんでした。

Twitterの方でもよろしくお願いします。

突然のご連絡にて失礼致します。

名古屋で電子部品のオンラインマーケティングを行なっております、ANCHOR代表の森下と申します。

この度、貴サイトを拝見しまして、ぜひ弊社顧客(電子部品関連のグローバル企業)とのタイアップをお願いできないかと考えております。

つきましては、詳細についてお伺いさせていただくことは可能でしょうか。

何卒、よろしくお願い申し上げます。

森下彰大
メールアドレス:info@anchor2018.com
事業紹介HP:https://www.anchor2018.com/

コメントを書く

(ウェブ上には掲載しません)

トラックバック


この記事へのトラックバック一覧です: IC732 内蔵OLED表示器:

« 山梨県南都留郡道志村(鳥井立)移動 | トップページ | FT680 周波数ステップが変わらない »