2011年12月29日

PIC: 超効率コンパイラ jalv2 入門 2012, 2017 (1)

PIC: 超効率コンパイラ jalv2 入門 2012, 2017 (1)
* はじまり
* jalv2: 完全無料、制限なしのPIC用コンパイラ
* 注意ポイント
* Jalv2 ドキュメント・言語仕様 (2017/02追記)
* Jallib API仕様 (2017/02追記)

Jalv2の構文
* コメント
* 関数の定義
* CONFIG値の設定
* 割込みルーチン
* ブートローダと先頭アドレス
* インライン関数
* asm文/インライン・アセンブラ
* 複数行コメント
* Alias機能
* 変数の再定義、部分再定義、ビット定義
* 擬似変数
* case文
* 文字列
* 制御構造 (while/for/repeat)

* RAM BANKと配列について (2016/12追記)
* FlashサイズとSRAMを削減するコンパイルオプション (2016/12追記)


* インストール
* JALEdit:
* LEDチカチカ/PIC16f1827
* Pickit2 + pk2cmd.exe で書き込み
* USBブートローダ
* I2Cマスター/スレーブでLEDチカチカ(1)
* I2Cマスター/スレーブでLEDチカチカ(2)
* USB-CDCサンプルを試す
* LCDサンプルを試す(hd44780互換)
* 新型PIC対応
* jalv2の構文色分けに対応しているエディタ

* 最新バージョン
* Jalv2コンパイラについてのメモ
* Jallibついてのメモ

* はじまり
埋もれたままにしておくのは惜しい言語、Jal。

JALv2 Homepage
    http://www.casadeyork.com/jalv2/
jallib JAL V2 libraries
    ダウンロード
    http://justanotherlanguage.org/downloads
    ソースコード
    https://github.com/jallib/jallib
Jal言語メーリングリスト
    http://tech.groups.yahoo.com/group/jallist/
Jalライブラリ・メーリングリスト
    http://groups.google.com/group/jallib
チュートリアルサイト
    http://justanotherlanguage.org/
jaluino
    http://code.google.com/p/jaluino/

* jalv2: 完全無料、制限なしのPIC用コンパイラ
jalv2とは、一部Pascalの文法を取り入れたPIC用(10F,12F,16F,18F)の開発言語。
オープンソース(BSD, zlibライセンス)。

海外では3冊の書籍が発売されている。  英語 書籍のサポートページ 他国語
(同じ内容で英語、他国語、PaperBack版。この書籍用のライブラリはGPL)

