初めまして、クロレッツと申します。
今年の秋ごろからRX210を独学で勉強している者です。
現在、RX210(R5F5210BBDFP)のRTCを使って1時間ごとにLEDを反転させる。といったプログラムを組みたいと思っています。
インターネットでRX210のマニュアルや、色々な方の記事を参考にさせていただきながら、
確認のためアラーム設定値を1時間を5秒に変えたプログラムを作ってみたところ、LEDが消えたままで5秒経過後もLEDが付くことはありませんでした。
お恥ずかしながら、初心者でマイコンの基礎的な知識が足りず、うまく動作しない原因について見当がつかないといったような状況です。
有識者の方々の知識に頼らせていただきたく、投稿をさせていただきました。
やりたいこととしては
main関数内でアラームフラグを検出した際にLED1の値を反転させ、
RTCの時刻とアラーム設定をもう一度初期化させる。のループを考えています。
以下、今回使用したプログラムになります。
---------------------------------------------------------------------------------------------------------------------
RTCの初期化
void initRTC(void){ /* Set subclock drive capacity */ RTC.RCR3.BIT.RTCDV = 0x06; //標準CL用ドライブ能力 while(RTC.RCR3.BIT.RTCDV != 0x06); //Confirm that it has changed, it's slow. /* Enable the subclock for RTC */ RTC.RCR3.BIT.RTCEN = 1; // enable subclock while(RTC.RCR3.BIT.RTCEN != 1); /* Disable RTC interrupts */ RTC.RCR1.BYTE = 0x00u; /* Stop RTC counter */ RTC.RCR2.BIT.START = 0; while(RTC.RCR2.BIT.RESET != 0) ; /*RCR2レジスタのb7を“0”にする*/ RTC.RCR2.BYTE &= 0x7F; //RTC.RCR2.BIT.CNTMD = 0; //カレンダーモード /* RTCは24時間モードで動作 */ RTC.RCR2.BIT.HR24 = 1; /* Clear alarms, capture regs, adjustment regs, and output enable */ RTC.RCR2.BIT.RESET = 1; /* Wait for reset to happen before continuing.*/ while(RTC.RCR2.BIT.RESET != 0) ; /* Insure ICU RTC interrupts disabled */ IEN(RTC,PRD) = 0; IEN(RTC,ALM) = 0; //アラーム割り込み許可?(※要確認) IEN(RTC,CUP) = 0; /* Enable RTC interrupts (PIE, CIE and AIE), not ICU yet */ RTC.RCR1.BYTE = 0x07u; while (RTC.RCR1.BYTE != 0x07u) ;}
----------------------------------------------------------------------------------------------------------------------------------
RTCの時刻設定
void RTCsetTime (void){ /* Stop RTC counter */ RTC.RCR2.BIT.START = 0; while(RTC.RCR2.BIT.START != 0); RTC.RCR2.BIT.RESET = 1; /* Set time */ /* Set seconds. (0-59) */ RTC.RSECCNT.BYTE = 0x00; /* Set minutes (0-59) */ RTC.RMINCNT.BYTE = 0x00; /* Set hours. (0-23) */ RTC.RHRCNT.BYTE = 0x00; /* Set the date */ /* Day of the week (0-6, 0=Sunday) */ RTC.RWKCNT.BYTE = 0x00; /* Day of the month (1-31) */ RTC.RDAYCNT.BYTE = 0x00; /* Month. (1-12, 1=January) */ RTC.RMONCNT.BYTE = 0x00; /* Year. (00-99) */ RTC.RYRCNT.WORD = 0x00; /* start RTC counter */ //RTC.RCR2.BIT.START = 1; //while(RTC.RCR2.BIT.START != 1);}
アラーム設定
void RTC_alarm(void){ int i; //時計動作中であること(RCR2.STARTビットが“1”)を確認する RTC.RCR2.BIT.START = 1; while(RTC.RCR2.BIT.START != 1); //誤割り込みを避けるために、ICUのIER0B.IEN4ビットに“0”を書き込む IEN(RTC,PRD) = 0; IEN(RTC,ALM) = 0; //アラーム割り込み許可?(※要確認) IEN(RTC,CUP) = 0; //-------アラーム時刻設定------------// //アラーム時刻設定と同時または設定後にアラームイネーブルを設定 RTC.RSECAR.BYTE = 0x05; //ENB ビット “1”であれば、RSECCNTカウンタの値と比較を行います RTC.RSECAR.BIT.ENB = 1; //RTCアラーム割り込み要求許可 RTC.RCR1.BIT.AIE = 1; //アラーム時刻設定確定待ち //RCR1.PES[3:0]ビットを“1000b”にし、 //RTC.RCR1.BYTE = 0x08; RTC.RCR1.BIT.PIE = 1; //周期割り込みを2回待つ for(i=0;i<1000;i++); //アラームフラグを“0”にする //アラーム時刻設定中にICUのIR92.IRフラグが設定されたことを考慮して“0”にする ICU.IR[92].BYTE = 0x00; //ICUアラーム割り込み要求許可 //ICUのIER0B.IEN4ビットに“1”を書き込む IEN(RTC,ALM) = 1;}
main関数
void main(void){ PORT_INITIALIZE(); /* ---- Disable maskable interrupts ---- */ clrpsw_i(); /* ---- Initialize non-existent ports ---- */ non_existent_port_init(); /* ---- Initialize the clock ---- */ clock_init(); /* peripheral initialize */ peripheral_init(); initRTC(); RTCsetTime(); RTC_alarm(); /* ---- Disable maskable interrupts ---- */ setpsw_i(); LED2 = 0; while(1){ if(ICU.IR[92].BYTE == 1) { LED1 = ~LED1; initRTC(); RTCsetTime(); RTC_alarm(); } }}
--------------------------------------------------------------------------------------------------------------
使用している開発環境はHEWを使っています。
どうぞよろしくお願いいたします。
クロレッツさん、こんにちは。NoMaYと申します。main()の中央の以下の行をコメントアウトするとどうなりますか?参考にしたプログラムがそもそも割り込み駆動の例だと思われるのですが、その場合、割り込み要求が発生して割り込み要求フラグが一瞬立っても、即座に割り込みルーチンに飛んで行ってしまって、そして飛んで行ったら即座に自動で割り込み要求フラグがクリアされてしまって、main()でポーリングしていては割り込み要求フラグが立ったことを検出出来ない、というのは、たぶん、初学者さんあるある、だと思いますので、まずそれが気になりました。
/* ---- Disable maskable interrupts ---- */ setpsw_i();
NoMaYさん、アドバイスありがとうございます。
指摘していただいたmain関数内の個所をコメントアウトしてみたところ、挙動に特に変わった様子はなく…といった動作でした。
また、割り込み要求についてNoMaYさんからご指摘をいただいた箇所について
以下の認識であっていますでしょうか?
RTCアラームによって割り込みフラグが立つ
ICU.IR[92].BYTE == 1
⇓
割り込みルーチンに飛ぶ
if(ICU.IR[92].BYTE == 1) { LED1 = ~LED1; initRTC(); RTCsetTime(); RTC_alarm(); }
initRTCによって割り込みフラグが即座にクリアされる
それとも他の個所で割り込みフラグがすぐにクリアされている可能性があるのでしょうか?
クロレッツさん、こんにちは。NoMaYです。いえ、以下の部分は認識が違います。投稿されていない箇所にあるはずのRTC割り込みルーチンです。(RX210もRTCも使用したことが無くて、正しい言い回しになっているか自信がありませんけれども。) ごめんなさい、私では、もうこれ以上はリプライ出来ませんので、他の人からのリプライを待って頂けませんでしょうか。(実は、RXマイコンのソフトウェア開発の潮流としては、ハードウェアマニュアルや内蔵周辺レジスタ直接叩きのサンプルコード(もしも見付かればですが)からソフトウェア開発に着手するのは時代遅れになっていて、しかも、もともと私自身も不得手でして、、、すみません、、、)
⇓割り込みルーチンに飛ぶ if(ICU.IR[92].BYTE == 1) { LED1 = ~LED1; initRTC(); RTCsetTime(); RTC_alarm(); }⇓
つまり、以下の部分の認識の方になる、ということです。ただし、昨日の投稿の箇所をコメントアウトしても動作が変わらなかったということは、そういう理由では無い、ということになりますけれども。> それとも他の個所で割り込みフラグがすぐにクリアされている可能性があるのでしょうか?
NoMaYさん、ありがとうございます。
自分1人の力ではうまくいかない原因に見当もつかなかった状況でしたので、
NoMaYさんから指摘をいただいたことで、また一つ新しい考え方を得ることが出来ました。
また、自分でもマニュアルなどを再度研究してもう少し頑張ってみます。
原因究明に協力をしていただき、本当にありがとうございました。