2018/08/16
RL78関係の記事はこちらに移動しました。
下記ページは今後更新しません。
2016/10/24
CC-RLでの開発開始時の設定 無償評価版はここからDL
CS+のパラメータなどの設定情報。
なおCC-RLではポートのBITの触り方が変わった。またiodefine.hがソースとして出てくるようになった。
P7_bit.no6 = 1; // P76 Out
既に設定変更済みのPRJを持っている場合はインポートすればOK。 真っさらから始める場合は下の方の設定を変更する。 |
|
![]() |
|
CREFを使用するに変更、これをしないとソースモードでのstataic関数への関数ジャンプ(F12)が出来ない。 最適化はデバッグ優先に変更、これでデバッグ時の変数や動作を追いやすくなる。 |
|
![]() |
|
コメントのネストは自分には必須。 | |
![]() |
|
WDTはコード生成では「使用する」に設定しておき、オプションバイトで停止してる(先にコード生成してから変更する)。理由 ROMとRAMの使用量を表示させてる(ビルド終了時にメッセージ欄に出てくる)。 |
|
![]() |
|
デバッグを指定の関数から始めるためにはここを変更する(関数名の先頭には '_' アンダースコアが必要だ)。 宣言してあっても実際にコールしてない関数名を書いちゃうと、いきなりゼロ番地に飛んだりするので要注意。 |
|
![]() |
2016/10/23
PWMしてみた
RL78ではPWMをするときにタイマを最低でも二つ使う。
一つはマスターと呼び、こいつはPWM周波数を決める。
もう一つはスレーブと呼び、こいつはPWMのデューティーを決める。
スレーブは複数有っても構わなくて、複数有れば複数のデューティーのPWMを同時に出力可能だ(マスターは一個だけなので周波数は同じになる)。
今回はマスター一個にスレーブ二個で試した。つまりタイマを3個使う。
マスター:TAU1のチャンネル0
スレーブ:TAU1のチャンネル1と2
コード生成でこんな感じで設定した(スレーブのチャンネル2はデューティーを10%にしてる)。
割込みは使わないけど、実験用に発生させることにした。
![]() |
んで端子配置表へ反映させると、TO11とTO12が端子配置される。
更にコード生成させると”R_TAU1_Create()"にそれなりのコードが出力される。
このコードの中で大事なのはデューティーを決めるレジスタとその値だ。
なんとなくわざとらしい数値がある(0640と0140)んで、これをいじってデューティーが変わるか調べれば良い。
![]() |
今回はスレーブのチャンネル1だけを調べてるんで、オシロをTO11(P30)に接続しておく。
コードはこんな感じで作ってみた。
デューティーは50%で0x640だから100%なら二倍の0xC80だろうってことで(コード生成時に100%にすれば計算するまでもなかった)。
ステップ実行するとオシロに表示される波形の幅が変化する。
RL78のハードウエアマニュアルを読むのが面倒くさい自分には、コード生成は確かに便利だわ。
//================================================================================================ // TO11/12 16ビット・タイマ出力(モーターPWM) //================================================================================================ void To11Main(void) { To11Duty(80); // duty 80% R_TAU1_Channel0_Start(); To11Duty(10); // duty 10% R_TAU1_Channel0_Stop(); } // PWMのduty設定:duty比 0〜100(%) void To11Duty(uint8_t d) { if (d >= 100) TDR11 = 0x0C80U; // 100%=0x0C80U, 50%=0x0640U else TDR11 = (0x0C80U / 100U) * d; } void To10Intr(void){ NOP(); } // PWMマスター10INTR void To11Intr(void){ NOP(); } // PWMスレーブ11INTR // TO12 16ビット・タイマ12出力(予備PWM出力) void To12Main(void) { TDR12 = 0x0C80U; // duty 100% R_TAU1_Channel0_Start(); TDR12 = 0x0640U; // duty 50% TDR12 = 0x0U; // duty 0% R_TAU1_Channel0_Stop(); } void To12Intr(void){ NOP(); } // PWMスレーブ12INTR |
2016/10/23
SPIのスレーブ ルネサスサンプル
SPIのマスターは簡単だけど、スレーブってどうやるんだろ?
今のところ思いついてる方法をメモ。
※SPIのDMA転送は面倒くさいらしいからやめた方が良いようだ。
SPIってのは要するにシフトレジスタでシリパラ変換してるんだよね?
だとしたらシリパラ変換の完了割込み(シリパラINTRと略)で、シフトレジスタからデータをINしてバッファに蓄えれば良いんじゃない。
ただしソフトで動かすからハンドシェークが必要だ。
<スレーブ受信の第一案>
1:シリパラINTRが発生したらCSがenableであることを確認。
2:buf[cnt++]にデータをセットする。
ただこの方法だとCSがdisableの時にもシリパラINTRが発生するんで余りよろしくないかも。
<スレーブ受信の第二案>
1:CSがenableになったら割込みを発生させ、その中でシリパラINTRの発生を許可する(マスター側は少し待つ必要有り)。
2:シリパラINTRが発生したら無条件にbuf[cnt++]にデータをセットする。
3:CSがdisableになったら割込みを発生させ、その中でシリパラINTRの発生を禁止する。
これかな?
CSの上下両エッヂでの割込みを使えば一番良い感じかも。
この方法ならUART受信みたいに、勝手に裏で受信できるから良さそうだ。
送信はどうやるか。
マスターからのクロックはいつ来るか分からないのだから・・・
<スレーブ送信の第一案>
1:パラシリレジスタに予めデータをセットしておく。
2:マスターに送信準備完了の合図を適当なポートで示す。
3:パラシリ変換完了INTRで次のデータをパラシリレジスタにセット。
こうか?
いずれ実験してみよう。
2016/10/29
ILI9341+グラフィックLCD 参考HP1 参考HP2 データシート
グラフィックLCDを使うことになった。
LCDを直接操作するわけじゃなくて、コントローラICのILI9341(ILI9340でも動くと思う)のいじり方。
・RL78と9341は16bitのパラレルで接続してる。
・リセットはハード的に発生してる。
ってことで、あちこちググり回って見付けたのが上記の参考HP。
とても分かりやすく、更にソースも載せてくれてるんでいたって簡単に完成した。有り難うございます。
ところでどのHPもCPUと9341をSPIで接続してる。
今回は16bitパラレル接続(P7/8)なんで、IO部分だけを修正すれば動くはずと目星を付けて作ったのがこれ。
要するにSPIで出力してるのをポート出力に変更しただけ。
IM0〜3を0001にセットすることで16bitバスになる(9341マニュアルより抜粋)。 またレジスタへのアクセスは8bit幅だけど、GRAMは16bit幅でアクセスすることが読み取れる。 ![]() CMDを書くときはDCX=L、DATAを書くときはDCX=Hにしておいて、WRXで↑エッジを出してやる。 ![]() GRAMに上位8bitゼロで書き込むと赤だけ表示されなかった(CPUボードは北斗電子製)。 この後で16bitで書き込んだら赤も表示されたから、上位側が赤なんだろな。 ![]() |
// // lcd.c ILI9341+4DLCD-28QA 2016/10/15 // http://imagewriteriij.blogspot.jp/2014/01/raspberry-pi-9-lcd-1.html // http://nopnop2002.webcrow.jp/TFT/ILI9340-1.html // #include "r_cg_macrodriver.h" #include "iodefine.h" #include "r_cg_userdefine.h" // LCD Ports define #define LCD_BKL P3_bit.no1 // BackLight #define LCD_CSX P6_bit.no5 // CSX #define LCD_DCX P6_bit.no4 // DCX #define LCD_WRX P6_bit.no7 // WRX #define LCD_RDX P6_bit.no6 // RDX // Prototype static void lcd_test(uint16_t r, uint16_t g, uint16_t b); static void clear(uint16_t r, uint16_t g, uint16_t b); static void colorbar(void); static void write_dc(uint8_t dc, uint8_t c); static void write_dc_w(uint16_t w); static void write_dc_w16(uint16_t w); static void lcd_init(void); static void addset(uint16_t x, uint16_t y); static uint16_t rgb565_conv(uint16_t r, uint16_t g, uint16_t b); //================================================================================================ // LCD main //================================================================================================ void LcdMain(void) { /* 手動でリセットするなら・・・ LCD_CSX = 0; // CS=L(これは要らないかも) LCD_DCX = 1; // D/C = H RESET = 0; // Reset = L delay1ms(100); // delay 100ms RESET = 1; // Reset = 1 delay1ms(100); // delay 100ms */ LCD_BKL = 1; // バックライトON LCD_CSX = 0; // CS=L lcd_init(); lcd_test(0, 255, 255); lcd_test(255, 255, 0); lcd_test(255, 0, 255); LCD_CSX = 1; // CS=H LCD_BKL = 0; // バックライトOFF } // デバッグ用のLCD表示 void lcd_test(uint16_t r, uint16_t g, uint16_t b) { clear(r, g, b); colorbar(); } // lcd initial static void lcd_init(void) { LCD_WRX = 1; LCD_RDX = 1; delay1ms(25); write_dc(0,0xC0); //Power control write_dc(1,0x23); write_dc(0,0xC1); //Power control write_dc(1,0x10); write_dc(0,0xC5); //VCM control write_dc(1,0x3e); write_dc(1,0x28); write_dc(0,0xC7); //VCM control2 write_dc(1,0x86); write_dc(0,0x36); // Memory Access Control write_dc(1,0x48); write_dc(0,0x3A); write_dc(1,0x55); write_dc(0,0xB1); write_dc(1,0x00); write_dc(1,0x18); write_dc(0,0xB6); // Display Function Control write_dc(1,0x08); write_dc(1,0x82); write_dc(1,0x27); write_dc(0,0xF2); // 3Gamma Function Disable write_dc(1,0x00); write_dc(0,0x26); //Gamma curve selected write_dc(1,0x01); write_dc(0,0xE0); //Set Gamma write_dc(1,0x0F); write_dc(1,0x31); write_dc(1,0x2B); write_dc(1,0x0C); write_dc(1,0x0E); write_dc(1,0x08); write_dc(1,0x4E); write_dc(1,0xF1); write_dc(1,0x37); write_dc(1,0x07); write_dc(1,0x10); write_dc(1,0x03); write_dc(1,0x0E); write_dc(1,0x09); write_dc(1,0x00); write_dc(0,0XE1); //Set Gamma write_dc(1,0x00); write_dc(1,0x0E); write_dc(1,0x14); write_dc(1,0x03); write_dc(1,0x11); write_dc(1,0x07); write_dc(1,0x31); write_dc(1,0xC1); write_dc(1,0x48); write_dc(1,0x08); write_dc(1,0x0F); write_dc(1,0x0C); write_dc(1,0x31); write_dc(1,0x36); write_dc(1,0x0F); write_dc(0,0x11); //Exit Sleep delay1ms(120); write_dc(0,0x29); //Display on write_dc(0,0x2c); //Memory Write } // clear static void clear(uint16_t r, uint16_t g, uint16_t b) { int i,j; for (i=0;i<240;i++) { // x = 0 to 239 for(j=0;j<320;j++) { // y = 0 to 319 addset(i,j); write_dc_w16(rgb565_conv(r, g, b)); } } } // write color bar static void colorbar(void) { int i,j; for(i=0;i<240;i++){ // x = 0 to 239 for(j=0;j<320;j++){ // y = 0 to 319 if(j<106) { addset(i,j); write_dc_w16(rgb565_conv(255,0,0)); //red } else if(j<212) { addset(i,j); write_dc_w16(rgb565_conv(0,255,0)); //green } else { addset(i,j); write_dc_w16(rgb565_conv(0,0,255)); //blue } } } } // set address static void addset(uint16_t x, uint16_t y) { write_dc(0,0x2A); // set column(x) address write_dc_w(x); write_dc_w(x); write_dc(0,0x2B); // set Page(y) address write_dc_w(y); write_dc_w(y); write_dc(0,0x2C); // Memory Write } // RGB565 conversion // RGB565 is R(5)+G(6)+B(5)=16bit color format. // Bit image "RRRRRGGGGGGBBBBB" static uint16_t rgb565_conv(uint16_t r,uint16_t g,uint16_t b) { uint16_t RR,GG,BB; RR = (r * 31 / 255) << 11; GG = (g * 63 / 255) << 5; BB = (b * 31 / 255); return(RR | GG | BB); } // Write data/command static void write_dc(uint8_t dc, uint8_t c) { LCD_DCX = dc; // 0=command, 1=data P7 = c; // 下位8bitのみ(上位8bitはdont care) LCD_WRX = 0; // WR out NOP(); LCD_WRX = 1; } // Write data word static void write_dc_w(uint16_t w) { uint8_t hi,lo; hi = (uint8_t)(w >> 8); lo = (uint8_t)(w & 0x00FF); write_dc(1,hi); write_dc(1,lo); } // Write data word by 16bit static void write_dc_w16(uint16_t w) { uint8_t hi,lo; hi = (uint8_t)(w >> 8); lo = (uint8_t)(w & 0x00FF); LCD_DCX = 1; // 1=data P8 = hi; // 上位8bit P7 = lo; // 下位8bit LCD_WRX = 0; // WR out NOP(); LCD_WRX = 1; } |
2016/11/09
この関数のコール元はどこ?
コールスタックの表示方法を見付けた。デバッガマニュアルP98
![]() |
”E1202855 起動時にフラッシュROMを消去しろ”が出た
デバッグしようとすると「E1202855の”起動時にフラッシュROMを消去しろ”」が出る。
いくら消去しても何度も出る。
原因はプロジェクトを取り違えてデバッグしてた(CPUを間違えてた)。
「CPUの選択を間違えてるよ」とは出てくれないんだなこれが。
RFPだとシグネチャーエラーとか出るけど、CS+では出ない・・・CPUの型番チェックをしてない?
この手の統一性の無さはユーザーに不親切じゃん ← なんだかんだ文句をたれながらCS+を有り難く使ってるやつ(^^;
ちなみに本当にフラッシュを消去してからデバッグするなら、”起動時にフラッシュROMを消去する”を”はい”にするんだそうだ。
![]() |
かなり便利なスマート・マニュアル
CS+V6で追加された機能。
コード生成で自動生成されたコードを確認・改造する時にチョー便利。
マウスをレジスタ名に持って行くとマニュアルの該当ページが表示される(自分の場合はフローティングにしてサブディスプレイに表示してる)。
いちいちPDFのマニュアルを検索して開く必要が無い。
おお〜これは便利。日本語マニュアルだし、ルネサスも最近は大分良いな〜
![]() |