埋め込まれた「スマート」キャラクターLCDドライバー。これは良い考えですか?

StackOverflow https://stackoverflow.com/questions/2892407

質問

私は取り組んでいる埋め込みプロジェクトを持っています。現在、キャラクターLCDドライバーをコーディングしています。

現時点では、LCDドライバーは「愚かな」執筆のみをサポートしています。たとえば、行1にはいくつかのテキストがあるとしましょう。私は、行に書き込む関数に電話をかけます。この関数は、単に行の先頭に向かって検索し、テキストを書くだけです(さらに、最後に書かれたものを消去するのに十分な空白)。

これはうまくいっていますが、一部の行は単に「ある程度の読み物:何らかの価値」であるため、私はそれが恐ろしく非効率的であると感じます。

行全体を置き換える「ブルートフォース」ではなく、最善の方法を理解するコードを開発したかったのです アップデート LCDに関する情報。

(背景として、char位置を探すのに2バイトが必要です。その後、文字列の書き込みを開始できます)

私の考えは、最初にループを持つことでした。このループは、入力を最後の書き込みと比較し、そうすることで、次の2つをカバーします。

A:最後の書き込みと入力のすべての違いを収集します。すべての連続したセグメント(同じか異なる場合でも)について、バイトカウントに2バイトを追加します。これはBで参照され、シリアル帯域幅を無駄にしているかどうかを判断します。

B:ループは、これが本当に賢いことであるかどうかを判断します。ラインを「ブルートフォース」するよりも多くのバイトを使用してラインを更新する場合は、戻ってブルートフォースメソッドを引き継ぐだけです。時間を無駄にしないように、この状態が満たされたらすぐにスマート書き込み機能を終了する必要があります。

関数の次の部分では、すべての違いを取り、LCDで必要なcharを求めて書き込みます。

したがって、LCDにすでにこのような文字列がある場合:「Current Temp:80F」と「Current Temp:79F」に更新したい

この関数は、「8」を求めて「79」を書き込むには、帯域幅が少ないことがわかります。 「7」は「8」をカバーし、「9」は「0」をカバーします。そうすれば、文字列全体を書き出す時間を無駄にしません。

これは実用的なアイデアのように思えますか?

役に立ちましたか?

解決

これを最適化することは意味がありません。 9600ボーで20バイトを送信するには、ハードウェアが21ミリ秒かかります。ソフトウェアを数マイクロ秒かかります。人間の目が2倍に知覚できるよりも速くディスプレイを更新できるほど速く、「帯域幅」が必要なわけではありません。 'シリアルチャネルで多重化したい。

他のヒント

ディスプレイの自動インクレメントへのオフセットと、それぞれの連続した文字を出力するための単一の書き込みであると仮定すると、私はあなたが修正しようとしている特定のパフォーマンスの問題がない限り、毎回ディスプレイライン全体を単に書き込む傾向があります。 IE:不必要な最適化は潜在的な将来のメンテナンスの頭痛であり、「最適化」は、アプリケーション全体のパフォーマンスに実際に影響を与えるものにより適しています。

注:ディスプレイアップデートが実際にパフォーマンスの問題に影響するアプリケーションである場合、おそらくあなたはどれだけ速くする必要があるかという感覚を持っています。

計画している実装は、問題には複雑すぎるようです。プロセッサが高速でない場合、必要な比較は実際に操作を遅くする可能性があります。

たとえば、温度値を更新する必要がある場合は、温度値を更新し、固定テキストを無視するだけです。更新する必要がある各フィールドのメモリ内に座標が必要です。次に、書き込み位置をその場所に移動し、値を書きます。それが私が通常それをする方法です。

画面の更新がまだ遅すぎる場合は、アセンブリ言語の使用を検討できます。たとえば、数年前、DOT Matrix LCDディスプレイを備えた腕時計タイプデバイス用のソフトウェアを作成しました。ディスプレイの更新は遅すぎました(たとえばスクロールするときにディスプレイ全体を更新するにはほぼ1秒)ので、アセンブリで最も低いレベルのルーチンを書きました(約20行のCを30行のアセンブリに置き換えました)。結果の関数はサイズの半分で、最適化されたC関数の3倍高速であり、ディスプレイの更新速度は適切でした。

そうすれば、文字列全体を書き出す時間を無駄にしません。

多くの時間を無駄にするべきではありません。確かに、このすべてのチェックを行うのにかかる時間よりも少なくなります。

LCDへの接続は何ですか? Spi/i2c/Parellel?

