ReactとかTypeScriptとかでアプリとかを作っているうちに 前に買ったとき95円だったお気に入りのSTM32L010F4P6が200円になっていた。
円安のせいだろうが、ここで文句を言ってもどうしようもないので 国産のたぶん熊本産のルネサスエレクトロニクス製 秋月電子価格110円マイコンRL78/G10ファミリR5F10Y16ASP を使ってみる。
RL78-S1コア8ビット・シングルチップ・マイクロコントローラの世界にウェブフロントエンドから戻ってまいりました。
書き込み回路を用意 ブレッドボードに挿すので120円のR5F10Y16ASP使用 RL78マイコンモジュール の方を選ぶ。 このマイコンにRenesas Flash Programmerを使ってシリアル書込みでプログラミングするのでルネサスのドキュメントを参考にして書き込み回路を作る。
ドキュメント名:『Renesas Flash Programmer PCのシリアルポートを使用した書き込み回路例』
ドキュメント番号:R20UT0857JJ0300
https://ja-support.renesas.com/knowledgeBase/17793793
秋月電子でこれらを買って書き込み器を作る。
買ってみた後で気づいたが、このページ によるともっと単純になるようだ。
シリアル変換器からRTS信号が出てないのでDTRにインバーター回路を接続した。きちんと動く
RL78マイコンモジュールと書き込み回路を接続 接続回路はこのように GND, VDD, TOOL0, RESETを接続する。
R5F10Y16ASP使用 RL78マイコンモジュール
回路図を参照して、ポートP00つまり6番ピンにLチカ用LEDをシンク接続する。(ソース接続でも構わないが)
Renesas Flash Programmer Renesas Flash Programmerを起動して「新しいプロジェクトの作成」を選択。
ツール詳細 -> リセット設定 リセット信号をDTRにする。 (デフォルトでInvertなのでインバーター回路が不要だった)
接続をクリックすると「操作が成功しました。」となる。
Device: RL78と表示されているのでマイコンと会話できている。 Renesas Flash ProgrammerによってRL78マイコンに書き込めるようになった。
e2 studioで新規プロジェクトを作る。 ファイル -> 新規 -> Renesas C/C++ Project -> Renesas RL78
LLVM for Renesas RL78 C/C++ Executable Project
プロジェクト名
ターゲットデバイスはR5F10Y16を選択
Hardware Debug構成はエミュレーターを持っていないのでチェックを外す。
スマート・コンフィギュレータが選択できないのだが。。。
この後は「次へ」を連続でクリックして新規プロジェクトを作る。
Lチカソフトウェアを作る スマート・コンフィギュレータが使えないようなので、
RL78/G10 ユーザーズマニュアル ハードウェア編を参照して手作業でレジスタ設定をする。
LEDを接続しているP00はリセット直後は入力モード。
P00のポート機能を制御するレジスタはPM00
ポートモードレジスタ0(PM0)を設定してP00を出力に設定。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/***************************************************************/
/* */
/* PROJECT NAME : RL78_blink */
/* FILE : RL78_blink.c */
/* DESCRIPTION : Main Program */
/* */
/* This file was generated by e2 studio. */
/* */
/***************************************************************/
#include "iodefine.h"
#include "iodefine_ext.h"
#include <stdbool.h>
int main() {
// IOポート
PM0 &= ~(0x1FU); // P00-P04 を出力に設定
while(true) {
P0_bit.no0 = 0; // P00 をクリア
P0_bit.no0 = 1; // P00 をセット
}
return 0;
}
ビルド プロジェクト -> すべてビルドをする。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Extracting support files...
15:22:38 **** プロジェクト RL78_blink に対する構成 Debug の ビルド ****
make -r -j16 all
Building file: ../src/RL78_blink.c
Building file: ../generate/hwinit.c
Building file: ../generate/inthandler.c
../src/RL78_blink.c
../generate/hwinit.c
Building file: ../generate/start.S
../generate/inthandler.c
Building file: ../generate/vects.c
../generate/start.S
../generate/vects.c
Building target: RL78_blink.elf
llvm-objcopy "RL78_blink.elf" -O srec "RL78_blink.srec"
llvm-size --format=berkeley "RL78_blink.elf"
text data bss dec hex filename
252 128 32 412 19c RL78_blink.elf
15:22:39 Build Finished. 0 errors, 0 warnings. (took 257ms)
「構成 Debug」なのでDebugディレクトリ内のRL78_blink.srecファイルがRenesas Flash Programmerで書き込むファイル。
Renesas Flash Programmerによるプログラミング RL78_blink.srecファイルを選択して「スタート」をクリックすると書き込める。
RESETピンにつながる線を抜くとプログラムが実行されてLEDが点灯する。 (このソフトウェアでは点滅が早すぎて点灯に見える。)
RESETボタンを追加する 実行するのに毎回RESET線を抜くのが面倒なので、RESET端子を1k抵抗でプルアップしてRESET線とRESET端子間にタクトスイッチを追加する。 このタクトスイッチは書き込み時に書込みが完了するまで押し続ける。
Lチカが見えるように遅くする LEDの点滅が早すぎて点灯にしか見えないので、ループでnopを実行する(つまり「なにもしない」を実行する)ことで点滅を遅くする。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/***************************************************************/
/* */
/* PROJECT NAME : RL78_blink */
/* FILE : RL78_blink.c */
/* DESCRIPTION : Main Program */
/* */
/* This file was generated by e2 studio. */
/* */
/***************************************************************/
#include "iodefine.h"
#include "iodefine_ext.h"
#include <stdbool.h>
#include <stdint.h>
static void __near toggle_pin(){
P0_bit.no0 ^= 1U; // P00 出力を反転
}
int main() {
// IOポート
PM0 &= ~(0x1FU); // P00-P04 を出力に設定
P0_bit.no0 = 0; // P00 をクリア
while(true) {
for(uint16_t counter=50000U ; counter>0 ; --counter) {
NOP();
}
toggle_pin();
}
return 0;
}
プロジェクト -> すべてビルドをする。 タクトスイッチを押し続けながらRenesas Flash Programmerの「スタート」をクリックしてRL78マイコンにソフトウェアをプログラミングする。
実行 書込み完了後にタクトスイッチを離すことでプログラムを実行する。blink
インターバルタイマーを使ってLチカ 続けてインターバルタイマー割り込みを使ってLチカしてみる。
タイマー0を使ってINTTIM00割り込みでLチカしてみる。
インターバルタイマーの操作手順はマニュアルを参照する。
リンクエラーになるので generate/inthandler.c の void INT_TM00 (void) { }
の部分をコメントアウトする。
1
2
3
4
/*
* INT_TM00 (0x12)
*/
//void INT_TM00 (void) { }
で、こう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/***************************************************************/
/* */
/* PROJECT NAME : RL78_blink */
/* FILE : RL78_blink.c */
/* DESCRIPTION : Main Program */
/* */
/* This file was generated by e2 studio. */
/* */
/***************************************************************/
#include "iodefine.h"
#include "iodefine_ext.h"
#include <stdbool.h>
#include <stdint.h>
#include "interrupt_handlers.h"
/*
* INT_TM00 (0x12)
*/
void INT_TM00 (void) {
P0_bit.no0 ^= 1U; // P00出力を反転
}
int main() {
// クロック設定
HOCODIV = 0x01U ; // 高速オンチップオシレータ―クロック 20 MHz
// 周辺ハードウェアに供給するクロック
PER0 |= 1U; // TAU0EN タイマアレイユニットにクロックを供給
// タイマアレイユニット
TPS0 = 0x08U; // 20MHzクロック, プリスケーラ 1/256 = 78.1kHz = 12.8us
// INTTM0nの発生周期=カウントクロックの周期×(TDR0nの設定値+1)
// 12.8us * (39061+1) = 500ms
const uint16_t timer_count = 39061;
// タイマアレイユニット
TT0 = 1U; // チャネル0カウント停止
// インターバルタイマ設定
TMR00H = 0x00;
TMR00L = 0x00;
// カウント値設定
TDR00H = timer_count >> 8 & 0xFF;
TDR00L = timer_count & 0xFF;
//
MK0L &= ~(1 << 7); // タイマー0割り込み許可
TS0 = 1U; // タイマー開始
//
EI(); // 割り込み許可
// IOポート
PM0 &= ~0x1F; // P00-P04 を出力に設定
PMC0 &= ~0x1E; // P01-P04はアナログ入力が可能なポートなので
// デジタル入出力に設定
P0_bit.no0 = 0; // P00 をクリア
// メインループは何もしない
while(true) {}
return 0;
}
インターバルタイマー割り込みの発生周期はマニュアルに書いてある。
実行してポートP00をオシロスコープで見てみると、だいたい計算通り500msで割り込みされている。
CC-RL無償評価版を使ってみる。 https://www.google.com/search?q=R20TS0898JJ0100
V1.12.00以降のCC-RL無償評価版のライセンスが「製品開発・商用利用」が許可に変更されていたので、使ってみる。
ファイル -> 新規 -> Renesas C/C++ Project -> Renesas RL78
Renesas CC-RL C/C++ Executable Project
プロジェクト名
ツールチェーンはRenesas CC-RL v.1.12.01 ターゲットデバイスはR5F10Y16を選択
Use周辺コード生成
「次へ」をクリックして新規プロジェクトを作る。
コード生成 端子割り当て設定は変更せずに確定。
コード生成 > 周辺機能 > ポート機能 > Port0 P00 を出力で設定する。
「コードを生成する」をクリックする。
src/cg_src/r_cg_main.c ファイルのmain関数内にある Start user code から End user codeに囲まれた部分にLチカコードをかく。
1
2
3
4
5
6
7
8
9
/* Start user code. Do not edit comment generated here */
while (1U)
{
for(uint16_t counter=50000U ; counter>0 ; --counter) {
NOP();
}
P0_bit.no0 ^= 1U; // P00 出力を反転
}
/* End user code. Do not edit comment generated here */
赤線が出るので言語規格をC99規格にしておく。
ビルド 出力ファイル形式を「モトローラ・Sタイプファイルを出力する」を選択してビルドする。
Debugフォルダ内に mot ファイルが出来上がる。
このファイルをRenesas Flash Programmerでマイコンに書き込むと LLVMツールチェーンでビルドしたソフトウェアと同じくLEDが点滅する。
コード生成を使ってインターバルタイマー CC-RLコード生成を使ってインターバルタイマー割り込みのLチカをしてみる。
コード生成 > タイマアレイユニット > チャネル0 > 周辺機能 チャネル0 : 「インターバルタイマ」を選択
インターバル時間 500 ms
「コードを生成する」をクリックする。
src/cg_src/r_cg_tau_user.c ファイルのr_tau0_channel0_interrupt関数内にある Start user code から End user codeに囲まれた部分にLチカコードをかく。 (コピペするならStart user code から End user codeに囲まれた部分のみ)
1
2
3
4
5
6
static void __near r_tau0_channel0_interrupt(void)
{
/* Start user code. Do not edit comment generated here */
P0_bit.no0 ^= 1U; // P00 出力を反転
/* End user code. Do not edit comment generated here */
}
src/cg_src/r_cg_main.c ファイルのmain関数内にある Start user code から End user codeに囲まれた部分にコードをかく。 タイマー割り込みでLチカするので、このメインループは何もしない。 (コピペするならStart user code から End user codeに囲まれた部分のみ)
1
2
3
4
5
6
7
8
9
10
void main(void)
{
R_MAIN_UserInit();
/* Start user code. Do not edit comment generated here */
while (1U)
{
NOP();
}
/* End user code. Do not edit comment generated here */
}
同じファイルのR_MAIN_UserInit関数内にある Start user code から End user codeに囲まれた部分に初期化コードをかく。 (コピペするならStart user code から End user codeに囲まれた部分のみ)
1
2
3
4
5
6
7
static void R_MAIN_UserInit(void)
{
/* Start user code. Do not edit comment generated here */
R_TAU0_Channel0_Start();
EI();
/* End user code. Do not edit comment generated here */
}
ビルドしてできたmotファイルをRenesas Flash Programmerでマイコンに書き込むと LLVMツールチェーンでビルドしたソフトウェアと同じくLEDが点滅する。
なぜか周期が安定しない。(LEDを見ていても感じる。) まあいいか。