忘備録-備忘録

技術的な備忘録

RX62NでFreeRTOSを動かす

2015-11-27 22:05:41 | RX62N
RX62N(インターフェス2011年5月号付録)でFreeRTOSを動かしました。環境はe2 studio, renesas RXCコンパイラです。
ここにプロジェクトをエクスポートしたものを置いておきます。
ファイル構成は次の通りです。
”FreeRTOS”以下のフォルダに必要なファイルをまとめました。
”FreeRTOS/renesas”以下にウィザードが自動生成するファイルをまとめておいてあります。
”port.c”にエラーが表示されているのはインラインアセンブラを使用しているためです。



フォルダを閉じるとユーザープログラムのみでシンプルになります。



プロジェクト作成時にはできるだけ自動生成するファイルを省き、それでも作成されるものは”FreeRTOS/renesas”のファイルと被るので削除します。



ここに”FreeRTOS”フォルダ以下のファイルをドラッグアンドドロップでコピーすればFreeRTOSのインストールは終了です。



4つのタスクが違う間隔で起動と待期を繰り返しながらLEDを点滅させるプログラムは次のようになります。

  1. #include <stdio.h>
  2. #include "FreeRTOS/renesas/iodefine.h"
  3. /* Kernel includes. */
  4. #include "FreeRTOS/FreeRTOS.h"
  5. #include "FreeRTOS/task.h"
  6. #include "FreeRTOS/queue.h"
  7. void vTask1(void *pvParameters)
  8. {
  9.     while(1) {
  10.         PORTD.DR.BIT.B1 = ~PORTD.DR.BIT.B1;
  11.         vTaskDelay(100/portTICK_PERIOD_MS);
  12.     }
  13. }
  14. void vTask2(void *pvParameters)
  15. {
  16.     while(1) {
  17.         PORTD.DR.BIT.B2 = ~PORTD.DR.BIT.B2;
  18.         vTaskDelay(200/portTICK_PERIOD_MS);
  19.     }
  20. }
  21. void vTask3(void *pvParameters)
  22. {
  23.     while(1) {
  24.         PORTD.DR.BIT.B3 = ~PORTD.DR.BIT.B3;
  25.         vTaskDelay(300/portTICK_PERIOD_MS);
  26.     }
  27. }
  28. void vTask4(void *pvParameters)
  29. {
  30.     while(1) {
  31.         PORTD.DR.BIT.B0 = ~PORTD.DR.BIT.B0;
  32.         vTaskDelay(400/portTICK_PERIOD_MS);
  33.     }
  34. }
  35. void main(void)
  36. {
  37.     /* Renesas provided CPU configuration routine. The clocks are configured in
  38.     here. */
  39.     /* Turn all LEDs off. */
  40.     PORTD.DDR.BYTE = 0xFF;    //ポートC出力
  41.     PORTD.DR.BYTE = 0xFF;    //初期値
  42.     xTaskCreate(vTask1,"Task1",100,NULL,1,NULL);
  43.     xTaskCreate(vTask2,"Task2",100,NULL,1,NULL);
  44.     xTaskCreate(vTask3,"Task3",100,NULL,1,NULL);
  45.     xTaskCreate(vTask4,"Task4",100,NULL,1,NULL);
  46.     /* Create the queue. */
  47.     vTaskStartScheduler();
  48.     /* If all is well the next line of code will not be reached as the scheduler
  49.     will be    running. If the next line is reached then it is likely that there was
  50.     insufficient heap available for the idle task to be created. */
  51.     for( ;; );
  52. }

RX62Nの12bitAD変換を使うその2