それが何であれ、DMAがインターフェイス上のSOCによってサポートされている場合、それを使用してください。

そうでない場合は、特にプロセッサの命令クロックがデータリンクのクロックよりもはるかに高い場合、TXバイトの間を待ってはいけません。これは、私が扱ってきたほとんどのキャラクターディスプレイが最大時計の仕様が低いため、おそらく真実です。

割り込みルーチンのいずれかを使用して、各バイトの送信を処理するか、割り込みルーティングを制御できる場合は「ハイブリッド」アプローチを使用します(電力節約のためにこれを行っています)。興味深い記事があります ここ

キャラクターディスプレイの場合、この種の更新最適化は curses 図書館はすべてでした。当時、1200ボー以下で愚かな端末と電話回線を備えた大型コンピューターと話をしたとき、画面を遅くするモデムリンクでインタラクティブに感じるほど速く画面を更新することは困難でした。 Curses Libraryは、ユーザーの画面にあるもののキャッシュを保持し、ディスプレイ用の通常の文字が散在する最適な数の移動および消去コマンドに近いものを送信することにより、実用的になりました。端末が何らかの形のカーソルポジショニングをサポートする必要がありました。

Curses Libraryはいくつかの形で存在し、 ncurses, 、たとえば、よく知られており、オープンソースであり、GPLの下でライセンスされています。

原則として、ncursesを適応させてディスプレイコントローラーと話し合い、すべてのハードワークを行わせることができます。

未解決の問題は、それが努力する価値があるかどうかです。 9600ボーでは、毎秒960文字を送信できます。これは、20列のLCDで4行を完全に塗り直すのに十分な速さです。したがって、写真やattinyを実行していて、ソフトウェアにそのuartを実装し、実際に何か便利なことをするためのサイクルが必要な場合がない限り、あまりにも賢いことにはほとんど利点がありません。

とはいえ、通常、固定テキストを一度ペイントし、変更された値を変更するだけで更新することはまだ理にかなっています。

テキストモードLCD

私は他の人に同意します。テキストモードで書いている場合、キャラクターレベルでこれを行うポイントは実際にはありません。計算を行うために必要な処理時間には、実際に物を書く時間が長くなる可能性があります。

さらに、現在表示されているものをバッファリングする必要があるため、文字ごとのレベルが少しメモリを噛みます(つまり、最後に書かれたもの)。

画面をセクションに分割することでプロセスを簡素化できます(行が最も便利である傾向があります)。その回線が変更されたときにフラグを立てることができます。これは、画面のメモリバッファーに書き込み、後で同期する場合に特に便利です(たとえば、タイミングの割り込みで)。

設計による削減

これをドライバーに任せて達成する代わりに、変更するもののみを書くことができるようにすることで、アプリケーションレベルで書き込み時間を短縮できます。これは、特定の値セルを指定することで実現できます。本質的に次のことを行います。

char text[50];
int val;
...
lcd_print("The count is ", 0, 0); // Print static text at the coords (0,0)
sprintf(text, "%d", val);
lcd_print(text, 0, 13); // Print changing text at (0,13)
...
sprintf(text, "%d", val);
lcd_print(text, 0, 13); // Print changing text at (0,13)

そしてそうではありません:

char text[50];
int val;
...
sprintf(text, "The count is %d", val);
lcd_print(text, 0, 0); // Print all text at the coords (0,0)
...
sprintf(text, "The count is %d", val);
lcd_print(text, 0, 0); // Print all text at the coords (0,0)

グラフィックモードLCD

一方、書き込みプロセスが私のように非常に高価である場合(〜20バイト、グラフィックモードで文字を描く)、キャラクターベースで時間を節約するのが役立ちます。使用できる2つのスキームがあります。 1つ目はあなたが説明する通りですが、テキストのラインを通る水平ピクセル線をバッファリングするという概念を(グラフィカルモードを使用して)考慮したいかもしれません。

各文字ベースで各キャラクターを書くには、描画を水平に想定してから上から下まで、書き込みカーソルをピクセルラインに手動で移動する必要があります。この手順は、テキストライン上のすべての文字のすべてのトップラインを書くことで削除することができます。または、変更されたサブセット(つまり、 "abc"、次に「xxxdefghx」 - > "abcdefghi"で個別に「i」)を作成することで削除できます。

もちろん、後者の方法を使用した正確な保存は、文字の高さを構成するピクセル線の数に依存します。ラインが多いほど、節約が大きくなります(カーソルをさらに移動する必要があるため)。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top