MSP430F2012を使ったお題を一つ [MSP430]
定番のLCDを2012から動かしてみました。最終的にはI2C接続のLCD表示スレーブにするつもりです。
デバックはあれから行っています。電源もあれのUSBからです。
LCDのコントラスト用に電源が必要となりますが、電圧コンバーターIC(LTC1144)を使っています。周辺にコンデンサを2個追加するだけで反転出力(例えば3.3Vを入れると-3.3Vを出力する)しますので、簡単にコントラスト用の負電圧を作れます。あそこで300円で売っています。
その他は、特に特徴は無いですね。
基板はこの方法で作りました。今回はまあまあ上手く行きました。まあ何度か工程の途中で手直しをしていますが。
ソフトウエアは、今までH8とかSHで散々やってきたプログラムをMSP430用に移植しただけなので、わりとすんなり動きました。やっぱりC言語は良いですね。
/****************************/
/* SC1620 LCDに表示をしてみるプログラム */
/****************************/
#include <string.h>
#include "msp430x20x2.h"
#include "iodef2012.h"
#define _MCLK_ (16000000UL)
#define _SAMPLING_FREQ_ (16000 * 2)
union sc1602
{
unsigned char BYTE;
struct
{
unsigned char rsv1:2;
unsigned char RS:1;
unsigned char rsv2:1;
unsigned char DATA:4;
} BIT;
};
#define LCD (*(volatile union sc1602 *)&P1_O)
#define RS_bit P1_O.BIT.B5
#define E_bit P2_O.BIT.B6
#define RW_bit P2_O.BIT.B7
#define DATA_MODE 0 /*データを書込みモード*/
#define CMD_MODE 1 /*コマンドを書込みモード*/
#define FUNCTIONSET LcdWrite(CMD_MODE,0x28) /*ファンクションセットで4bitモードを選択*/
#define DISPLAYOFF LcdWrite(CMD_MODE,0x08) /*表示OFF*/
#define DISPLAYON LcdWrite(CMD_MODE,0x0c) /*表示ON*/
#define DISPLAYCLEAR LcdWrite(CMD_MODE,0x01) /*表示クリア*/
#define ENTRYMODESET LcdWrite(CMD_MODE,0x06) /*インクリメント、表示をシフトしない*/
#define CURSORHOME LcdWrite(CMD_MODE,0x02) /*カーソルホーム*/
#define LINE1 LcdWrite(CMD_MODE,0x80+0x00) /*一行目*/
#define LINE2 LcdWrite(CMD_MODE,0x80+0x40) /*二行目*/
#define LINE3 LcdWrite(CMD_MODE,0x80+0x14) /*三行目*/
#define LINE4 LcdWrite(CMD_MODE,0x80+0x54) /*四行目*/
#define ROWSIZE 16
#define COLSIZE 2
#define LCDBUFFERSIZE (ROWSIZE * COLSIZE)
/************/
/* プロタイプ宣言 */
/************/
static void LcdWrite( int mode, char c );
static void LcdWrite4( char c );
/**************/
/* 大域変数の皆さん */
/**************/
char LcdBuf[ LCDBUFFERSIZE ]; /*LCD用の表示バッファ*/
/**********/
/* WAIT処理 */
/**********/
static void ms_wait(int tim)
{
int i;
volatile int j;
for( i = 0,tim *= 1000; i < tim; i++ )
{
j++;
}
}
/*******************************************/
/* 4bit単位でのLCD書込み処理 */
/* 引数cはLCDにコマンドを書込むかデータ、但し上位4bitのみ有効 */
/*******************************************/
static void LcdWrite4( char c )
{
E_bit = 1; /*Ebitを立てる*/
LCD.BIT.DATA = c; /*データ書込み*/
E_bit = 0; /*Ebitを下げると書き込まれる*/
}
/******************************************/
/* LCD書込み処理 */
/* 引数modeはLCDにコマンドを書込むか、データを書込むかを選択 */
/******************************************/
static void LcdWrite( int mode, char c )
{
RS_bit = ( mode == DATA_MODE ) ? 1 : 0; /*データモードとコマンドモードの切り換え*/
LcdWrite4( c >> 4 ); /*上位4bitを書き込む*/
LcdWrite4( c ); /*下位4bitを書き込む*/
ms_wait( 2 ); /*1ms以上待つ*/
}
/************/
/* refresh */
/* 画面更新処理 */
/************/
void LCD_Refresh( void )
{
int i;
/* DISPLAYCLEAR; */
CURSORHOME;
LINE1; /*一行目の入力*/
for(i = 0; i < LCDBUFFERSIZE; i++)
{
switch ( i )
{
case ROWSIZE: LINE2; break; /*二行目*/
default: break;
}
LcdWrite( DATA_MODE, LcdBuf[ i ] );
}
}
/*******/
/* CLS */
/*******/
void LCD_Cls( void )
{
memset( LcdBuf, ' ', sizeof(LcdBuf) );
}
/***********************/
/* 初期化処理 */
/* LCDを4bitバスモードに設定する */
/***********************/
void LCDInit( void )
{
LCD_Cls();
/*ソフトウエアRESET*/
RS_bit = E_bit = RW_bit = 0; /*RS=E=RW=0*/
LcdWrite4( 0x03 ); /*3を書くらしい*/
ms_wait( 5 ); /*4.1ms以上待つ*/
LcdWrite4( 0x03 ); /*3を書くらしい*/
ms_wait( 1 ); /*1ms以上待つ*/
LcdWrite4( 0x03 ); /*3を書くらしい*/
ms_wait( 1 ); /*1ms以上待つ*/
LcdWrite4( 0x02 ); /*2を書くらしい*/
/*初期設定*/
FUNCTIONSET;
FUNCTIONSET;
DISPLAYOFF;
ENTRYMODESET;
DISPLAYCLEAR;
ms_wait( 1 ); /*待ち*/
CURSORHOME;
ms_wait( 1 ); /*待ち*/
DISPLAYON;
}
/*********** */
/* プログラムmain */
/*********** */
void main( void )
{
static const char msg[] = "モウスグDOSガウゴキソウデス";
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
_BIS_SR( OSCOFF ); //外部に発振子は実装していない
// BCS_CTL1.BIT._RSEL = 15; //16MHzに設定
// DCO_CTL.BIT._DCO = 4; //16MHzに設定
//LCD関連のポートの初期化
P1_SEL.BYTE = 0x00;
P1_D.BYTE = 0xff;
P2_SEL.BYTE = 0x00;
P2_D.BYTE = 0xc0;
LCD.BIT.DATA = 0x0f;
LCDInit();
memcpy( LcdBuf, msg, sizeof(msg) - 1 );
LCD_Refresh();
_BIS_SR(LPM3_bits); // LPM3に入る
}
/****************************** */
/* designed by hamayan since 2007/03/07 */
/****************************** */
以下は回路図です。右クリックでローカルに保存してから見ると、はっきり見る事が出来ます。
> 突然のコメント失礼いたします。
> アライドアーキテクツ株式会社の清水と申します。
> この度、ある企業様が弊社サービスであるエディタエンタープライズを
> 使用してエンジニア様の情報を集めたクチコミサイトをオープンさせてい
> ただくことになりました。
> そこで、是非ともお力添えを頂きたくコメントさせて頂きました。
どんな奴が、どんな転載をして、どんな編集をするのか判らんので、様子見だね。
> 記事が収集されると元記事へのリンクが貼られますので、サイトか
> らの訪問者の増加が期待できますので、サイトのアクセスアップに
> 活用いただければ幸いでございます。
ここは脱力系サイトなんで、訪問者の増加なんかどうでもいいや。
by hamayan (2007-03-08 16:42)
ついにDIPサイズマイコンの使用例がでましたね。何とかMSP430-CQ基板の出力でLCDに表示しようかと思っていました。この回路で表示ができる、、
ちなみにマルツ2号店ではDIPサイズのF2013は無し。F2012はREV.Bが10個くらい箱に入っていました。
>基板はこの方法で作りました。
この方法をぜひ別枠で詳しくお願いします。アイロンは1回こすればOK?ですか?何回もやっていますか?シンナー以外では消去不可?
など。やってみればわかるんでしょうけど。
by ごだ (2007-03-08 20:41)
> この方法をぜひ別枠で詳しくお願いします。
うーん、残念ながら今の所高い再現性を持てる方法が見つかっていないので、紹介したとしても同じ様にできるかどうか。
あくまでも参考程度で。
> アイロンは1回こすればOK?
アイロンで満遍無く熱を掛けるのは難しいです。特にヨドバシで2800円で買ってきたアイロンは、ご丁寧に底面が丸くなっているので、余計難しい。
まず、基板もパターンを印刷した光沢紙も、作りたいサイズから1cm位ははみ出す程度の大きさにし、アイロンをあてますが、満遍無くあてるには、アイロンで紙を擦った時出来る痕跡が紙に付きますので、その痕を見ながら紙全体に熱を掛けて行きます。
大きめにするのは、ピッタリサイズの基板と紙だとどうしても端っこにあてむらができますので、大きめにする事でむらになる事を防ぎます。
転写完了かな?と思ったら。と言うより開き直りで転写完了とし、紙が付いた基板ごと水に10分位は漬けて置きます。
紙をはいだら、その時点でもまだ紙の繊維が付着していますので、さらに水に漬けて紙をふやかします。
歯ブラシで優しく、丁寧に付着している繊維を除去しますが、全部取り切れる訳ではないので、適当な所で切り上げて、カッターの歯等で歯ブラシで取りきれなかった繊維の除去や、つぶれたパターンの修正など等、とにかくここで徹底的に修正を行います。エッチング液に漬けてからでは遅いので。
> シンナー以外では消去不可?
シンナーは別に入手困難な薬品では無いので、それ以外の選択と言うのもあれですが、根性が有るなら、クリームクレンザーで擦ってもとれると思います。
ちなみにアルコールやブレーキクリーナーは全く歯が立ちませんでした。
ガソリンなら行けるかも。
タイトなパターンなら、感光基板をお勧めします。
そうそう、アイロンプリントでシルク印刷は結構良いかもしれない。
こっちはそれ程出来栄えを求めませんしね。
by hamayan (2007-03-08 21:51)
>何とかMSP430-CQ基板の出力でLCDに表示しようかと
100円ショップの電卓のLCDを使うと書いてたのは、ごださんのHPじゃ?
セグメントが違うので-1999の表示は出来ませんでしたが、
999-は出来ました。1の部分はMかEの文字部分を表示(私の買ったLCD
では)
でも、それで終わってます。
by nori@55歳 (2007-03-08 22:46)
hamayanさんありがとうございます。やってみるしかないかな~
シンナーも買ってこよう。何十年前かに買って以来だな~
noriさん「100円ショップの電卓のLCDを使う」は私じゃないのですね。私は2千円も出してLCDを使いたくなかったので取りつけていません。今は500円とか。
その100円ショップの液晶も興味があります。どこだろう?
NDIの著者確認済み基板が売れ残って、基板+LCD組で秋月で売り出されたら買いましょう。
by ごだ (2007-03-09 09:21)
>電圧コンバーターIC(LTC1144)を使っています。
こんな便利なICが世の中にはあったんですね。明日、さっそく買ってこよっと。
上の回路図で、輝度調節用に使ってるボリューム(半固定抵抗?)って、何Ωとかありますか?分圧してるだけだから、なんでもいいとは思うのですが、念のため、よろしければ教えてください。
by Sim (2007-03-09 22:23)
↑10KΩです。
ただこのICは"A"のある時商品なので、店舗に確認してみてください。
by hamayan (2007-03-09 23:26)
ありがとうございます。店の人に聞いたら奥から出してくれました。
明日からオープンするという秋月の仮店舗って、なんか空き地なんですけど、どうなるんでしょうね?
by Sim (2007-03-10 21:39)
> 明日からオープンするという秋月の仮店舗って、なんか空き地なん
> ですけど、どうなるんでしょうね?
(*´ー`)
まあプレハブなら、4tに積んでユニックで下ろせばなんとかなっちゃいますからね。
今頃やっているんじゃないかと。
by hamayan (2007-03-10 22:07)
皆さんこんばんは。
今日は何もする事なかったのでTIのボードが搭載している2013
にチョッカイを出してみました。報告は以下のURLにあります。
http://passworld.co.jp/ForumMSP430/viewtopic.php?t=15
日本語訳は数日待って下さいんで。
ご質問等ありましたら掲示板にどうぞ。
次回は同じ101x64ピクセルLCDにグラフィックを書いてみます。
宜しくお願いします。
by パスカル (2007-03-11 21:50)
既に日本語で書かれていますね。
よし、パスワールドさんから「101x64 LCD kit」を買って追試だ!。
って、実はパスワールドさんって向こう(海外)の会社かと今迄思っていたんですよ。
by hamayan (2007-03-11 22:35)
こんばんは!
返事を有り難う。いいえ、パスワールドは京都の会社です
(2003年からやっています)。
実は昨日このページを見つけて、2013のLCDドライバ開発の
きっかけになった。
ではでは。。。
パスカル
PS: 誤字・変な表現は済みませんね!
by パスカル (2007-03-11 22:54)
調べてからじゃないとまずいと、WAIT処理 について調べたけど不明。
WAIT処理 の時間はどうやって決めていますか?
PICならシミュレータプログラム、R8Cなら測定の画面があるけどまったくのでたらめなので外部にシンクロ接続で確認。
さて、MSP430の命令語のループ時間の計算はどのようにやられているのでしょうか?
by ごだ (2007-03-12 10:09)
> WAIT処理 の時間はどうやって決めていますか?
上のms_waitの事ですね。実は適当です。
しかし、F2012をデフォルト(DCOの設定無し)で起動すると、約1MHzで動きますので、少なくとも1000倍すれば1ms以上の時間が掛かる事となります。長い分にはそれ程問題無いですから。
しかしそれではあれなので実際にどうなるか調べる手段ですが、色々方法が有るかと思いますが、一番簡単なのはシミュレータでしょう。
アセンブラに展開されたコードを見ると、
62 for( i = 0,tim *= 1000; i < tim; i++ )
\ 000004 0A43 MOV.W #0x0, R10
\ 000006 3E40E803 MOV.W #0x3e8, R14
\ 00000A B012.... CALL #?Mul16
\ 00000E 033C JMP ??ms_wait_1
63 {
64 j++;
\ ??ms_wait_0:
\ 000010 91530000 ADD.W #0x1, 0x0(SP)
65 }
\ 000014 1A53 ADD.W #0x1, R10
\ ??ms_wait_1:
\ 000016 0A9C CMP.W R12, R10
\ 000018 FB3B JL ??ms_wait_0
66 }
\ 00001A 2153 ADD.W #0x2, SP
\ 00001C 3A41 POP.W R10
\ 00001E 3041 RET
多分綺麗にコードは出ないでしょうけれど、この様に展開されていますので、この部分をシミュレータのCYCLECOUNTERで見てみると、1ループ8サイクルで回っています。つまり約8μsですね。
まあ8倍余計に時間が掛かっているので、×1000ではなく、×125でも良いですね。
しかし、この結果は当然最適化レベルに依存しますので、ソフトループの場合は、自分で確認してください。
by hamayan (2007-03-12 11:45)
リファレンスブックを見ながら手計算でサイクル数を計算してみましたが、当然の如く合っていますね。
by hamayan (2007-03-12 12:01)
ウェイトの所だけソースを抜き出してtim <<= 7 (×128)にして実測してみました。494Hzだったので、ほぼ1msです。周波数カウンターはP-16という秋月で売ってるDMMを使いました。
by Sim (2007-03-12 13:17)
>まあプレハブなら、4tに積んでユニックで下ろせばなんとかなっちゃいますからね。
この写真を見ると、テント?
http://www.eleki-jack.com/2007/03/post_65.html
by NO NAME (2007-03-12 14:31)
テ、テ、テ、テント!
前にCCDカメラをごっそり盗まれて大騒ぎだったのに、テント!。
夜は見張りとか居るのかな?。
by hamayan (2007-03-12 14:37)
waitの計算の仕方、ありがとうございます。実測もありがとうございます。
シミュレータのCYCLECOUNTERは正確なんですね。MCLKの時間をかければ実行時間が出るということで、、
秋月は完全にテントですね。横から商品も店員も見えます。商品移動したため、どこにあるかちょっと判りにくいかも。袋100円抵抗どこ行った。
元の店舗は結構奥まであるのが見えます。
何となく閉店すると、テントから昔の店舗に戻す感じしますね。どうでしょう?店員は知らないと言っていたけど。
by ごだ (2007-03-13 19:34)
↑のプログラムを動かしてみました。
waitを減らすと初期化に失敗することが多かったです。付属データシートでは電源投入後15ms待つとなっているみたいなので、試しにwaitを入れてみたら初期化に失敗することもなくなりました。
ところで、どうせwriteしかしないなら、R/WをGNDに落としてしまえとか思ったんですが、ありですか?
by Sim (2007-03-13 23:15)
> ↑のプログラムを動かしてみました。
おお!と言うことは、LCDに何か表示してみたんですね。
ちなみに皆さんのLCDに最初に表示するメッセージは?。
> 付属データシートでは電源投入後15ms待つとなっているみたいなの
> で、試しにwaitを入れてみたら初期化に失敗することもなくなりました。
ですね。ON CHIPデバッカーから外さなかったから気付かなかったけれど、電源投入後にはある程度の時間が必要ですね。
> どうせwriteしかしないなら、R/WをGNDに落としてしまえとか思っ
> たんですが、ありですか?
良いのではないでしょうか。私も使っていませんし。
まあBUSYを読み出すとか、RAMの内容を読み出すとかしない限り、必要無いですね。
by hamayan (2007-03-13 23:55)
あう。ソースをコピペしたので文字列は一緒です。ヒネリがなくてすみません。R/Wの件ありがとうございます。
by Sim (2007-03-14 22:26)