対象は秋月電子さんのRX220ボードに載っている64pinのRX220です
/***************************************************/
/* */
/* PROJECT NAME : RX220_init */
/* FILE : RX220_init.c */
/* DESCRIPTION : Main Program */
/* RX220初期設定例:値は適宜変更する */
/* This file was generated by e2 studio. */
/* */
/***************************************************/
#include
// 存在しないpinに対応するポート(64ピン)
#define DEF_P0PDR 0x80 /* non-existent pin: P07 */
#define DEF_P1PDR 0x0C /* non-existent pin: P12, P13 */
#define DEF_P2PDR 0x3F /* non-existent pin: P20 to P25 */
#define DEF_P3PDR 0x18 /* non-existent pin: P33, P34 */
#define DEF_P4PDR 0xA0 /* non-existent pin: P45, P47 */
#define DEF_P5PDR 0x0F /* non-existent pin: P50 to P53 */
#define DEF_PAPDR 0xA4 /* non-existent pin: PA2, PA5, PA7 */
#define DEF_PBPDR 0x14 /* non-existent pin: PB2, PB4 */
#define DEF_PCPDR 0x03 /* non-existent pin: PC0, PC1 */
#define DEF_PDPDR 0xFF /* non-existent pin: PD0 to PD7 */
#define DEF_PEPDR 0xC0 /* non-existent pin: PE6, PE7 */
#define DEF_PHPDR 0x00 /* non-existent pin: none */
#define DEF_PJPDR 0x0A /* non-existent pin: PJ1, PJ3 */
void R_INIT_NonExistentPort(void){ //存在しないpinの内部ポートを出力に固定する
PORT0.PDR.BYTE = PORT0.PDR.BYTE | DEF_P0PDR;
PORT1.PDR.BYTE = PORT1.PDR.BYTE | DEF_P1PDR;
PORT2.PDR.BYTE = PORT2.PDR.BYTE | DEF_P2PDR;
PORT3.PDR.BYTE = PORT3.PDR.BYTE | DEF_P3PDR;
PORT4.PDR.BYTE = PORT4.PDR.BYTE | DEF_P4PDR;
PORT5.PDR.BYTE = PORT5.PDR.BYTE | DEF_P5PDR;
PORTA.PDR.BYTE = PORTA.PDR.BYTE | DEF_PAPDR;
PORTB.PDR.BYTE = PORTB.PDR.BYTE | DEF_PBPDR;
PORTC.PDR.BYTE = PORTC.PDR.BYTE | DEF_PCPDR;
// PORTD.PDR.BYTE = PORTD.PDR.BYTE | DEF_PDPDR;
PORTE.PDR.BYTE = PORTE.PDR.BYTE | DEF_PEPDR;
PORTH.PDR.BYTE = PORTH.PDR.BYTE | DEF_PHPDR;
PORTJ.PDR.BYTE = PORTJ.PDR.BYTE | DEF_PJPDR;
}
void pullup(void){ //未使用端子プルアップ P3-6,7に注意
PORT0.PCR.BYTE = 0x28;
PORT1.PCR.BYTE = 0xf0;
PORT2.PCR.BYTE = 0xc0;
PORT3.PCR.BYTE = 0x27; //00100111
/*
PORT3.PCR.BIT.B0 == 1; //RXD1
PORT3.PCR.BIT.B1 == 1;
PORT3.PCR.BIT.B2 == 1;
PORT3.PCR.BIT.B5 == 1; //NMI
// PORT3.PCR.BIT.B6 == 0; //Clock:EXTAL
// PORT3.PCR.BIT.B7 == 0; //Clock:XTAL
*/
PORT4.PCR.BYTE = 0x58; //01011000:0-2 AD入力
PORT5.PCR.BYTE = 0x30;
PORTA.PCR.BYTE = 0x5b;
PORTB.PCR.BYTE = 0xeb;
PORTC.PCR.BYTE = 0xfc;
PORTE.PCR.BYTE = 0x3f;
}
void init_adc(){
//Port設定
PORT4.PMR.BYTE = 0x07; //Port40,41,42を周辺機能とする
PORT4.PDR.BYTE = 0x00; //入力端子
SYSTEM.PRCR.WORD = 0xa50b; //プロテクトの解除
SYSTEM.MSTPCRA.BIT.MSTPA17 = 0; //S12ADモジュールを有効化:AD変換可能
SYSTEM.PRCR.WORD = 0xa500; //変更不可に戻す
S12AD.ADCSR.BIT.ADCS = 0x2; //連続スキャンモード
S12AD.ADANSA.WORD = 0x0007; //AN000-003を有効にする
S12AD.ADSSTR0 = 0xFF; //サンプリング時間255ADCLKクロック(=10us,多分)
S12AD.ADCSR.BIT.ADST = 0x1; //AD変換スタート
}
void MTUset(void){
// PWM波形を出力する。それぞれのチャンネルに対し、TGRAにパルス周期・TGRDにパルス幅をセットする。
// 周期とは不同期にTGRDを書き換えると次のカウントアップ時にパルス幅が新しい値に書き換わる。
// MTUの起動設定
SYSTEM.PRCR.WORD = 0xa50b; //プロテクトの解除 変更可能にする
SYSTEM.MSTPCRA.BIT.MSTPA9 = 0; //ユニット1起動
// Ch0の設定
PORTB.PMR.BIT.B3 = 1; //PB3端子を周辺機器端子として使用する
MPC.PB3PFS.BIT.PSEL = 1; //PB3端子をMTIOC0Aに割り当てる
MTU0.TCR.BIT.TPSC = 0; //周辺モジュールクロックの1分周
MTU0.TCR.BIT.CKEG = 0; //立ち上がりエッジ
MTU0.TCR.BIT.CCLR = 1; //TGRAのコンペアマッチでTCNTクリア
MTU0.TMDR.BIT.MD = 0x02; // PWMモード1で動作
MTU0.TMDR.BIT.BFB = 1; //TGRAとTGRCはバッファ動作
MTU0.TIORH.BIT.IOA = 6; //0110 H-H
MTU0.TIORH.BIT.IOB = 5; //0101 H-L
MTU0.TGRA = CYCLETIME; //cycletime 1msec
MTU0.TBTM.BIT.TTSB = 1; //TGRC->A の転送タイミング TCNTクリア時
MTU.TSTR.BIT.CST0 = 1; //カウントスタート
// Ch3の設定
PORT1.PMR.BIT.B4 = 1; //P14端子を周辺機器端子として使用す
MPC.P14PFS.BIT.PSEL = 1; //P14端子をMTIOC3Aに割り当てる
MTU3.TCR.BIT.TPSC = 0; //周辺モジュールクロックの1分周
MTU3.TCR.BIT.CKEG = 0; //立ち上がりエッジ
MTU3.TCR.BIT.CCLR = 1; //TGRAのコンペアマッチでTCNTクリア
MTU3.TMDR.BIT.MD = 0x02; // PWMモード1で動作
MTU3.TMDR.BIT.BFB = 1; //TGRAとTGRCはバッファ動作
MTU3.TIORH.BIT.IOA = 6; //0110 H-H
MTU3.TIORH.BIT.IOB = 5; //0101 H-L
MTU3.TGRA = CYCLETIME; //cycletime 1msec
// MTU3.TGRD = width; //width Min0.5msec Max1.5msec
MTU3.TBTM.BIT.TTSB = 1; //TGRC->A の転送タイミング TCNTクリア時
MTU.TSTR.BIT.CST3 = 1; //カウントスタート
SYSTEM.PRCR.WORD = 0xa500; //変更禁止に戻す
}
/*
********************************************************************************
RX220はコールドスタート時のクロックが125KHzに設定されている。
通常動作のクロックに切り替えるには操作が必要になる。
メイン外部発振端子XTAL及びEXTALは機能切り替えでPORT3-6、PORT3-7と排他的に使用する。(端子数が足りないので重畳されている)
メイン外部発振を使用するとPORT3-6,7は使用できない。(内臓発振器を使用可能)
秋月のボードではPORT3-6,7は外部に結線されていない。発振専用になっている。
RX621ではコールドスタートで通常クロックになり、外部発振端子は専用なのでこの操作は不要(内部発振器は存在しない)
*/
void clockset(void){
SYSTEM.PRCR.WORD = 0xa50b; //システムプロテクト解除(クロックを選択可能にする)
SYSTEM.SCKCR.BIT.PCKB = 0x01; //周辺モジュールのクロックはシステムクロックの2分周とにする
SYSTEM.SCKCR.BIT.ICK = 0x00; //システムクロックはデフォルト設定:1分周とする
SYSTEM.MOSCCR.BYTE = 0; //メインクロック発振器動作
SYSTEM.SOSCCR.BYTE = 0; //サブクロック発振器動作
SYSTEM.SCKCR3.WORD = 0x0200; //大元のクロックにメインクロックを使用する。
// 内臓発振器を使用する場合
// SYSTEM.SCKCR3.BIT.CKSEL=1; //HOCOをクロックソースに設定
// SYSTEM.HOCOCR.BIT.HCSTP = 0; //HOCO動作
// SYSTEM.HOCOCR2.BIT.HCFRQ = 0; //HOCOのク ロック選択 0**32MHz
SYSTEM.PRCR.WORD = 0xa500; //システムプロテクト設定(クロックを変更不可にする)
}
void enable_functionselect(void){ // 端子機能選択許可
MPC.PWPR.BIT.B0WI = 0; //PWPR.PFSWEライトプロテクト解除
MPC.PWPR.BIT.PFSWE = 1; //上記と組み合わせ端子機能選択可能にする。
}
void disable_functionselect(void){ //端子機能選択禁止
MPC.PWPR.BIT.B0WI = 1; //PWPR.PFSWEライトプロテクト設定
MPC.PWPR.BIT.PFSWE = 0; //上記と組み合わせ端子機能選択禁止にする。
}
//******************************************************************************
// ここからメインルーチン
int main(void) {
// 初期設定
//__builtin_rx_clrpsw('I'); //割り込み受付禁止
clockset();
enable_functionselect(); // 端子機能選択許可
init_adc(); //ADC start
MTUset(); //PWM開始
pullup(); //未使用入力端子をプルアップする
disable_functionselect(); // 端子機能選択禁止
// 初期設定終了
//__builtin_rx_setpsw('I');CPU割り込み受付許可
R_INIT_NonExistentPort(); //出力pinが存在しないポートの設定
while(1){
***** ここに実作業のプログラムを記載する *****
}
return 0;
}
| 1 |
クロック設定は clockset(); で行います。 起動時のクロックは125KHzと超低速に設定されていますので変更しないとまともに動きません。設定変更レジスタは書き換え禁止されていますので初めに書き換え許可を行います。 システムクロックとしてHOCO(内部発振器)を使うかメインクロック(外部の水晶発振子)の選択起動や、サブクロック(カレンダー時計に使う)を必要に応じて設定します。 内部発振は最大1%の誤差があるようです。(ハードウェアマニュアル参照) 私の用途においてこの誤差は全く問題ありませんので内部発振で十分ですが秋月さんのボードではメインクロック及び サブクロックの水晶発振子が両方とも組み込まれております。メインクロック発振器はPORT3の6及び7と兼用ですのでP3-6、P3-7は使用できません。 |
| 2 |
不使用端子の処理 void R_INIT_NonExistentPort(void);は、100pinパッケージのRX220ではすべての機能が外部に出されていますが 秋月さんのボードに採用されている64pinパッケージでは内部半導体のチップ上には存在するが外部には結線されていない機能pinがあります。 この機能が悪影響を及ぼさないようにする処理です。多分RX621では不要だったと思います。 |
| 3 |
void init_adc();void MTUset(void); どちらもCPUではなくて周辺機能の初期設定です。void init_adc();はA/Dコンバータ00~03の4チャンネルスキャンするモードで起動します。 結果は”A/D データレジスタ y( ADDRy)( y = 0 ~ 3)”に入ります。(私の用途では全16チャンネル使用することはありませんので4チャンネル使用する設定です) 起動すると停止せずにデータレジスタは次々に更新されます。起動したままデータを読み出すこともできますし必要に応じ起動停止を繰り返す事もできます。 割り込み要求は禁止ですので必要に応じADCSR.ADIEビットを1にして下さい。 |
/__builtin_rx_clrpsw('I');
この記述はGccコンパイラでのCPU割り込み受付禁止です。割り込みにより処理を妨げられたくない時設定します。 Gccで生成されるスタートアップルーチン内で、C言語でのプログラムが実行される以前に、割り込み許可されます。__builtin_rx_setpsw('I');
この記述はGccでのCPU割り込み受付許可です。 割り込み処理を行うプログラムを組んだ場合に割り込みルーチンに移動する許可を与えるために必要です。 Gccではスタートアップルーチンで許可されていますので禁止していなければ許可状態が続きます。多重割り込みについて
割り込みルーチンに入ると自動的に割込み禁止されます。この割り込みルーチンを抜けると(メインルーチンに戻ると)再び自動的に割り込み許可になります。 もし割り込みAの途中で別の割り込みBを受け付けたい場合はAに入ってから割り込み許可(__builtin_rx_setpsw('I');を呼び出す)にします。
その場合でも、割り込みには優先順位を、割り込みAよりも割り込みBの優先度を高く設定しておく必要があります。
Port3の6,7について
P3-6,7はメインクロック発振(外部)で使用します。迂闊にアクセスすると発振停止しますので十分注意が必要です。 秋月さんの基板にはメインクロック用水晶20MHzの載っていて、発信専用に結線されており外部端子(CN1,2)には接続されていません。 従って、水晶を外してもP3-6,7は使用できません。Copyright © 面白半分