言語としてはJal言語だけど、ここでは同じ意味で「jalv2」も使う。
また「jalv2」とは、現在のリリースの総称的な意味も含む事にする。
なぜなら、検索時に「jalv2」とした方が良いからである。(爆
使用コンパイラのバージョンは基本的に最新正式版を使用する。

Jal言語の特徴は、
1, Jal ≒( Pascal言語 + C言語 + Basic言語 + スクリプト言語 ) 風味÷ 5
    という感じ。(オイ
    Pascalのサブセットをベースに、Pascalの「嫌みなところ」を :D
    ある程度取り去って、現代風にアレンジした感じ。
    比較演算子等はC言語風なので違和感は少ないし、C言語へのコンバートも容易。
    とにかく、シンプルでイージーな言語。
    読み易さ、書きやすさへの配慮:
        例えば、数値表現として「_」アンダースコア区切りで書ける。
        4MHzは、4_000_000
        ビット値は、0b10_01_01_11 等。

        代入文は「:=」でなく、「=」でよい。  (^^)/
        「begin, end」はいらない。  (^^)/
        変数定義はC言語と同じ順。  (^^)/
        比較演算子やビットシフト、割り算もC言語と同じ記法、又は違和感が少ない記法  (^^)/

      従って、イージーなJal言語を学べばC言語への移行もスムースと思われる。
      また、Arduino系やBasic言語、C言語入門程度の知識があれば容易に理解可能と思われます。

2, 完全無料、制限なしのPIC開発言語としては製品版にも匹敵する、
    トップクラスのコード効率をたたき出す。
    と思われる。
    ここを参照
    PIC18F: 超効率Cコンパイラ CPIK

3, 対応PIC   (jallib 1.2.0)
    完全無料、制限なしでPIC10FからPIC18Fまでカバーするのは良い。
        http://avr.client.jp/jallib_full-1.2.0/lib/
    秋月で売っている「お値打ち感のあるPIC」や「入門用PIC」には、ほとんど対応している。

4, ライブラリ/サンプルが豊富
    ライブラリは「jallib」という別プロジェクトとして存在する。
        http://avr.client.jp/jallib_full-1.2.0/sample/
    全ては挙げないが、
    adc, pwm, can, eeprom, lcd, glcd, usb-cdc, spi, uart, sd-card, i2c(master/slave)など一式。
    PIC18F系は、Jal言語で書かれたUSBブートローダや、USB-CDCサンプルがある。

    これらのライブラリが「BSD/zlibライセンス」なところが良い。
    ライセンスに基づいてC言語にコンバートして使うことも可能。

    特に「18F14k50」、「18F2450(18F2550で使える)」のサンプルが多いのはうれしい。

  サンプル/ライブラリのライセンスが明確:
    MikroCなどの無料版には制限がある。気にいったら買えばいいんだけど(爆
    無料で使える商用版のライブラリやサンプルコードが多数ある場合でも、
    改変の有無を問わず、自由に再配布できないものや、ライセンスが不明確な場合が多い。
    その点、
    Jal言語+Jallib の場合、BSD/zlibライセンスの下で改変や再配布が自由に出来る
    メリットは大きいだろう。
5, コマンドライン・コンパイラはWindows,Mac,Linux上で動作可能。

* 注意ポイント
そうは言っても、ボランティアベースでぼちぼち維持されている物なので、
それなりの広い心は必要かと思います。
Jalのメーリングリストはもう12年も続いています。
不具合や不明な点はメーリングリストを参照、参加するのが吉かも。(英語だけど。 orz)

以下、Jal言語を使う時のポイントを記述する。詳細はマニュアルを参照。

* Jalv2 ドキュメント・言語仕様 (2017/02追記)
Jalv2 言語仕様書:
    PDF: http://avr.client.jp/jallib_full-1.2.0/compiler/jalv2.pdf
    TXT: http://avr.client.jp/jallib_full-1.2.0/compiler/jalv2.txt
Jalv2 コンパイル・オプション:
    PDF: http://avr.client.jp/jallib_full-1.2.0/compiler/jalv2opt.pdf
    TXT: http://avr.client.jp/jallib_full-1.2.0/compiler/jalv2opt.txt
Jalv2 pragmaディレクティブの仕様:
    PDF: http://avr.client.jp/jallib_full-1.2.0/compiler/jalv2pragma.pdf
    TXT: http://avr.client.jp/jallib_full-1.2.0/compiler/jalv2pragma.txt

* Jallib API仕様 (2017/02追記)
    各種ライブラリの説明と、サンプルコードにアクセスできる様にしておきました。
    http://avr.client.jp/jallib_full-1.2.0/doc/html/

* 大文字小文字の区別はありません
これは、Pascal言語やBasic言語と同じ。

* 変数の初期化
初期値なしのグローバル変数は、プログラム開始前の時点で"0"に初期化されません。
オプションで"0初期化可能"の様ですが、例外事項があったりと分かりにくいので、
自分の場合"0初期化"が必要な場合、プログラム内で明示的に行っています。

*コメント
「--」(マイナス2つ)又は、「;」(セミコロン)以降がコメントとなる。(行末まで)
「;」セミコロン以降がコメントであることを利用して、
このブログでは以下のような記述を使用する。
青文字がコメント。
-- この行はコメント
if( INTCON_TMR0IE & INTCON_TMR0IF ) then
    INTCON_TMR0IF = 0;  /* 要求フラグをクリア */
    TMR0 = 0xF0;        /* カウント値の再設定 */
end if
上のようにC言語風に見せかける事が出来る。 少なくとも「Pascal言語」には見えない。 従って、C言語への移行も、お気楽。 「;」は文の区切りではなくコメントの開始マーク。 言語規約上、1行中の複文は未対応である。 *関数の定義 procedureはC言語の「void関数」と同じ。(値を返さない関数) 変数の定義順がC言語と同じなので違和感が少ない。「begin, end 」も必要ない。 黄色は型を表す。「var ..」でローカル変数を定義する。
procedure proc_name( byte in foo, word in bar ) is
    var byte baz, zoo;       /* ローカル変数定義 /
    var dword bal;

    TRISIO_TRISIO0 = output; /* 出力に設定  */
    GPIO_GP0       = on;     /* Hを出力     */ 
    ...
end procedure
上で1行目の最後に「is」が必要。 戻り値が必要な関数はfunctionで以下のように定義する。 ちょっと変態チック (オイ
function func_name( byte in foo, word in bar ) return dword is
    var dword res;           /* 戻り値 */

    TRISIO_TRISIO0 = output; /* 出力に設定  */
    GPIO_GP0       = on;     /* Hを出力     */ 
    ...
    return res;
end function
上はdword型の値を返す。 型さえ合えば、戻り値は式でも変数でも可能。 関数の引数: 引数が「値渡し(in)」か「参照渡し(in out)」かを指定する。 「out」単独の使用は非推奨と書いてあるものの、ライブラリでは使用されている。。
procedure mulx( word in foo, word in out bar ) is
    bar = bar + foo * 5;
end procedure
上で、引数fooが「値渡し」、barが「参照渡し」。
var word a=3, b=2;
mulx( a, b );
変数bは17に書き換えられる。 各種の言語で上と等価な関数を書いてみると、
/* C++言語なら */
void mulx( uint16_t foo, uint16_t& bar ){
    bar = bar + foo * 5;
}

/* C言語なら */
void mulx( uint16_t foo, uint16_t *bar ){
    *bar = *bar + foo * 5;
}

(* Pascal言語なら *)
procedure mulx( foo: integer, var bar: integer )
begin
    bar := bar + foo * 5;
end
*CONFIG値の設定 sampleフォルダのソースコードを見れば一目瞭然。 http://avr.client.jp/jallib_full-1.2.0/sample/ 設定可能な項目と設定値はlibフォルダの「PIC名.jal」の中身を「CONFIG」で検索すれば分る。 http://avr.client.jp/jallib_full-1.2.0/lib/ サンプルのCONFIG記述が古く、コンパイルエラーになる場合は、 上記ファイル中(「PIC名.jal」)の記述を指定する。 *割込みルーチン procedure関数の先頭に「pramga interrupt」を書くだけ。 関数名は任意。
procedure isr_name() is
    pramga interrupt;    /* これは割込み関数 */
    if( INTCON_TMR0IE & INTCON_TMR0IF ) then
        INTCON_TMR0IF = 0;
       ...
    end if
end procedure
PIC18Fの場合、高優先度割込みだけがサポートされている。(0x0018番地) *複数の割込みルーチン定義 割込みルーチンはいくつでも定義することが可能。探査中。 割込みベクタは1つしかないけれど、数珠つなぎに呼び出される。
procedure isr_uart_receive() is
    pramga interrupt;    /* UART受信割込み */
    if( ... ) then
       ...
    end if
end procedure

procedure isr_uart_trans() is
    pramga interrupt;    /* UART 送信empty割込み */
    if( ... ) then
       ...
    end if
end procedure
"割込み処理の内容"単位で関数を管理したいときに使える。 各割込み関数は、割込みが発生すると順不同?で1回だけの呼び出しが保証される。 オーバーヘッドは未確認。 *ブートローダと先頭アドレス PIC18Fでユーザープログラムをブートローダ対応にしたい場合、 ユーザープログラムの「リセット時の開始先頭アドレス」をずらす必要がある。 プログラム中に記述する場合は
pragma bootloader loader18 0x1000
とする。この場合「0x1000分」プログラム全体が後方にずれる。 割込みアドレスは自動追従するので気にする必要はない。 コンパイルオプション: コンパイル時のオプションで指定する時は
-loader18 4096
の様に、オフセットアドレスを「10進数」で指定する。 このオプションよりも、pragma bootloader指定が優先される。 CONFIG値をHEXファイルに書かない設定: ブートローダ経由で書き込む場合、これもコンパイルオプションで指定しておく。
-no-fuse
*インライン関数 一度しか呼ばれない初期化関数や、サブルーチン・コールの時間的なオーバーヘッドを削減(注2)したい時に使える。 関数の先頭に「pramga inline」を書くだけ。
procedure init_foo() is
    pramga inline;
    INTCON_TMR0IF = 0;
    ...
end procedure
アセンブラの「sleep命令」をsleep()関数としてラップする方法は 以下、
procedure sleep() is
    pragma inline
    asm sleep
end procedure
上の関数呼び出しは、インライン化されて「sleep命令」1つになる。 *asm文/インライン・アセンブラ 1行だけ書くなら、関数内のどこでも asm sleep 等と書ける。 複数行書きたいなら、任意の場所で
assembler
    sleep
    clrw
    nop
    ...
end assembler
等とする。 アセンブラはあまり使いたくないので、詳細はマニュアル参照。 *複数行コメント 上で書いた1行コメントを繰り返すのが面倒な時に使えるものの、 これは、ちょっとダーティ。 if文で代用する。
if false then
    ここに、
    複数行のコメントを書く。
end if
if文の中身がコンパイルされないことを利用している。 *Alias機能 Alias(エイリアス)とは、変数等に別名を付ける機能。 C言語の「引数なしの#define文」の様な感じでしょうか。 例えば、デフォルトで「GP0端子」は「GPIO_GP0」と定義されている。 これを「GP0」でも参照できるようにするには、
alias GP0 is GPIO_GP0
と定義する。 「GP0端子」に1を設定する場合、
GPIO_GP0 = 1;             /* alias未使用 */

alias GP0 is GPIO_GP0;    /* aliasを定義 */
GP0 = 1;                  /* aliasで短く書ける */
変数、I/Oレジスタ、ビット定義、擬似変数などがAlias可能。 この機能は標準Pascalには無い機能なので非常に便利。 *変数の再定義、部分再定義、ビット定義 Aliasと違って定義済みの変数を「別の型、サイズ」に再定義出来る。 例、
var dword data;               /* dataは32bitの変数 */
var bit data_b29 at data:29;  /* dataの第29ビットをビット変数data_b29 として使う定義 */
var byte elm[4] at data;      /* dataを4つの8ビット型配列として使う定義 */
最後の使い方は、C言語のunionの様でおもしろい。 ライブラリでは、関数に「参照渡し」された引数を再定義して使っている例がある。 *擬似変数 この機能はちょっとユニーク。 任意の関数名に「ゲッター関数とセッター関数」(getter,setter)を定義して、 関数名を(プロパティ)変数のように使うことが出来る機能。 例えば、 eeprom_lastという「EEPROMの最終アドレスのデータを読み書きする擬似変数」を定義すると、 (定義自体はマニュアル参照)
var byte temp;
temp        = eeprom_last;      /* EEPROMから読み出す */
eeprom_last = temp + 1;         /* EEPROMへ書き込む   */
eeprom_last = eeprom_last + 1;  /* これも同じ */
の様に、EEPROMに対する読み書き処理が隠蔽されたまま、変数のように使うことが出来る。 また、擬似変数を「関数の引数に渡す」ことも可能。 これによりC言語の関数ポインタと同様の効果が得られる。 また、擬似変数は「引数」を取るように定義可能で、アドレスを引数として定義すれば、
eeprom_n( 0x04 ) = eeprom_n( 0x10 ) + 1;
の様な記述も可能。 「EEPROMの0x10番地」の内容を読み出して、 「 + 1」した値を「EEPROMの0x04番地」に書き込む。 擬似変数はライブラリ中で多用されている。 * case文 case文はこんな感じ。 C言語の「break」に相当するものはない。 「otherwise:」がC言語の「default:」に相当する。 処理が2行以上になるなら「block ... end block」で囲む。
; /* jalのcase文 */

const STATE_A = 0;
const STATE_B = 1;
const STATE_C = 2;
const STATE_D = 3;
function func_foo( byte in state ) return byte is
    var byte res = 0;
    case state of
        STATE_A: block    ; /* 2行以上なのでblock文で囲む */
            res = res + 3;
            res = res | 0x01;
            end block
        STATE_B:
            res = res + 5;
        STATE_C, STATE_D:
            res = res * 8;
        otherwise: block
            res = 0xFF;
            end block
    end case
    return res;
end function
上をC言語で書いてみると、
/* C言語のcase文 */

#define STATE_A 0
#define STATE_B 1
#define STATE_C 2
#define STATE_D 3
uint8_t func_foo( uint8_t state )
{
    uint8_t res = 0;
    switch( state )
        case STATE_A:
            res = res + 3;
            res = res | 0x01;
            break;
        case STATE_B:
            res = res + 5;
            break;
        case STATE_C:
        case STATE_D:
            res = res * 8;
            break;
        default:
            res = 0xFF;
            break;
    }
    return res;
}
* 文字列 jalv2にはC言語で言う「文字列」(ASCII-Z)という概念がありません。(ポインタもない) 文字列も単なるbyte型の配列と見なされます。
const byte str1[] = "01234"; 「'4'」の後に「\0」は存在しない。
ASCII-Zではないものの、上の様な文字列定数の初期化が可能です。 以下の様に文字列定数「"test1"」を関数の引数に出来ます。
disp_str( "test1" );
実際の使い方: disp_str()関数は架空の関数でしたが、例えば実際にLCD表示するときは、 disp_str()の代わりに、「print_string()関数」を使います。
lcd_cursor_position( 0, 0 );    /* LCDカーソルをhomeへ */
print_string( lcd, "message1");       /* 文字列を表示 */
*制御構造 (while/for/repeat) C言語で言うところの、「continue」に相当する命令はありません。 ループを抜ける「break」は、jalv2では「exit loop」を使います。 forループ: C言語のforループ、
/* C言語 */
int8_t  i;
int8_t dim[10];

for(  i = 0 ;  i < 10 ;  i++ ){
    dim[i] = 0;
}
と等価なjalv2の書式は、
-- jalv2
var byte i;
var byte dim[10];

for 10 using i loop
    dim[i] = 0;
end loop
となります。この場合、"i" は 0〜9の値をとります。 単に処理を10回繰り返すなら、
-- jalv2
for 10 loop
    処理;
    ...
end loop
と書ける。 * RAM BANKと配列について (2016/12追記) 配列は1次元配列のみ。 配列の最大添え字は、一つのRAMバンクサイズに制限されます。 PIC18FでもPIC16F1xxx系のEnhanced midrangeでも同様です。 orz 仮に80バイトのRAM BANKが4つあるマイコンの場合、最大配列は、 var byte dimx[80] と80バイトに制限されます。 ほかの3つのBANKに空きがあれば、dimy[80],dimz[80]と複数確保することは可能と 思われます。 word型なら同様にdimx[40]までとなります。 その他の変数定義のためBANKあたりの未使用RAMが80バイトを割り込んでいればコンパイルエラーに なるでしょう。 large_array: PIC18F PIC18Fマイコンの場合、1BANK 最大256バイトのところ「large_array」ライブラリを使うと、 byte型でdim[2048],word型でdim[1024],dword型でdim[512]までサポートされます。 * FlashサイズとSRAMを削減するコンパイルオプション (2016/12追記) -variable-reuseオプション: 過去のバージョンで「-variable-reuse」オプションにバグがあって非推奨でしたが、 現在(jalv24q5)は大丈夫そうです。従って「-no-variable-reuse」オプションは 指定しないほうが良いです。(デフォルトで -variable-reuseはONです) このオプションでSRAM使用量はかなり減る(状況にもよるが)ので 使う方向で試してみると良いと思います。:D -temp-reduce FLASHとSRAM使用量ががそれなりに削減されます。 現在このオプションをONにしてお試し中です。 -deadcode 指定しても効果がない様だ。 その他のオプション このほかのFLASH・SRAM削減オプションは結構デンジャラスな感じだったので 使っていません。(マイコンが正しく動作しなくなる等) *インストール (2016/12)現在の最新版 jallib v1.2.0を使います。 この版はjalコンパイラjalv24q5が添付されています。 (最新のコンパイラjalv24q6を使いたい場合は、 jallib-pack-bee-jalv24q6-日付.zipをダウンロードします。) ここから http://justanotherlanguage.org/downloads jallib_full-1.2.0.zipを取得して解凍します。 jallib_full_win_setup-1.2.0.exeでも良いでしょう。 以下はjallib_full-1.2.0.zipについての説明です。 *.zipを解凍したトップフォルダをjaldirと表記します。(VERSIONファイルがあるフォルダ) jaldirの部分は実際には「c:\jalsys\jallib_full-1.2.0」等、自分の好きなように解凍した フォルダ名に入れ替える必要があります。 *JALEdit:(注1) Jalv2の統合開発環境「JALEdit」は、メンテナンスされなくなったので 自分は今のところ、後述のコマンドライン・コンパイルしか使っていません。 JALEditも使えないことはないので、ひとまず説明だけは書いておきます。 jaldir\jaledit\jaledit.exe を実行します。 jaledit.png メニューから「Tools」-「Environment Options」-「General」で (1) Path of JAL Lib folder (multiple folders can be separated by semicolon) は、 jaldir\lib (2) Include Source Folder as first item in Library search Path に、 チェックを入れる。(チェックなしでも可) (3) Path to JALV2.exe に、 jaldir\compiler\jalv2.exe を指定する。 その他はデフォルトで。 次に、隣の「JAL」タブで「Optimizations」の (1) 「Disable reusing variable space」のチェックを外します (2) 「Enable temporary reduction」にチェックを入れます。 これらは、Flash、SRAM削減オプションです。 * Jaledit: コンパイルと書込み Jaleditのツールボタンを使ってコンパイルと書込みができます。 jalv2-compile-flash-write.png * LEDチカチカ / PIC16f1827 Jalv2でサポートしているPICには全て「LEDチカチカ」プログラムが付属しています。 JALEditメニューから「File」-「Open」で例えば「jaldir\sample」内の http://avr.client.jp/jallib_full-1.2.0/sample/ 「16f1827_blink_intosc.jal」を開きます。 http://avr.client.jp/jallib_full-1.2.0/sample/16f1827_blink_intosc.jal これは内蔵クロックINTOSCを使ったLED点滅サンプルです。 メニューの「Compile」でプログラムがコンパイルされます。 コンパイル結果のHEXファイルは、「jaldir\sample」フォルダの中に出来ます。 * Pickit3 + ipecmd.exe で書き込み 以下の内容を例えば「jalv2-pickit3.bat」という名前でどこかに保存します。 パス名(黄色の部分)はMPLABXをインストールしたフォルダを指定します。
"C:\Program Files\Microchip\MPLABX\v3.45\mplab_ipe\ipecmd.exe" %1 %2 %3 %4 %5 %6 %7 %8 %9
pause
次にメニューから、「Tool」 - 「Enviromnent Options」 - 「Programmer」 タブ、 「Programmer Executable Path」で「jalv2-pickit3.bat」を指定します。 その下のエディットボックスに
 -TPPK3 -P%D -F%F -M -OL 
を入力してOKします。 *Pickit2 + pk2cmd.exe で書き込み pk2cmd.exeは、ここから、 PK2CMD v1.20をダウンロードしてセットアップします。 1、ダウンロードした「PK2CMD v1.20.zip」を「c:\pk2cmd」に解凍したとします。 「c:\pk2cmd\pk2cmd.exe」があることを確認します。 2、Windowsの環境変数「PATH」に実行パス「c:\pk2cmd」を追加します。 3、MS-DOSコマンドラインで「pk2cmd.exe」を実行してHELP画面が表示されるのを確認します。 次にメニューから、「Tool」 - 「Enviromnent Options」 - 「Programmer」 タブ、 「Programmer Executable Path」で「pk2cmd.exe」の場所を例えば、
c:\pk2cmd\pk2cmd.exe
に指定。 その下のエディットボックスに
-P -M -Y -R -F%F -H100
を入力します。 最後の「-H100」は書き込み終了後に100秒間画面を保持する命令です。 秒数は自由に設定しますが、これがないと正常に書けたかどうかの確認が難しくなります。 書き込み: 後は、メニューから「Compile」-「Program」でPICに書き込みが出来ます。 * コマンドライン・コンパイル方法 自分の場合はMakefileを作ってコマンドライン・コンパイルで使っています。 *I2Cマスター/スレーブでLEDチカチカ(1) jalv2は「I2Cのマスター/スレーブ」のライブラリ・サンプルがあるので実験してみた。 電源電圧は3.3V。 I2Cスレーブ・マイコン:PIC16F883、内蔵クロック8MHz(Fosc)で使用。 ハードウエアI2Cスレーブ・ライブラリを使う。 PIC16F877a用の「16f877a_i2c_hw_slave_echo.jal」を改造。 受け取った1バイトデータをコマンドに見立てる部分を追加しただけ。 動作: I2CマスターからLEDのon/offコマンドを受け取り、LEDをon/offする。(RC2ポート) FLASH使用量:280 word程度。 I2Cマスター・マイコン:PIC18F14k50、内蔵クロック32MHz(Fosc)で使用。 ソフトウエアI2Cマスタ・ライブラリを使う。 「18f14k50_i2c_sw_master_echo.jal」を改造。 送る1バイトデータにコマンドの意味を持たせただけ。 動作: I2CスレーブへLEDのon/offコマンドを1秒周期で送る。 FLASH使用量:830バイト程度。 結果: サクッと「I2Cマスター/スレーブでLEDチカチカ」できた。 (^^)/ (^^)/ 普通はマスター/スレーブ同時に作ると困難を極めるところが(爆、あっさり動作。 Jalのライブラリはかなり良くできてると思う。 I2CマスターのSCLクロック周波数を400khzに設定したが、実測78khzだった。 マスターマイコンのFoscが少し遅いのが影響しているにしても、ちょっと遅いが、 ソフトI2Cなのでよしとする。 3.3VでI2Cバス・プルアップ抵抗は10kΩ(手持ちを使っただけで値は未検証)。 2.2kΩだとI2C通信が不安定だった。 *I2Cマスター/スレーブでLEDチカチカ(2) PICでI2Cスレーブは初めてだったけど、あまりにもあっけなく動いてしまったので、 「queue01」ライブラリ(リングバッファ)も使って、 I2C-LCDの可変長引数コマンドの解析機能を追加してみた。 「case文」が大きくなるのでコードサイズを見るのだ。 *USB-CDCサンプルを試す サクッと動作OK. PIC18F2550でFLASH使用量 2872 byte *LCDサンプルを試す(hd44780互換) サクッと動作OK. PIC18F2550でFLASH使用量 1228byte *新型PIC対応 秋月で安く買える新型PIC、PIC16F1827等にも対応しています。 これらの新型PIC16Fは、PIC18Fが持つ機能も一部含むため「hybrid」と呼ばれる様です。 (Enhanced midrange) *jalv2の構文色分けに対応しているエディタ 以下のエディタが色分け表示に対応している。 1,Editra: http://editra.org/ http://editra.org/uploads/Win/editra.win32.0.6.89.exe (jaluinoのエディタ: 中身は「Editra」 http://code.google.com/p/jaluino/) 2,vim/gVim : http://vim-jp.org/ 対応内容が少し古いけど十分使える。 http://files.kaoriya.net/goto/vim73w32 エディタの背景を黒にする設定: Editra: この「my-black-base.ess」ファイルを 「C:\Documents and Settings\ユーザ名\Application Data\Editra\styles」に置く。 Edit - Preferences - General タブの「Locale Settings Lanhuage」で「Japanese」を選択して 再起動で日本語になる。 編集 - 環境設定 - ドキュメントの「文法ハイライト」タブ - カラースキームで 「my-black-base」を選択すると黒背景になる。 edtra-black.png gVim: この「my-black-base.vim」ファイルを $HOMEのvmfiles/colorsフォルダに置く。(Windowsの場合) $HOMEの_vimrcと_gvimrcに以下を追加して再起動。
" カラー設定: 黒背景
colorscheme my-black-base
gvim-black.png *最新バージョン 現在(2016/12)の正式版は「jal 2.4q5」。 既に 2.4q6がリリースされているので 2017年にはjallib版もリリースされると思う。 2.4q6版が使いたい場合、以下から http://justanotherlanguage.org/downloads jallib-pack-bee-jalv24q6-20161225.zip 等を使えば良い。 現在(2012/03)の正式版は「jal 2.4o」。 ベータ版扱いの次期バージョンは「jal 2.4p」。 http://www.casadeyork.com/jalv2/archive/beta/jalv24p-beta.zip http://www.casadeyork.com/jalv2/ 「jal 2.4p」はコード効率が更に10%程度改善されるらしいので少し探査。 10%も改善されたら完全無料系としては「業界ブッちぎり」の超効率となりそう。 (オントカヨ * Jalv2コンパイラについてのメモ (2017/03): jal 2.4q5: (1) 例えば、PIC16F18313の様にFLASHが2Kword(Page0)しかないマイコンでも movlp(ページ切り替え)命令が全体の10%程度も生成されている。orz この部分はコンパイラの作者にツッコミを入れようかどうか考え中。 * Jallibについてのメモ (2017/03):jallib 1.2.0: (1) sd_card.jal ライブラリの初期化は恐らくバグっていて、初期化中に無限ループに突入する。 orz ここに修正版をsd_card_local.jalとして含めた。 http://mpu.seesaa.net/artile/445037481.html#download 但し、バグ修正以外に自分用にコードサイズ削減のためテキトーに変えた部分があるので注意。 (注1)JALEditは、現在のところ更新されていないので、GUIのバグが残っている模様。 使いにくい場合は、コマンドライン・コンパイルの方が良いかも。 (注2)サブルーチンが複数回呼ばれる場合は、コードサイズとトレードオフ。 参考リンク: USB CDC / 18F2550 usb_serial http://tech.groups.yahoo.com/group/jallist/message/31590
posted by Copyright (C) avrin All Rights Reserved. at 00:28| Comment(39) | PIC関連 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
こんにちは
16f628aのtmr1をカウンタとして使い。
TMR2をゲートタイマとして、ゲート制御の
割り込み処理をしたいのですが、
TMR2の処理の所がエラーになり、
また、
割り込みを許可する所の書き方が判りません。
この書き方を教えて頂けませんでしょうか?

ソースを表示する手段はどどの様にしましょうか
Posted by nekonoko at 2012年03月29日 15:15
こんばんわ、audinです。
TMR2の割込み許可は、以下の感じになると思います。
PEIE1_TMR2IE = 1;
INTCON_PEIE = 1;
INTCON_GIE = 1;
自分はエイリアスを使って、
alias TMR2IE is PEIE1_TMR2IE;
alias PEIE is INTCON_PEIE;
alias GIE is INTCON_GIE;
とした後、
TMR2IE = 1;
PEIE = 1;
GIE = 1;
という風に使っています。
ソースコードはnekonokoさんのページに貼ってもらえば参照出来ると思います。
Posted by audin at 2012年03月29日 22:16
こんにちは 書くべき所を間違って済みません。
拙のページ
割り込みが?なソース
に UPし直しました。
Posted by nekonoko at 2012年03月30日 13:55
こんばんわ、
149行目 procedure _timend_isr() is
 の様に「is」を付けて、156行目のコメントをはずします。
150行目 pragma interrupt
 の様に割込みを有効にします。
170行-172行目は、141行目のBlockの中へ移動して、
INTCON_PEIE = 1
と言う記述も追加する。

という感じにしてみてください。
Posted by audin at 2012年03月30日 21:37
有り難うございます。
明日、早速やってみます。

割り込みの入口はある程度判るのですが、
出口の考えがおぼつきません。
Posted by nekonoko at 2012年03月31日 00:13
すいません、メインループと連動させる事が重要な場合、170行-172行目は、そのままが良いと思います。
Posted by audin at 2012年03月31日 00:25
140行 の最後に 「is」が抜けていました。
156行 のコメントアウトは無しで動作しました。
170行に「INTCON_PEIE = 1」を加えました。
(ペリフェラルインタラプト許可が抜けていました)
これで割り込みが動作するのが判ったので、動作モードの設定に進んでいます。
(出来ればレシプロカルモードも入れたいですが、
別のアルゴリズムなので、tmr機能の切り換えや割り込み先の切り替えが必要で悩んでいます)
カウントモードでタイムピリオドを0.1,0.6,1秒に選択し、tmr1を1/1,1/8のプリスケーラ と1/1で外部の1/64プリスケーラ の切り替えが必要です。
これは RB3の信号で切り換えるつもりですがハードが決まっていないので、ソフトだけの実装をします。

これらの選択に2個のデバウンスswと
case か if を使うつもりですが、
前のバージョンでは caseで組むと領域が大きくなった様な気がして、ifにしてみようと思っています。

この場合2個のswカウントを切り換え要素にするとき
「IF lexpr THEN」の「lexpr」にalias GATE_TIME_01 is 1 --3 で
「GATE_TIME_01」とかを当てたくなって仕方がないのですが、
この辺りの判断基準は、どの様に考えればよいでしょうか?
Posted by nekonoko at 2012年03月31日 13:47
こんにちわ、
ifとcaseのサイズ効率については、簡単な例で比較してみようと思います。

>「IF lexpr THEN」の「lexpr」にalias GATE_TIME_01 is 1 --3 で

aliasに定数は指定出来ないようなので、名前を付け
るなら、
const byte GATE_TIME_01 = 1
var byte gate_time
...
if gate_time == GATE_TIME_01 then
...
end if

という感じでしょうか。
Posted by audin at 2012年03月31日 17:00
機能を欲張って、増やしますと、エラーになってしまいました。
内容は恥ずかしいのでもっとまとめてからUPし、ます。
文例集が少ない(Lチカしかない)
聞いてみるとlcd関連はカーソル基準にアクセスして満足されているようです。
(これではHD44780 の機能が泣いてしまいそうです)
拙のノンノディスクcncにjalv2は判らないままjalv2の書いてはみたものの、まとめ切れませんでした。
Zの時代はすべてのコマンド例など値言うのがあって、重宝しましたが今はその様な考えがないようです。
さて、カウンタに関しては定義部分をさらりと流しながらくみ直してみます。
Posted by nekonoko at 2012年04月01日 01:46
色んな点で行き詰まっています。
しかし上手い具合にダリオさんのページを再発見、
今度は内容も理解できるのが判り読み返しています。
www.dattalo.com/
Posted by nekonoko at 2012年04月04日 00:57
上の方で「function」の項を読んだんですが、
「型さえ合えば、戻り値は式でも変数でも可能。」
と有りましたが, 実際に式を返すにはどの様な表現になりますでしょうか?
追伸 まだ1bitswの3回デバウンスコードで手こずっています。
3回を数えるのに「WHILE」を使いましたが、変数が思う様に変化せず動作しません。
変数を見ようと標準外LCDで表示をさせようとするとこれもまた動作せず、専用にLCDライブラリを書き換えると、
エラーの山になって、これまた失敗です。
Posted by nekonoko at 2012年04月10日 22:58
さっきやっと動作する様になりました。
「周波数カウンタ用予備テスト」
にUPしました。
Posted by nekonoko at 2012年04月11日 01:33
こんばんわ、
デバウンスについては、いろんな方法があると思いますが、以下のかたの方法が参考になると思います。

Arduino+押しボタンスイッチ(1個)
ttp://juncoffee.jp/arduino/swx1.html

Arduino+押しボタンスイッチ(4個)
ttp://juncoffee.jp/arduino/swx4.html

Arduino用ですがjalv2で試すのもおもしろそうです。
Posted by audin at 2012年04月11日 23:35
Arduino+押しボタンスイッチ(1個)
読んでみましたが、このソースは慣れていないので読み切れていません。

jalv2では何とかデバウンス処理は出来たものの、
本来の目標からまだ外れているようです。
ttp://den-nekonoko.blog.so-net.ne.jp/2012-04-12
2個のswでカーソル位置とそこの機能ファンクションを
設定するつもりです。
Posted by nekonoko at 2012年04月12日 14:18
デバウンスは曲がりなりに動作するので、
今度はカウンターを組んでみようと、
お手本にした「周波数カウンタV7」(maikoroC)
を組み直してみました。
元のソースはmaikoroC 現在の版はmaikoroC-PRO
で変更部分があり通らない所があります。
両者間でエキスポートインポートをしないとコンパイルが通りません。

と言うことで上の方にあったC言語風書き方を参考に書き直しましたが、
どうしても換わらない所があり、悩んでいます。
変数宣言(配列の様な感じ)。
case文の書き方等です。

これらはjalv2に変換できるのでしょうか?

それと「JALv2 2.4o ttp://www.casadeyork.com/jalv2/」と「ttp://code.google.com/p/jallib/」は違うものなんでしょうか?

現在はjaleditで動作させています。
見て頂けるのでしたら例の所にUPいたします。
Posted by nekonoko at 2012年04月13日 10:37
こんにちは 16f628aでカウンタが動いたようです。
(カウンタ動作は未確認、lcd表示が思う様に仕上がりました)
ttp://den-nekonoko.blog.so-net.ne.jp/2012-04-14
後不思議なのは
jalv2のコンパイル後のhexの渡し方と
mikrocの渡し方が違う様で、jalv2は一度見に行って失敗し、ボタン操作をしないと書き込めません。

lcdの取扱はコンパイラごとに違っていてややこしいですね。

jalv2で書くことが出来るとPROグラム容量の制限がないのが良いのですが、まだバグがある様で、熱心にバグ取りをされて居られ頭が下がります。
Posted by nekonoko at 2012年04月14日 16:17
こんばんわ
文字列とcase文の使い方は本文に追記しました。
jalv2が「jal言語本体」で、
jallibが「jalのライブラリ」プロジェクトですが
jallib側が便宜的に「jal言語本体の正式版」も
含めて配布しています。

もうすぐ出る「jal言語本体」の次期バージョン
「jal 2.4p」の動向はjalv2のURLを参照します。

HEXファイルの書き込みの件ですが、ちょっと内容が不明ですが、コンパイル時に「Warning」がでないように修正した方がよいかと思います。

jal 2.4oでは、
msg = "1/8 "
という書き方では上手く動きません。
追記した本文を参照してみてください。
Posted by audin at 2012年04月15日 00:25
こんばんは
LCD表示関数が、
const byte str2[] = "msg2";
disp_str( str2 ); /* 文字列を表示 */
の様に書くのを知りませんでした。
マニュアルはよく読んだつもりなんですが・・
lcd_cursor_position(0,0)
print_string(lcd, str1)
しか知らなかったのです。

今はjalv2で書けなかった所はmikrocで書いて試しています。これもmikroc_proではlcd表示が無茶くちゃになり、もっぱらmikrocの方ですが、
もうじき2Kを越えるのでjalv2に移らないと出来ません。

書き込みの件はmikorocではコンパイルが終わると自動的に書き込んでくれるのですが、
JALEditの方はWarningが無くても、自動的に書き込みに行ってエラーで止まり、手動で書き込むと、書けるという意味です。
Posted by nekonoko at 2012年04月15日 22:40
こんばんわ
>自動的に書き込みに行ってエラーで止まり、手動で書き込むと、書けるという意味です。

わかりました、確認してみます。
Posted by audin at 2012年04月15日 23:39
こんばんわ、
disp_str( str2 ); の部分は架空の物です。

const byte str1[] = "msg1";
lcd_cursor_position(0,0)
print_string(lcd, str1)
とすれば大丈夫だと思います。

本文は修正しておきます。
Posted by audin at 2012年04月16日 00:05
こんばんわ
pickit2の設定を本文に追記しました。
Posted by audin at 2012年04月16日 22:12
こんにちは
jalv2は難しいので、mikroCと比べながら、少しずつ移植をしています。
Posted by nekonoko at 2012年04月17日 14:58
こんばんわ、
カーソル関係は使ったことがないので調べないとよく分らないのですが、
ソフト的に実現するには少なくとも
procedure lcd_write_CGRAM_data()
では無理だと思います。
CGRAMに文字を登録するにはlcd_define()という関数が使える様です。
登録番号を、普通に文字の代わりに書き込めば表示できると思います。
登録した文字と元の文字を交互に表示すれば、
カーソル風にできなくはない気がしますが、
それなりに手間はかかる感じですかね。
それなら空白と文字を交互に表示するほうが簡単かもしれません。
Posted by audin at 2012年04月19日 00:15
こんばんは
アンダーカーソルと普通文字でここまでは出来たんですが
ttp://den-nekonoko.blog.so-net.ne.jp/2012-04-19
CGRAMまで使うべきか、適当な所でネゴッテしまうか思案中です。

CGRAMを使うとテーブルが結構要りますので、
ファンクションの設定方法を工夫して、現在の状態を
どの様にか省略(別の字を当てる)しながら、の使い方を考えてみます。

カウンタはAN592の様な抵抗縛りが無い分、楽かも知れません。

途中までの感じでは、4Kは喰いそうで、フリー版では無理のようですし、jalv2の方がコンパクトなコードを出すようです。(これ以上はアセンブラの領域でしょうか)
Posted by nekonoko at 2012年04月19日 18:10
またまた、こんばんは

lcd_define() は何度もやってみて上手く行かず
(エラーが止まらず)
始めはインクルードされる側に入れていたのを
呼び出す側に入れて、
ドットパターン定義を
const byte titled[] = "< dcha >"; -- for top line of LCD
const byte custom0d[] = {14,17,19,21,25,17,14,1}; -- upper left
にして、
lcd_define(0,custom0d); から呼び出せました。
この時 カラムは判ったのですが、行の入れ方が判りません。
if 0 != 0 then;
取りあえず、
コメント化ブロックはこれで済ませました
end if;
Posted by nekonoko at 2012年04月19日 21:46
こんばんわ、
JALPack\sample\16F に
「16f648a_lcd_hd44780_custom.jal」というサンプルがあるので
見てみてください。登録した番号を単純に文字の代わりに使います。

あと、デバウンスや周期処理に使える便利な関数があります。
JALPack\sample\16F に
「16f648a_timer0_interval.jal」というサンプルがあります。
check_delay()というライブラリ関数を使うと任意の周期のタイミング処理が
簡単にできます。(内部でtimer0を使います)
例えば、333msecと50msecと180msecのそれぞれの周期で3つのLEDを
チカチカさせつつメイン処理も実行すると言うことが簡単にできます。
このような処理を単純なdelay()関数だけでやるのは無理がある様な気がします。
(出来なくはないと思いますが)
Posted by audin at 2012年04月19日 23:22
こんにちは
情報を有り難うございます。
「16f648a_lcd_hd44780_custom.jal」
「16f648a_timer0_interval.jal」
よく読んでみますね。

「jallib-0.8.0」の「lcd_hd44780_common.jal」を元にCGRAMを試しました。

自分で作ったデバウンスはおそらくシャドーを使っているので遅いのかなと思っています(まだな用は確認していません)入力はRMW問題がないのでシャドーを使わない様にするには、アセンブラしかないのでしょうか?
Posted by nekonoko at 2012年04月20日 10:55
こんばんは
デバウンスの方が読んでは見たものの良く理解できず、
CGRAMの方をやってみました。
1カラム目を送り、2カラム目を送ったら1カラムと同じ文字しかでません、しかし記号を送るとそこだけは記号になるので、送り方を間違って考えているようです。(0+0・・・・と表示されます)
1行目から溢れた分は2行目へと繋がって表示されています。
1行目と2行目を分けて指定できるかが判っていません。
-- CGRAM定義
const byte custom0d[] = {14,17,19,21,25,17,14,1};
const byte custom1d[] = {4,12,4,4,4,4,14,1};
-- CGRAM呼び出し関数
lcd_define(0,custom0d);
lcd_define(1,custom0d);

forever loop;
lcd = 0; -- lcd_define(0,custom0d);を呼んでいるつもり。
lcd = "+";
lcd = 1; -- lcd_define(1,custom0d);を呼んでいるつもり なのに 0 が表示されてしまいます。
end loop;
-- どこか勘違いしています。

それとコメントアウトは
if false then;

end if
が使えました。

追記
CGRAMは2行モードで8キャラ分しか覚えられません、
無理に2行分を覚えさせ、その都度1行ずつ表示するとしても、前の行も交互にそれぞれのパターンでフリッカしてしまいます。

ですから、CGRAM使用を考えずに、もっと基本的な方法を考えねばならないようです。
Posted by nekonoko at 2012年04月20日 20:43
こんにちは

mikoroCでは16f628aに置き換え出来たんですが、
jalv2では小生の文法解釈が稚拙なため、3カ所ほどの置き換えが上手く行かず、
1カ所のエラー(明らかに文法が間違っていても)こちらを直したらあちらでエラーがどっさり、と進展せず、
しばらく放り出したままになっています。
C言語側
unsigned long FreqMeasurement(unsigned char gateTime)
(procedure? function? 或いは配列設定?)
freq = FreqMeasurement(gateTime);
jalv2側 (文字数を縮小しています)
case (gate_time) of -- exprが判らない

それでは宜しくお願いします。
Posted by nekonoko at 2012年04月22日 16:29
こんばんわ
143行目はコメントにします。
142行目の方がjalの関数の形をしていますので
これを有効にした方がよいです。(引数や戻り型の修正は必要です)
145行目のblockとペアになるend blockは削除します。
block文はcase文の中以外では使用しない方が良いと思います。

case文の exprですが、exprの部分に変数や式が来て、
最終的にそれらが評価された整数値になると言う意味です。
case文の使い方は、このブログの本文にあるので参考にしてください。

あと、
C言語のstatic変数はjalではグローバル変数にしないと
いけないと思います。
Posted by audin at 2012年04月24日 00:13
こんにちは
あれから作者の方にお教え頂いて、
(オリジナルを対象に書いています)
unsigned long FreqMeasurement(unsigned char gateTime)
は  gateTimeによって値を切り換えることが判り、
FreqMeasurement = FreqMeasurement * gateTime
と同じ意味かと思ってそれで進め、ノーエラーにはなったんですが、変数名 を省略したため自分でどれかと混同したままになっているので、よく調べて変数名の付け直しをやってみます。
オリジナルは3部門に分かれていて、
1.割り込み処理、
2.、unsigned long FreqMeasurement(unsigned char gateTime)
の部分、最後が return (freq); で終わっているので 周波数を求めるサブプログラムだとは思うんですが procedure、function、或いはblock にすればよいのか判断が付いていません、
3.
C言語の mainは JALV2ではなにか意味を持つのでしょうか、サブプログラムにして callしなければ 
(初期設定の様な感じ)ただの block で良さそうに思います

main の後にある while (1) { はJALV2の forever loop になると思いますが、間違っていますでしょうか?

それとまだまだ変数の理解が出来ていなくて、スコープなんかになるとblock内で再定義できるとか有るのですが意味が分かっていません。

LCDの表示関数がC言語と混同してしまって、表示に失敗、これももう一度整理し直してみます。
こんかいは「lcd_hd44780_4.jal」「print.jal」を使いますが、どうもそれ以外にもlcd表示関数があるようです。
周波数信号は実際にはまだ与えず、仮変数に書き込んで、lcd表示や、数値の確認もやってみます。

0,6秒のリフレッシュレートには端数を使うので、と言うか
周波数の計算に「math.jal」が要るはずだったんですが、インクルードしていませんでした、これも組み込んでやってみます、有る程度固まったら、またUPします。
143行目,142行目,145行目 が指す所が判らなかったので
今度は 行番の変わりに文章を特定する方法も考えてみます。

それでは宜しくお願いします。
Posted by nokonoko at 2012年04月24日 10:46
こんにちわ、
通常構文ならblock文は必要ないです。
blockの使用はcase文の中に限定します。
オリジナルのC言語ソースもblockに相当する書き方はしてないと思います。

C言語の以下の関数は、
unsigned long FreqMeasurement(unsigned char gateTime)
Jalだと、
function FreqMeasurement( byte in gateTime ) return dword is
...
return freq;
end function
になると思います。

書き方はいろいろあると思いますが、
main()+while(1)と同様に書くなら、
procedure main() is
...

end procedure
と定義して、最後に
main();
forever loop end loop
でも良いかもしれません。

スコープについてはマニュアルに書かれていない部分もあって
正確には分りませんが、「グローバル変数スコープ」と、
「関数内のローカル変数スコープ」の二つに絞った方が良いと思います。
blockを使ってスコープを作るのは返って混乱するだけなので、
使用は避けた方が良いと思います。
blockを使いたいところは、関数にすれば同様の効果が得られると思います。
Posted by audin at 2012年04月28日 13:54
こんばんは

ついこの前見つけたのですが、
format()とprint()関数で変数を表示できることが判りました。(しかも少数以下も、指定できるようです)

ttp://www.justanotherlanguage.org/content/jallib/tutorials/tutorial_print_format
それとアセンブルファイル中にはゴク最初の、変数やポート設定に所にmainが作られていました。
周波数計測は仰有るとおり、
function
return freq;
end function

永久ループwhile(1) は forever loop end loop
の様です。
今はプリスケーラ設定などをアレンジしています。

1/64外部プリスケーラでは無理ですが、内部1/8プリスケーラの場合プリスケーラに溜まっている0〜7のカウントをシステムクロックと、TMR1Lの変化から読み出せないかと思っています(切り替えや判断が難しそうです)

最後に残る大問題は、レシプロカル測定の実現と
それを切り替え移行する方法です。

特によいと思うのは、とにかくコンパクトで早いオブジェジェクトをだしてくれる事です。

ではまた。
Posted by lcdの表示関数 at 2012年04月29日 21:21
こんばんは
mikroCと同じ計数位取り機能のテストをしました。
困ったことに計数値は上の桁から下りてくる方が手っ取り早く、下から上がる様にする部は大部組まないといけないようです。
他にはマスルーチンがあったのでdwordサポートしているかと思っていたら、16ビットでした。これも移植しないと複雑な演算は無理のようです。
他には位取りの指標をif文中で文字列で入れようとするとエラーになります。
元の考え方を大部換えないといけないようです。
Posted by nekonoko at 2012年04月30日 22:47
こんばんは
表示の変化をupしました。
ttp://den-nekonoko.blog.so-net.ne.jp/2012-05-01
Posted by nekonoko at 2012年05月01日 18:53
こんばんは
表示ホーマットを換えることが出来ました。

ttp://den-nekonoko.blog.so-net.ne.jp/_images/blog/_615/den-nekonoko/sIMG_0594.jpg

ttp://den-nekonoko.blog.so-net.ne.jp/_images/blog/_615/den-nekonoko/sIMG_0614.jpg
Posted by nekonoko at 2012年05月10日 22:45
こんにちは ご無沙汰しております。

mikroCproでは 文字列配列のような形で「表示文字」を登録し、表示行を指定して 表示させると、
右詰めで表示されます。

しかしjalv2では 表示位置を
var byte line1[LCD_CHARS] = "<= 2 x 16 LCD =>"
var byte line2[LCD_CHARS] = "0123456789ABCDEF"
lcd_write_char(line1[i]) -- write using procedure
lcd_cursor_position(1,0) -- to second line
の様に左詰めを標準にしているようで、
右から書くには配列の文字数を読んで、右から読み出し、書き出し位置も計算しながら、ループを組むようにしかできないのでしょうか?

他の方法は試した割には得るところがなかったので、残念です。
これができればjalv2は無敵のように思います。
(24f以降はサポートされていませんが)

以前教えて頂いた「jalv24p」がもう出ていないかと時々探しては居ます、
ひょっとしてこの辺りが改善されていないか jalv24p
を探していまが、まだ見つけるには至っていません。

もう jalv24p はリリースされましたでしょうか?

ではまた。
Posted by nekonoko at 2012年08月28日 15:08
こんにちわ audinです。
include print
してprintライブラリを使います。
表示文字 str、LCDを16桁とすれば
表示文字数はcount(str)なので、
2行目に右詰め表示するなら
lcd_cursor_position(1, 16 - count(str) )
print_string( lcd, str)
で可能と思います。

無敵ですね。:D
Posted by audin at 2012年08月29日 07:28
こんにちは なるほど、やはり計算が必要なんですね。
lcd_cursor_position(1, 16 - count(str) )
簡単に右から記入ライブラリが作れるくらいのスキルが有れば良いんですが、無
いので苦労します。

今回はたまたま8桁2行を扱ってしまって、「,」「.」にも桁足らずで苦労します。

それでは有り難うございました。
Posted by nekonoko at 2012年08月30日 21:00
コメントを書く
お名前: [必須入力]

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。