Top Page [◀◀]  2   3   4   5   6   7   8   9   ... [▶▶Last Page

秋月RX621開発キットで、マイコンカ―ラリーH8 3048F-ONE用のサンプルプログラムでLCDを表示させたい。

こんばんわ!

表題にあります通り、秋月の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 constructors
    extern "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行目:0123456789abcdef
    2行目:0123456789ABCDEF と表示されます。

    ●lcdShowProcess関数

    LCDの制御を行います。1ms毎にこの関数を実行するようにします。
    initLcd関数を実行する前から、lcdShowProcess関数は1ms毎に実行しておきます。

    例) lcdShowProcess();

    ●setLcdBuff関数

    ※lcdPrintfを使用すればこの関数を実行する必要はありません。
     互換性を持たすために残しています。

    LCDに表示したいデータを配列のアドレスで渡します。
    引 数:表示したいアドレス
    戻り値:なし

    例) char lcd_buff[ 34 ]; と宣言しておいて、
    sprintf( lcd_buff , "0123456789abcdef0123456789ABCDEF" );
    setLcdBuff( lcd_buff );

    LCDには 1行目:0123456789abcdef
    2行目: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 0
    SWで使用 E RW RS D7 D6 D5 D4
    D3-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 ななめ:

    わわいです
    コードを読むのはめんどくさいので、RX特有の注意点を並べていきたいと思います
    ・RXでは、レジスタプロテクト機能があるので、特定のレジスタの設定には、プロテクト解除の必要がある
    ・周辺デバイスの初期化には、以下の設定の必要があります
    1.スタンバイコントロールレジスタによるデバイスのスタンバイモードからの解除
    2.周辺デバイスのレジスタの初期設定
    更に、割り込みを使用するなら、
    3.割り込みコントローラでの優先度、割り込みイネーブル設定
    というレジスタ群の設定の必要があります

    ここらへん、サンプルコードがいろいろ公開されてますんで、それらを参考にしながら組んでいくと理解しやすいかとおもいます。

    #個人的に、スクラッチで(コード生成を使わずに)組むというのは応援したいところではありますがw
  • ハードの確認ですが、LCDは3.3V対応品でしょうか?(型番は?)
    秋月RX621は3.3V動作です。古いLCDだと5V動作の可能性があります。
  • こんにちは。
    RX621は、H8から移行した初めてのRXマイコンでした。
    マニュアルもレジスタ構成も結構近いので、比較的容易に移行できました。
    タイマSCIについてもほどんど変更の必要が無かった記憶です。

    特に注意する事は、
    1.モジュールがスタンバイになっている。
    レジスタを書き換えても0のままだったりすると、これが原因です。
    MTU0~5のタイマを有効にするには、何種類か書き方がある様ですが、
    MSTP_MTUA = 0;

    2.ポートの入力と出力でレジスタが異なる。
    入力は、ICRレジスタにて、入力を有効にする。
    入力データは、PORTレジスタを読む。
    出力は、DDRレジスタにて、出力ポートを設定する。
    出力データは、DRレジスタに書き込む。
    たとえば、
    PORTD.ICR.BYTE = 0x0f; //下位を入力ポートにする
    PORTD.DDR.BYTE = 0xf0; //上位を出力ポートにする
    PORTD.DR.BYTE = 0xf0; //出力値を書き込む
    tmp = PORTD.PORT.BYTE; //入力値を読み込む
    (設定値は適当です)

    おそらく、標準的なプロジェクトを作成すれば、動くと思います。
    ただし、デフォルトだとクロックが遅くなっていますので、
    SYSTEM.SCKCR.LONG あたりで、クロック設定をしました。

    RX621なら、コード生成を使わない(使えない)ほうが楽な気がします。機能も少ないので、RXマイコンの理解としては良いのではないでしょうか。
  • ななめさん、こんにちは。NoMaYと申します。

    他の人からも同じリプライがありましたが、LCDの型番は何でしょうか?また、データシートのURLが分かっていれば、それも知りたいです。一応、以下で検索してみましたが、これかな?とピンと来るものが無かったので。(www.geocities.jpのブログがヒントになるかなと思ったら、ブログサービス終了になっていて見られませんでした、、、また、HITACHIのサイトのH8サンプルプログラムのページにLCDの文字列は見つかりませんでしたし、、、)

    Google検索: www.google.com/search?q=マイコンカーラリー H8 3048F-ONE LCD
    Google検索: www.google.com/search?q=これから始めるマイコンカーラリー

    それから、そちらのデバッグ状況についてですが、ソースコードをざっと見た印象では、私はlcdLocate( 0, 0 )で座標 ( 0, 0 ) にカーソルが表示されるようにすることが、移植失敗後の最初のステップかな?と思ったのですが、現在、どのようなことをされているでしょうか?

    ちなにみ、私的には、タイマ割り込み駆動で表示バッファの内容をLCDに表示させているのにソースコードにvolatileが無かったり、単なる変数デクリメントのソフトウェアタイマ関数があったり、RXコンパイラでは正しくは動かないのでは?という予感です。(たぶん、GNURXを使用されているのですよね? バージョンは何でしょう? また、e2 studioを使用されているですよね?) [追記] タイマ割り込み処理が変数の参照だけならvolatileは無くてもいいかな、と考え直しました。

  • In reply to NoMaY:

    こんにちは。
    RX621マイコン開発セットならこれかなと。
    akizukidenshi.com/.../
    LCDは3.3Vですが、回路図とか公開されていないみたいです。
    このセットを使用しているのでしょうか?
    これだとHEWが付属しており、H8と同じ環境を使われているのでしょうか。
  • 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制御プログラムの移植版とをすり合わせて行けば、動くものに辿り付けそうですね。

  • みなさん、ご助言ありがとうございます。LCDの型番はSC1602BBWB-XA-LB-G で3.3V動作品です。
    H8で使用していたLCDとの差は、データシートを見た限り、パワーON後のスタンバイ時間が15ms→40msくらいで、コードも使用ビットなどのモードも同じでした。
    モジュールストップに関しましては、ハードウェアセットアップで
    void SYSTEM_init( void ) //システムレジスタ初期化
    {
    SYSTEM.SCKCR.BIT.PCK = 0x01; //PCLK = メインクロック12MHz * 4 = 48MHz
    SYSTEM.MSTPCRA.BIT.MSTPA15 = 0; //モジュールストップ状態の解除 CMTユニット0
    }
    void IO_init( void ) //I/Oポート初期化
    {
    //-----------------------------------------------------------------------
    // LCD Port を設定する
    //-----------------------------------------------------------------------
    PORT4.DDR.BIT.B0 = 1; //出力モードに設定 LCD D4
    PORT4.DDR.BIT.B1 = 1; //出力モードに設定 LCD D5
    PORT4.DDR.BIT.B2 = 1; //出力モードに設定 LCD D6
    PORT4.DDR.BIT.B3 = 1; //出力モードに設定 LCD D7
    PORTE.DDR.BIT.B6 = 1; //出力モードに設定 LCD E
    PORTE.DDR.BIT.B7 = 1; //出力モードに設定 LCD RS
    }

    void CMT0_init( void ){
    //SYSTEM.MSTPCRA.BIT.MSTPA15 = 0; //モジュールストップ状態の解除 CMTユニット0
    CMT.CMSTR0.BIT.STR0 = 0; //カウント動作停止
    CMT0.CMCR.BIT.CKS = 1; // PCLK/32
    CMT0.CMCOR = 1499; // 1ms/(32/48MHz)-1
    CMT0.CMCNT = 0; // カウントクリア
    ICU.IER[0x03].BIT.IEN4 = 1; // 割り込み要求許可
    ICU.IPR[0x04].BIT.IPR = 0x05; // 割り込み優先レベル
    CMT0.CMCR.BIT.CMIE = 1; //割り込み許可
    CMT.CMSTR0.BIT.STR0 = 1; //割り込み開始
    }

    こんな感じに、今必要な分だけONにしています。
    使用しているコンパイラは、GCC for RXです。

    あと、秋月のキットは、RWが常にWriteになっています。(プルダウンされています)
    しかし、ポートを変更して、1本ずつ同じピンにつないで、Dポートなどにつないでも、表示されないか、意図したものではない文字「?」などが表示されます。
  • In reply to ななめ:

    あと、開発環境はE1エミュレータと、e2studioでやっています。秋月のキットにはHEWとサンプルがあったのですが、座標を表示したり変数を表示できなかったので、H8のを使えないかな?という思いから始まりました。
  • In reply to ななめ:

    少なくともタイマー関係はダメダメな書き方されてますね。

    
    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 で動作することしか考えてないプログラムみたいだし、俺だったら頑張って動かすよか捨てて一から書く方選ぶかな。

  • In reply to ななめ:

    > 自分で見れないので、2つソースを表示させます。

    ところで出所不明なソースを貼られてますが使用許諾等、問題ないものなのですか?
  • ななめさん、こんにちは。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()を使った時にローカル変数を幾つか使用したらスタックオーバーフローして暴走したことがあったからです。

  • かふぇルネ管理人です。

    NoMayさんの指摘にもありますように、ソースコードには「Copyright ジャパンマイコンカーラリー実行委員会」と記載されていることから、著作権、使用許諾の問題がある可能性があるため、この投稿を削除させて頂きます。
    詳細に確認後、問題ないと判断された場合は管理人のほうで再度公開する処理を行います。よろしくお願いします。
  • かふぇルネ管理人です。

    皆さんの有用なコメントまで消してしまうのは忍びないので、ななめさんが投稿されたソースコード部分のみを削除させて頂きます。よろしくお願いします。
  • In reply to rsv:

    かふぇルネ管理人です。

    先日削除しましたプログラムはJMCR実行委員会殿が公開を了承しているものであることが確認できました。
    そこで、2019/6/30 20:13の ななめさん記載の内容を復帰させて頂きました。

Top Page [◀◀]  2   3   4   5   6   7   8   9   ... [▶▶Last Page