Top Page [◀◀] 2 3 4 5 6 7 8 9 ... [▶▶] Last Page
こんばんわ!
表題にあります通り、秋月のRX621キット + マイコンカ―ラリー用3048F-ONE LCD表示プログラムが便利なので、流用したいのですが、割り込み、ポートともに設定をしても、表示されません。久しぶりに投稿なので、ソースをドラッグしましたが、見れないようでしたら、掲載いたします。
ご助言をお願い致します。
かふぇルネ管理人です。
先日削除しましたプログラムはJMCR実行委員会殿が公開を了承しているものです。削除した個所を以下に復帰させて頂きます。JMCR実行委員会殿にプログラムの内容に関する責任はなく、質問等には対応できません。
----ここから 書込みの復帰です----
自分で見れないので、2つソースを表示させます。メイン
//--------------------------------------------------------------/* *//* PROJECT NAME : DriveMonitor004 *//* FILE : DriveMonitor004.c *//* DESCRIPTION : Main Program *//* CPU SERIES : RX600 *//* CPU TYPE : RX621 *//* *//* This file is generated by e2 studio. *//* *///---------------------------------------------------------------
//------------------------------------------------------------------------/* File Version: V1.00 *//* Date Generated: 08/07/2013 *///------------------------------------------------------------------------
#include "iodefine.h"
#ifdef CPPAPP//Initialize global constructorsextern "C" void __main(){static int initialized;if (! initialized){typedef void (*pfunc) ();extern pfunc __ctors[];extern pfunc __ctors_end[];pfunc *p;
initialized = 1;for (p = __ctors_end; p > __ctors; )(*--p) ();
}}#endif
//#include "lcd2.c"
/*======================================*//* プロトタイプ宣言 *//*======================================*/void init( void );void timer( unsigned long timer_set );
/*-----------------------------------------------------------*//* LCD出力関数 プロトタイプ宣言 *//*-----------------------------------------------------------*/void lcd_init( void ); /* LCDの初期化 */void lcd_position( char tx ,char ty ); /* LCD表示位置の設定 */void lcd_put_str( char *str ); /* LCDに文字列を表示 */void lcd_put_num( long cnt, int keta ); /* LCDに10進数を表示 *///void lcd_put_hex( long cnt ); /* LCDに16進数を表示 */void lcd_put_ch( char ch ); /* LCD1バイト送信 */void lcd_put_4bit( char bitdata ); /* LCD4ビット送信 */
//----------------------------------------------------------------// 追加したプロトタイプ宣言 ////----------------------------------------------------------------void lcd( void );
/*======================================*//* グローバル変数の宣言 *//*======================================*/unsigned long cnt0; /* timer関数用 */
void main(void){/* マイコン機能の初期化 *///init(); /* 初期化 */initLcd();
while( 1 ){ //ループテストのために追加 2019/6/23
//PORTD.DR.BIT.B0 = cnt_test;timer( 10 ); //power on 4ms deray
initLcd();lcd_position(0,0);lcd_put_str("ready? 3");timer( 1500 );
initLcd();lcd_position(0,0);lcd_put_str("ready? 2");timer( 1500 );
initLcd();lcd_position(0,0);lcd_put_str("ready? 1");timer( 1500 );
initLcd();lcd_position(0,0);lcd_put_str("start!");timer( 1500 );
} //ループテストのための終了 2019/6/23
}//-----------------------------------------------------------------------//メイン終了//-----------------------------------------------------------------------//------------------------------------------------------------------------/* RX621 内蔵周辺機能 初期化 *///------------------------------------------------------------------------void init( void ){
}
//------------------------------------------------------------------------/* タイマ本体 *//* 引数 タイマ値 1=1ms *///------------------------------------------------------------------------void timer( unsigned long timer_set ){cnt0 = 0;while( cnt0 < timer_set );}
lcd.c用↓
//----------------------------------------------------------------------------//* ファイル名 lcd2.c *//* ファイル内容 LCD処理 Ver2.01 *//* Date 2006.05.25作成 2008.08.09改訂 *//* Copyright ジャパンマイコンカーラリー実行委員会 *///----------------------------------------------------------------------------/
/*使い方
●initLcd関数
LCD関連を初期化します。最初に必ず実行します。引 数:なし戻り値:なし
例) initLcd();
●lcdPosition関数
LCDに表示したい位置を指定します。引 数:横列 , 縦列戻り値:なし
例) lcdPosition( 5, 1 );
●lcdPrintf関数
LCDに表示したいデータを記述します。書き方は、printfと同じです。引 数:表示したいデータ戻り値:なし
例)lcdPrintf( "0123456789abcdef" );lcdPrintf( "0123456789ABCDEF" );
LCDには 1行目:0123456789abcdef2行目:0123456789ABCDEF と表示されます。
●lcdShowProcess関数
LCDの制御を行います。1ms毎にこの関数を実行するようにします。initLcd関数を実行する前から、lcdShowProcess関数は1ms毎に実行しておきます。
例) lcdShowProcess();
●setLcdBuff関数
※lcdPrintfを使用すればこの関数を実行する必要はありません。 互換性を持たすために残しています。
LCDに表示したいデータを配列のアドレスで渡します。引 数:表示したいアドレス戻り値:なし
例) char lcd_buff[ 34 ]; と宣言しておいて、sprintf( lcd_buff , "0123456789abcdef0123456789ABCDEF" );setLcdBuff( lcd_buff );
LCDには 1行目:0123456789abcdef2行目:0123456789ABCDEF と表示される。
※注意…sprintf関数は最後に\0文字が付加されるので、配列は1文字分多く取る必要がある。
*/
/*======================================*//* インクルード *//*======================================*///#include <no_float.h> /* stdioの簡略化 最初に置く*/#include "iodefine.h"#include <stdio.h>#include <stdarg.h>//#include <machine.h>//#include "h8_3048.h"/*======================================*//* プロトタイプ宣言 *//*======================================*/int initLcd( void );void lcdShowProcess( void );int lcdPrintf(char *format, ...);void setLcdBuff( char *rp );void lcdPosition(char x ,char y);
void lcd_position(char x ,char y);//void lcd_put_hex(int cnt);void lcd_put_num(long cnt, int keta);void lcd_put_str(char *str);
/*======================================*//* 定数設定 *//*======================================*//* ポート、ビット配置 */#define LCD_DDR PORTD.DDR.BYTE /* 定数名変更 LCDポートDに変更 */#define LCD_DR PORTD.DR.BYTE#define LCD_DDR_NOLCD (0x01<<7) /* LCDに関係ない1bitの位置 */#define LCD_DDR_NOLCD_DDR 1 /* INなら0、OUTなら1 */#define LCD_BIT_BUSY (0x01<<3) /* busy bit(D3のbit) */#define LCD_BIT_E (0x01<<6) /* E bit */#define LCD_BIT_RW (0x01<<5) /* RW bit */#define LCD_BIT_RS (0x01<<4) /* RS bit *//* D7~D4は、必ずポートのbit3~0に接続します *//*-----------------------------------------------------------*//* LCD出力関数 シンボル定義 *//*-----------------------------------------------------------*/#define LCD_E (1 << 6) /* 制御ビット H->L=ENABLE */#define LCD_RW (1 << 5) /* 制御ビット H=READ / L=WRITE */#define LCD_RS (1 << 4) /* 制御ビット REGISTER SELECT */
/*標準での接続: ポートDビット配列: 7 6 5 4 3 2 1 0SWで使用 E RW RS D7 D6 D5 D4D3-D0はGNDに接続*/
/* LCD関連変数 */#define LCD_MAX_X 16 /* 表示文字数 横 16 or 20 */#define LCD_MAX_Y 2 /* 表示文字数 縦 2 or 4 */
/* LCD制御コード */#define LCD_INST 0x00 /* インストラクション */#define LCD_DATA LCD_BIT_RS /* データ */
/*======================================*//* プロトタイプ宣言(ローカル) *//*======================================*/void lcdLocate( int x, int y );void lcdBusyStart( void );int checkLcdBusy( void );void lcdOut( char command, char data );void lcdOut2( char data2 );void lcdTimer( unsigned long timer_set );void lcd_nop( int i );
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*//* プログラムエリア *//*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
char buffLcdData[ LCD_MAX_X * LCD_MAX_Y ];/* 表示バッファ */char buffLcdData2[ LCD_MAX_X * LCD_MAX_Y + 10 ];/* 表示バッファ一時作業エリア */int iLcdposition; /* バッファに書き込む位置 */int iLcdMode = 1; /* 表示処理No管理 */int iLcdNowLocate; /* 現在の表示している位置 */unsigned long dLcdBusyTimer; /* busyスタートタイム */int fLcdRefresh; /* リフレッシュフラグ */int fLcdConnect = 1; /* LCDが接続されているか */
unsigned long dLcdTimer; /* LCDタイミング用タイマ */
//-----------------------------------------------------------------------/* モジュール名 initLcd *//* 処理概要 LCD処理部分初期化 *//* 引数 なし *//* 戻り値 0:異常 1:正常 *///-----------------------------------------------------------------------int initLcd( void ){int i;
for( i=0; i<=LCD_MAX_X*LCD_MAX_Y-1; i++ ) { /* 変数初期化 */buffLcdData[ i ] = ' ';}
lcdTimer( 45 ); /* 40ms以上のタイマ */lcdOut2( 0x03 ); /* ファンクションセット 8bit長 */lcdTimer( 5 ); /* 4.1ms以上のタイマ */
lcdOut2( 0x03 ); /* ファンクションセット 8bit長 */lcdTimer( 2 ); /* 100us以上のタイマ */
lcdOut2( 0x03 ); /* ファンクションセット 8bit長 */lcdBusyStart();while( !(i = checkLcdBusy()) );if( i == 2 ) {fLcdConnect = 0;return 0; /* エラー終了 */}
lcdOut2( 0x02 ); /* ファンクションセット 4bit長 */lcdBusyStart();while( !checkLcdBusy() );
lcdOut( LCD_INST, 0x28 ); /* 1行、font:5*7設定 */lcdBusyStart();while( !checkLcdBusy() );
lcdOut( LCD_INST, 0x08 ); /* 表示off設定 */lcdBusyStart();while( !checkLcdBusy() );
lcdOut( LCD_INST, 0x01 ); /* 表示クリア */lcdBusyStart();while( !checkLcdBusy() );
lcdOut( LCD_INST, 0x06 ); /* インクリメントする、表示シフト無し */lcdBusyStart();while( !checkLcdBusy() );
lcdOut( LCD_INST, 0x0c ); /* 表示ON */lcdBusyStart();while( !checkLcdBusy() );
return 1;}
//------------------------------------------------------------------------/* モジュール名 lcdLocate *//* 処理概要 LCDカーソル移動 *//* 引数 x , y *//* 戻り値 なし *///-------------------------------------------------------------------------/void lcdLocate( int x, int y ){unsigned char work = 0x80;
work += x;if( y == 1 ) {work += 0x40;} else if( y == 2 ) {work += 0x14;} else if( y == 3 ) {work += 0x54;}lcdOut( LCD_INST, work );lcdBusyStart();}
//-----------------------------------------------------------------------/* モジュール名 lcdBusyStart *//* 処理概要 LCD busyスタート *//* 引数 busy値 *//* 戻り値 なし *///-----------------------------------------------------------------------void lcdBusyStart( void ){dLcdBusyTimer = dLcdTimer;}
//------------------------------------------------------------------------/* モジュール名 checkLcdBusy *//* 処理概要 LCD busyチェック *//* 引数 なし *//* 戻り値 2:タイムアウト 1:ok 0:busy中 *///------------------------------------------------------------------------int checkLcdBusy( void ){unsigned char b, b_busy;int ret;
LCD_DDR = LCD_DDR_NOLCD * LCD_DDR_NOLCD_DDR | LCD_BIT_E |LCD_BIT_RS | LCD_BIT_RW; /* data bus read設定 */
b = LCD_DR & LCD_DDR_NOLCD;LCD_DR = b | LCD_BIT_RW;lcd_nop(1);
b = LCD_DR & LCD_DDR_NOLCD;LCD_DR = b | LCD_BIT_E | LCD_BIT_RW;lcd_nop(10);
b_busy = LCD_DR;
b = LCD_DR & LCD_DDR_NOLCD;LCD_DR = b | LCD_BIT_RW;lcd_nop(10);
b = LCD_DR & LCD_DDR_NOLCD;LCD_DR = b | LCD_BIT_E | LCD_BIT_RW; /* 4bitモードなので */lcd_nop(5); /* ダミーでE bitたてる */
b = LCD_DR & LCD_DDR_NOLCD;LCD_DR = b | LCD_BIT_RW;lcd_nop(5);
ret = ( b_busy & LCD_BIT_BUSY ) ? 0 : 1;
if( !ret ) {if( dLcdTimer - dLcdBusyTimer >= 11 ) ret = 2;}
LCD_DDR = LCD_DDR_NOLCD * LCD_DDR_NOLCD_DDR | LCD_BIT_E |LCD_BIT_RS | LCD_BIT_RW | 0x0f; /* data bus read設定 */
return ret;}
//---------------------------------------------------------------------/* モジュール名 lcdOut *//* 処理概要 LCDコマンド出力 *//* 引数 コマンド種類、データ *//* 戻り値 なし *///---------------------------------------------------------------------void lcdOut( char command, char data ){unsigned char work;
work = (unsigned char)command | ((unsigned char)data >> 4);lcdOut2( work );
work = (unsigned char)command | ((unsigned char)data & 0x0f);lcdOut2( work );}
/*======================================*//* lcdOutの共通処理 *//*======================================*/void lcdOut2( char data2 ){unsigned char b;
b = LCD_DR & LCD_DDR_NOLCD;LCD_DR = b | data2;lcd_nop(1);b = LCD_DR & LCD_DDR_NOLCD;LCD_DR = b | data2 | LCD_BIT_E;lcd_nop(9);b = LCD_DR & LCD_DDR_NOLCD;LCD_DR = b | data2;lcd_nop(9);}
//-----------------------------------------------------------------------/* モジュール名 lcdShowProcess *//* 処理概要 LCD表示処理 *//* 引数 なし *//* 戻り値 なし *///-----------------------------------------------------------------------void lcdShowProcess( void ){if( !fLcdConnect ) return; /* 接続されているかチェック */
dLcdTimer++;
switch( iLcdMode ) {case 1: /* データ更新されたかチェック */if( fLcdRefresh ) {fLcdRefresh = 0;iLcdMode = 2;}break;
case 2: /* 位置初期化*/if( checkLcdBusy() ) {iLcdNowLocate = 0;lcdLocate( 0, 0 );iLcdMode = 3;}break;
case 3: /* 改行位置の確認 */if( checkLcdBusy() ) {if( iLcdNowLocate % LCD_MAX_X == 0 ) {lcdLocate( 0, iLcdNowLocate / LCD_MAX_X );}iLcdMode = 4;}break;
case 4: /* データ表示処理 */if( checkLcdBusy() ) {lcdOut( LCD_DATA, buffLcdData[ iLcdNowLocate++ ] );lcdBusyStart();if( iLcdNowLocate >= LCD_MAX_X * LCD_MAX_Y ) {iLcdMode = 1;} else {iLcdMode = 3;}}break;
default:iLcdMode = 1;break;}}
//-----------------------------------------------------------------------/* モジュール名 lcdPrintf *//* 処理概要 LCDへ表示 表示位置は過去に表示した位置の次から *//* 引数 printfと同じ *//* 戻り値 正常時:出力した文字列 異常時:負の数 *///-----------------------------------------------------------------------int lcdPrintf(char *format, ...){va_list argptr;char *p;int ret = 0;
va_start(argptr, format);ret = vsprintf( buffLcdData2, format, argptr );va_end(argptr);
if( ret > 0 ) {/* vsprintfが正常ならLCDバッファへ転送 */p = buffLcdData2;while( *p ) {buffLcdData[iLcdposition++] = *p++;if( iLcdposition >= LCD_MAX_X * LCD_MAX_Y ) {iLcdposition = 0;}}fLcdRefresh = 1;}return ret;}
//--------------------------------------------------------------------/* モジュール名 setLcdBuff *//* 処理概要 LCDバッファにセット *//* 引数 なし *//* 戻り値 なし *///--------------------------------------------------------------------void setLcdBuff( char *rp ){char *wp;int i;
wp = buffLcdData;
for( i=0; i<LCD_MAX_X*LCD_MAX_Y; i++ ) {*wp++ = *rp++;}fLcdRefresh = 1;}
//------------------------------------------------------------------------/* タイマ *//* 引数 タイマ値 1=1ms *///------------------------------------------------------------------------void lcdTimer( unsigned long timer_set ){unsigned long t;
t = dLcdTimer;
while( dLcdTimer - t < timer_set );}
//-----------------------------------------------------------------------/* タイマ *//* 極短いタイミング用タイマ 1当たり1usくらい *///-----------------------------------------------------------------------void lcd_nop( int i ){i = i * 50;while( i-- );}
//-----------------------------------------------------------------------/* モジュール名 lcdPosition *//* 処理概要 LCDの表示位置指定 *//* 引数 横位置 , 縦位置 *//* 戻り値 なし *///-----------------------------------------------------------------------void lcdPosition(char x ,char y){if( x >= LCD_MAX_X ) return;if( y >= LCD_MAX_Y ) return;
iLcdposition = x + y * LCD_MAX_X;}
/*----------------------------------------------------------------------*//* 電波新聞社「これからはじめるマイコンカーラリー」で使用している *//* 関数と互換を取るため、同名の関数を定義します *//* 下記の関数を使用する場合でも、lcdShowProcess関数は *//* 1ms毎に呼ばなければいけません *//*----------------------------------------------------------------------*/
//------------------------------------------------------------------------/* 位置指定 *//* 引数 横位置 , 縦位置 *///------------------------------------------------------------------------void lcd_position(char x ,char y){lcdPosition( x, y );}
//-----------------------------------------------------------------------/* 16進数数値表示(4桁) *//* 引数 表示データ *///-----------------------------------------------------------------------void lcd_put_hex(int cnt){lcdPrintf( "%04x", cnt );}
//-------------------------------------------------------------------------/* 10進数数値表示 *//* 引数 表示データ, 表示桁 *///-------------------------------------------------------------------------void lcd_put_num(long cnt, int keta){char work[6];
if( keta >= 10 ) keta = 9;
work[0] = '%';work[1] = '0';work[2] = '0' + keta;work[3] = 'l';work[4] = 'd';work[5] = '\0';
lcdPrintf( work , cnt );}
//-----------------------------------------------------------------------/* 文字列表示 *//* 引数 文字列の先頭ポインタ *///-----------------------------------------------------------------------void lcd_put_str(char *str){lcdPrintf( "%s", str );}
//-------------------------------------------------------------------------// end of file//-------------------------------------------------------------------------
In reply to ななめ:
ななめさん、こんにちは。NoMaYと申します。他の人からも同じリプライがありましたが、LCDの型番は何でしょうか?また、データシートのURLが分かっていれば、それも知りたいです。一応、以下で検索してみましたが、これかな?とピンと来るものが無かったので。(www.geocities.jpのブログがヒントになるかなと思ったら、ブログサービス終了になっていて見られませんでした、、、また、HITACHIのサイトのH8サンプルプログラムのページにLCDの文字列は見つかりませんでしたし、、、)Google検索: www.google.com/search?q=マイコンカーラリー H8 3048F-ONE LCDGoogle検索: www.google.com/search?q=これから始めるマイコンカーラリーそれから、そちらのデバッグ状況についてですが、ソースコードをざっと見た印象では、私はlcdLocate( 0, 0 )で座標 ( 0, 0 ) にカーソルが表示されるようにすることが、移植失敗後の最初のステップかな?と思ったのですが、現在、どのようなことをされているでしょうか?ちなにみ、私的には、タイマ割り込み駆動で表示バッファの内容をLCDに表示させているのにソースコードにvolatileが無かったり、単なる変数デクリメントのソフトウェアタイマ関数があったり、RXコンパイラでは正しくは動かないのでは?という予感です。(たぶん、GNURXを使用されているのですよね? バージョンは何でしょう? また、e2 studioを使用されているですよね?) [追記] タイマ割り込み処理が変数の参照だけならvolatileは無くてもいいかな、と考え直しました。
In reply to NoMaY:
In reply to HiRoSan:
HiRoSanさん、こんにちは。NoMaYです。先走るのも何ですが、秋月さんのRX621マイコン開発セットの商品写真に見えるSC16の文字と"白抜き"という文字と動作電圧が3.3Vということから推測すると、以下のLCDなのかな?という感じですね。3.3V動作LCDキャラクタディスプレイモジュール 16×2行 バックライト付白抜き [SC1602BBWB-XA-LB-G]akizukidenshi.com/catalog/g/gP-04794/また、RX621マイコン開発セットのCD-RにはLCD制御のサンプルプログラムも付いているようなので、もしこのセットであれば、そのサンプルプログラムと投稿されていたマイコンカーラリーのLCD制御プログラムの移植版とをすり合わせて行けば、動くものに辿り付けそうですね。
少なくともタイマー関係はダメダメな書き方されてますね。
unsigned long dLcdBusyTimer; /* busyスタートタイム */ unsigned long dLcdTimer; /* LCDタイミング用タイマ */ /* LCDの制御を行います。1ms毎にこの関数を実行するようにします。 initLcd関数を実行する前から、lcdShowProcess関数は1ms毎に実行しておきます。 */ void lcdShowProcess( void ) { /* 略 */ dLcdTimer++; /* 略 */ } void lcdBusyStart( void ) { dLcdBusyTimer = dLcdTimer; } int checkLcdBusy( void ) { /* 略 */ ret = ( b_busy & LCD_BIT_BUSY ) ? 0 : 1; if( !ret ) { if( dLcdTimer - dLcdBusyTimer >= 11 ) ret = 2; } /* 略 */ } void lcdTimer( unsigned long timer_set ) { unsigned long t; t = dLcdTimer; while( dLcdTimer - t < timer_set ); } void lcd_nop( int i ) { i = i * 50; while( i-- ); }
dLcdTimer の宣言に volatile 付けるだけで良いのかなあ? なんか H8 で動作することしか考えてないプログラムみたいだし、俺だったら頑張って動かすよか捨てて一から書く方選ぶかな。
ななめさん、こんにちは。NoMaYです。ソースコードの使用許諾的に問題有かも知れませんね。(ジャパンマイコンカーラリー実行委員会によるオープンソース的なものでなく、日立ドキュメントソリューションズの有償著作物かな?)ですので、少しググってみたのですが、ELM-CHANという人のキャラクタLCD制御モジュールと組み込み用printfモジュールをAKI-RX62へ移植するようにして、それに失敗したら、その件を投稿してはどうでしょうか?(RXマイコンならprintfは投稿されていたソースのva_start(), vsprintf(),va_end()を使うような実装でいいと思いますので、組み込み用printfモジュールは参考として。)キャラクタLCDモジュールの使いかたelm-chan.org/docs/lcd/hd44780_j.htmlキャラクタLCD制御モジュールelm-chan.org/fsw/ezlcd/00index_j.html組み込み用printfモジュールelm-chan.org/fsw/strf/xprintf_j.htmlそれで、vsprintf()を使っているということで気になったのですが、スタックが足りてなかったという可能性も、チェックした方が良いように思います。確かe2 studioでGNURXプロジェクトを生成させた時のデフォルトのスタックサイズは256バイトだと思うのですが、以前にsprintf()を使った時にローカル変数を幾つか使用したらスタックオーバーフローして暴走したことがあったからです。
In reply to rsv: