プロが教える店舗&オフィスのセキュリティ対策術

SH7144Fマイコンを用いて秋月のLCDモニターSC1602BSの駆動を試みています。
以下のようなソースを用意したのですが、文字化けが発生し、20回くらいリセットをかけるとうまく表示されるようになります。
結線方法はBFチェックなしの4BITです。
#include "7144.h"
#define E_SIG 0x20
#define RS_SIG 0x10

void wait(void)
{
int t = 20000;
while(t--);
}

void waits(void)
{
int ts = 800;
while(ts--);
}

void lcdo(unsigned char d)
{
d=d | E_SIG;
PE.DRL.BYTE.L = d;
d = d & 0xdf;
PE.DRL.BYTE.L = d;
waits();
}

void lcdinit(void)
{
lcdo(3);
lcdo(3);
lcdo(3);
lcdo(2);
lcdo(2);
lcdo(8);
lcdo(0);
lcdo(0x0c);
lcdo0);
lcdo(6);
}

void lcdclr(void)
{
PE.DRL.BYTE.L = 0;
lcdo(0);
lcdo(1);
wait();
}

void lcdxy(int y,int x)
{
PE.DRL.BYTE.L = 0;
lcdo(y);
lcdo(x);
waits();
}

void lcdo2(unsigned char d)
{
unsigned dd;
dd = d;
d = d >> 4;
d = d & 0x0f;
d = d | RS_SIG;
lcdo(d);
waits();
dd = dd & 0x0f;
dd = dd | RS_SIG;
lcdo(dd);
waits();
}

void dsp1g(int c,char *str)
{
int i;
for(i = 1;i <= c;i++)
{
lcdo2(*str);
str++;
}
}
void initLCD(void)
{
wait();
lcdinit();
waits();
lcdclr();
}
void main()
{
PFC.PEIORL.BYTE.L = 0xff;
wait();
lcdinit();
waits();
lcdclr();
lcdxy(8,0);
lcdxy(8,2);
dsp1g(5,"HELLO");
waits();
lcdxy(0x0c,2);
dsp1g(5,"WORLD");
while(1);
}
上記ソースに含まれる間違いや改善点がありましたらどうかご教授ください。

A 回答 (1件)

ソースプログラムを拝見して一番に改善した方が良いと思うのは、待ち時間を作る関数のwait()とwaits()です。


ソフトウェアのループで待ち時間を作るのは消費電力と時間の無駄です。
お使いのCPUのクロック周波数が解らないので何ともいえませんが、まさか50MHzのような高速では無いでしょうね?

恐らくウェイトの時間が短か過ぎるのが原因だと思います。

折角タイマーが内蔵されているのですから待ち時間作りはタイマーに任せてその間スリープさせるのが懸命な利用方法です。またもし他にすることが有れば待ち時間に他のタスクを実行できますから。
待ち時間の関数は待ち時間を例えばms単位で指定できる形にすべきです。そうすればLCD表示器だけでなく様々な入出力ポートの制御をするのに汎用的に使えます。
例えば1秒間の待ち時間が欲しければ、wait(1000);とすればいいですね。
私はSHマイコンには詳しくありませんが(このご質問を見てハードウェアマニュアルだけダウンロードしてさらりとCPUの概要を見ただけです)、ウェイト関数がライブラリーに無いでしょうか。

お使いのLCD表示器は私も所有していますが、説明書をご覧頂くと、
LCDの電源を入れてVDDが4.5V以上になった後、15ms以上待って、ファンクションセット命令を送って、4.1ms以上待つ、2個目のファンクションセット命令を送って、100μs以上待つ、3個目のファンクションセット命令を送って、それ以降はBFのチェックが利用可能となりますが、BFを利用できなければ規格表に示された各命令の最大実行時間に十分な余裕を持たせた待ち時間の後に、LCDへ次の命令を送る必要が有ります。

LCDの初期設定が先の手順でなされて無事に立ち上がった後では、例えば「表示クリア」と「カーソルホーム」命令の場合、実行時間の最大値が1.52msとなっていますね。これはLCDの動作クロックが標準の270kHzの時の話で、規格では最低は190kHzですから、BFが利用できない場合はこの最低周波数であってもちゃんと動作するように命令を送った後の待ち時間には十分な余裕を持たせる必要が有ります。1.52ms*270/190=2.16msとなりますからこの場合は3msの待ち時間を取ればいいでしょう。

先にあげたLCDの初期化の時の、15msは余裕をみて22msにしたり4.1msは余裕をみて6msにするなどしてより安全に動作させるように考慮します。

ソースプログラムはwait()とwaits()ぐらいで、他の関数はまだじっくり見ていませんのであしからず。
    • good
    • 0
この回答へのお礼

ご丁寧にありがとうございます。
致命的な欠陥はvolatileが抜けていることでした。
CPUは50MHzで動作しており、ご指摘の通り、待ち時間も短かったようです。
ありがとうございました。

お礼日時:2010/02/02 03:03

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!