2015-11-26 15:00:48 | RX62N
RX62Nの12bitAD変換器を動かすプログラムのサンプルです。MTU0のTGRAのコンペアマッチを使い一定間隔で変換を行います。AD変換結果の読み出しに割り込みを使用しています。

  1. #include <stdio.h>
  2. #include <machine.h>
  3. #include "iodefine.h"
  4. #include "vect.h"
  5. #define PCLK    48    //PCLK = 48MHz
  6. /*
  7.  * MTU0の初期化
  8.  * TGRAのコンペアマッチでAD変換をスタートさせる
  9.  *
  10.  * 12bit A/Dコンバータ初期化
  11.  * AN0のみ使用
  12.  */
  13. void initMTU0_S12AD(void)
  14. {
  15.     MSTP(MTU0) = 0;                    //タイマMTU0回路動作
  16.     MTU0.TCR.BIT.CCLR = 1;            //TGRAコンペアマッチでカウンタクリア
  17.     MTU0.TCR.BIT.CKEG = 0;            //クロックエッジ選択ビット (使用しない)
  18.     MTU0.TCR.BIT.TPSC = 3;            //PCLK/64でカウント
  19.     MTU0.TMDR.BIT.MD = 0;            //通常動作
  20.     MTU0.TIER.BIT.TTGE = 1;            //A/D変換開始要求の発生を許可
  21.     MTU0.TCNT = 0;
  22.     MTU0.TGRA = PCLK*1000000L/64L/1000L - 1L;    // PCLK = 48MHzで1秒間に1000回AD変換を行う
  23.     MSTP(S12AD) = 0;                // 12bit AD変換回路動作
  24.     delay_ms(100);                    // AD変換回路が安定するのを待つ
  25.     PORT4.DDR.BIT.B0 = 0;            // AN0を使用するためデジタル入力に
  26.     S12AD.ADCSR.BIT.CKS = 3;        // クロック PCLK/1
  27.     S12AD.ADCSR.BIT.EXTRG = 0;        // A/D開始トリガ選択レジスタ(ADSTRGR)で選択されたタイマ要因による、スキャン変換の開始を選択
  28.     S12AD.ADCSR.BIT.TRGE = 1;        // 外部トリガ(ADTRG0#)または、MTU、TMRトリガによるスキャン変換を許可
  29.     S12AD.ADCSR.BIT.ADIE = 1;        // スキャン終了後のS12ADI0割り込み発生の許可
  30.     IR(S12AD,ADI) = 0;                // 割り込みフラグクリア
  31.     IEN(S12AD,ADI) = 1;                // 割込み許可
  32.     IPR(S12AD,ADI) = 0x01;            // 割り込み優先順位設定
  33.     S12AD.ADANS.BIT.ANS = 0x01;        // AN0のみ変換
  34.     S12AD.ADCER.BIT.ADRFMT = 0;        // 保存データは右詰め
  35.     S12AD.ADSTRGR.BIT.ADSTRS = 1;    // TRG0AN_0トリガで変換開始
  36.     MTUA.TSTR.BIT.CST0 = 1;            // タイマMTU0スタート
  37. }
  38. /*
  39.  * S12AD ADI
  40.  * AD変換終了で呼び出される割り込み関数
  41.  * AD変換の結果を表示
  42.  */
  43. //
  44. void Excep_S12AD_ADI(void)
  45. {
  46.     int ans;
  47.     ans = S12AD.ADDR0;
  48.     printf("AD value %d\n",ans);
  49. }
  50. int main(void)
  51. {
  52.     volatile int i;
  53.     Initialization();
  54.     initMTU0_S12AD();                        //AD変換初期化
  55.     printf("A/D converter test.\n");
  56.     while (1) {
  57.         //何もしない 割込みで動作
  58.     }
  59. }

RX62Nの12bitAD変換を使うその1

2015-11-26 14:51:43 | RX62N
RX62Nの12bitAD変換器を動かすプログラムのサンプルです。

  1. #include <stdio.h>
  2. #include <machine.h>
  3. #include "iodefine.h"
  4. /*
  5.  * 12bit A/Dコンバータ初期化
  6.  * AN0のみ使用
  7.  */
  8. void s12ad_init(void) {
  9.     MSTP(S12AD) = 0;
  10.     delay_ms(100);                // AD変換回路が安定するのを待つ
  11.     PORT4.DDR.BIT.B0 = 0;        // AN0を使用するためデジタル入力に
  12.     S12AD.ADCSR.BIT.CKS = 0x03;    // クロック PCLK/1
  13.     S12AD.ADANS.BIT.ANS = 0x01;    // AN0のみ変換
  14.     S12AD.ADCER.BIT.ADRFMT = 0;    // 保存データは右詰め
  15. }
  16. /*
  17.  * AD変換を実行
  18.  */
  19. unsigned short get_s12ad(void) {
  20.   int i;
  21.   unsigned short adv;
  22.   S12AD.ADCSR.BIT.ADST = 1;         // AD変換開始
  23.   while(S12AD.ADCSR.BIT.ADST==1);    // AD変換が終了するのを待つ
  24.   adv = S12AD.ADDR0;                // 結果の読み出し
  25.   return adv;
  26. }
  27. int main(void)
  28. {
  29.     int adv;
  30.     Initialization();
  31.     s12ad_init();                        //AD変換初期化
  32.     printf("A/D converter test.\n");
  33.     while (1) {
  34.         adv = get_s12ad();
  35.         printf("AD value %d\n",adv);
  36.         delay_ms(100);
  37.     }
  38. }

RX62Nのタイマを使うその3

2015-11-26 09:37:31 | RX62N
RX62NのタイマMTUを使いusオーダーで時間待ちするプログラムです。割り込みを使用しないバージョンです。

  1. #include "iodefine.h"
  2. #define PCLK    48    //PCLK = 48MHz
  3. unsigned int usecCount;
  4. /*
  5.  * タイマの初期化
  6.  *  使用タイマ MTU10
  7.  * 割込みは使用しないフラグは使用する。
  8.  */
  9. void initTimer(void)
  10. {
  11.     MSTP(MTU10) = 0;
  12.     MTU10.TCR.BIT.TPSC = 0x02;    // PCLK/16でカウント
  13.     MTU10.TCNT = 0;                //フリーランカウンタ
  14.     usecCount = PCLK*1000000L/1000000L/16L;    //1usecのカウント値
  15. }
  16. /*
  17.  * タイマスタート
  18.  */
  19. void startMTU(void)
  20. {
  21.     MTU10.TCNT = 0;
  22.     MTUB.TSTR.BIT.CST4 = 1;            /* Start MTU2_8 */
  23. }
  24. /*
  25.  * タイマストップ
  26.  */
  27. void stopMTU(void)
  28. {
  29.     MTUB.TSTR.BIT.CST4 = 0;            /* Stop MTU2_8 */
  30. }
  31. /*
  32.  * usecオーダーでの時間待ち
  33.  */
  34. void delay_us(unsigned int us)
  35. {
  36.     unsigned int waitCount;
  37.     waitCount = us * usecCount;    //カウンタの値がいくつになれば指定した時間が来たか
  38.                                 //16bitなのでオーバーフローに注意
  39.     startMTU();
  40.     while(MTU10.TCNT <waitCount);
  41.     stopMTU();
  42. }
  43. /*
  44.  * msecオーダーでの時間待ち
  45.  */
  46. void delay_ms(unsigned int ms)
  47. {
  48.     unsigned int i;
  49.     for(i=0;i<ms;i++) {
  50.         delay_us(1000);
  51.     }
  52. }

RX62Nのタイマを使うその2

2015-11-25 14:06:39 | RX62N
RX62NのタイマCMTを使いusオーダーで時間待ちするプログラムです。割り込みを使用しています。頻繁に割り込みが発生するので実用的かどうかはわかりません。

  1. #include <machine.h>
  2. #include "timer.h"
  3. #include "iodefine.h"
  4. #include "vect.h"
  5. #define PCLK    48    //PCLK = 48MHz
  6. /* 1usecでカウントアップする変数 */
  7. static volatile unsigned int utimer;
  8. /*
  9.    タイマ初期化 使用するタイマCMT1
  10.    引数  無し
  11.    戻り値 無し
  12. */
  13. void initTimer(void)
  14. {
  15.     MSTP(CMT1) = 0;                                    // enable CMT1
  16.     CMT1.CMCR.WORD = 0x0040;                        // 1/8
  17.     //CMT1.CMCOR = PCLK*1000000L/1000L/8L - 1;        // 1000Hz(1ms)
  18.     CMT1.CMCOR = PCLK*1000000L/1000000L/8L - 1;        // 1MHz(1us)
  19.     ICU.IER[IER_CMT1_CMI1].BIT.IEN_CMT1_CMI1 = 1;    //Enable CMIE
  20.     ICU.IPR[IPR_CMT1_CMI1].BYTE = 8;                // Set interrupt priority level
  21.     CMT.CMSTR0.WORD |= 0x0002;                        // start CMT0 CMT1
  22.     
  23.     utimer = 0;    //タイマの初期化
  24. }
  25. /*
  26.    タイマカウンタの初期化
  27.    引数  タイマ番号
  28.    戻り値 無し
  29. */
  30. void clearTimer(void)
  31. {
  32.     utimer = 0;
  33. }
  34. /*
  35.    タイマの値を取得する
  36.    引数  タイマ番号
  37.    戻り値 タイマの値
  38. */
  39. unsigned int getTimer(void)
  40. {
  41.     return utimer;
  42. }
  43. /*
  44.    mSec単位でウェイトをかける
  45.    引数   待ち時間 ミリ秒
  46.    戻り値  無し
  47. */
  48. void delay_ms(unsigned int ms)
  49. {
  50.     unsigned int us;
  51.     us = 1000*ms;
  52.     clearTimer();
  53.     while(getTimer()<=us);
  54. }
  55. /*
  56.    uSec単位でウェイトをかける
  57.    引数   待ち時間 マイクロ秒
  58.    戻り値  無し
  59. */
  60. void delay_us(unsigned int us)
  61. {
  62.     clearTimer();
  63.     while(getTimer()<=us);
  64. }
  65. /*
  66.    タイマ割込みプログラム
  67.    CMT1割込みで起動
  68. */
  69. void Excep_CMT1_CMI1(void)
  70. {
  71.     utimer++;
  72. }