Cypress/SpansionのFM0+ S6E1B8シリーズマイクロコントローラ入門

作成者:Matthew Bon、最終更新日:2016年4月12日

image

お役立ちリンク集

S6E1B8 FM0+ Starter Kit

S6E1B Starter Kit Cypress page

FM0+ Cypress Page

背景

本稿では、CypressのマイクロコントローラS6E1B8で、ポテンショメータを調整してLEDの輝度を制御する簡単なデモアプリケーションの作成方法を説明します。この例では、S6E1B8上でCypressのFM0+ペリフェラルドライバライブラリをセットアップして利用する方法、ベースタイマを使ってパルス幅変調を生成する方法、および12ビットSARアナログ/デジタルコンバータのセットアップと利用方法について紹介します。

IAR Embedded Workbenchを使用してプロジェクトを作成

  • Cypressのホームページから、以下に示すS6E1B8 Start kit complete setup fileをダウンロードしてください:S6E1B8 Starter Kit page

  • インストールウィザードの指示に従って、ドライバをインストールし、PDLファイルを解凍します。

  • 「FM_PDL_2.0.1」ファイルをダウンロード・解凍したら、\FM_PDL_2.0.1\template\IARフォルダに移動し、サンプルプロジェクトを開きます。

  • Workspaceが開いたら、projectを右クリックして「Options」を選択します。

  • ここで、ツールチェーンを設定する必要があります。以下のセクションでは、S6E1B8マイクロコントローラのプロセスを詳細に説明します。FM0+ファミリのどの製品にも同じプロセスを適用できますが、選択される正確なファイルは各マイクロコントローラシリーズで異なります。

S6E1B8用のツールチェーンをセットアップ

  1. 「Options」ウィンドウで、「General Options」セクションを選択します。「Target」タブで、Deviceに「None」、Coreに「Cortex M0+」が選択されていることを確認します。

  2. 「Linker」セクションを選択します。リンカ設定ファイル(linker configuration file)として「PROJ_DIR\config\s6e1b8x\s6e1b86.icf」が選択されていることを確認します。

  3. 「Debugger」セクションを選択します。「Setup」タブで、「CMSIS DAP」が選択されていること、Setup macroが「PROJ_DIR\config\s6e1b8x\Ram_VTOR_s6e1b8.mac」であることを確認します。
    「Download」タブで、flash loaderが「PROJ_DIR\config\s6e1b8x\flashloader\FlashLoader.board」であることを確認します。



  4. 「CMSIS DAP」セクションを選択し、「JTAG/SWD」タブで、「SWD」が選択されていることを確認します。

  5. OKをクリックして、変更を適用します。

  6. 次にpdl_devices.hを開き、MCUシリーズをPDL_DEVICE_SERIES_S6E1B8Xに、MCUパッケージをPDL_DEVICE_PACKAGE_S6_Eに変更します。MCUパッケージによってPDLがGPIOピンにどのようにマッピングされるかが決まります。各マイクロコントローラファミリは、MCUによりピンアウトが異なり、それに応じて異なるMCUパッケージが存在することにご注意ください。

    image

  7. 最後に、プロジェクトが正しく設定されていることを確認することが重要です。「Project」メニューの「Rebuild All(すべてを再構築する)」を選択するだけで、これを行うことができます。プロジェクトがエラーなくビルドされたら、正しく設定されている可能性が高いです。

PWMを設定

このセクションでは、PWM動作させるためのベースタイマの設定方法を説明します。ここで示すConfigurePWM()関数は、後のサンプルプログラムで使用します。

  • pdl_user.hファイルで、図のようにGPIOの動作、ベースタイマ、およびベースタイマモードを有効にします。

  • main.cで、以下の変数を定義します。

PWMの定義とグローバル変数

/*Defines*/
#define User_Timer  BT5
               
/*Globals*/
 
//PWM globals
uint16_t Pulse_Value =  9999;     //Duty Cycle Value
stc_bt_pwm_config_t stcPwmConfig; //PWM Configuration Structure
  • 前項の変数を用いて、次の関数でPWMモードでタイマを設定・起動することができます。

ConfigurePWM()

void ConfigurePWM(void)
{
   /*Wipe structure*/
    PDL_ZERO_STRUCT(stcPwmConfig);
     
  /*Configure and Initialize PWM timer*/
    stcPwmConfig.enPres = PwmPres1Div4;              //20Mhz/4 = 5Mhz PWM clock
    stcPwmConfig.enMode = PwmContinuous;             //Enable continous mode
    stcPwmConfig.enExtTrig = PwmExtTrigDisable;      //Disable External Trigger
    stcPwmConfig.enOutputMask = PwmOutputNormal;     //Normal Output (no Mask)
    stcPwmConfig.enOutputPolarity = PwmPolarityLow;  //Initial Polarity Low
    stcPwmConfig.enRestartEn = PwmRestartEnable;     //Restart Enabled 
  
    Bt_Pwm_Init(&User_Timer , &stcPwmConfig);        //Init PWM with new Config 
     
     
    /* Set I/O mode */
    Bt_ConfigIOMode(&User_Timer, BtIoMode0);
     
     
    /* Set cycle and duty value*/
    Bt_Pwm_WriteCycleVal(&User_Timer, 9999); // Cycle = 200us
    Bt_Pwm_WriteDutyVal(&User_Timer,  Pulse_Value); // Duty = start at 100%
             
    /*Enable Counter Operation*/
    Bt_Pwm_EnableCount(&User_Timer);
     
    /*Enable Software Trigger/Start PWM timer*/
    Bt_Pwm_EnableSwTrig(&User_Timer);
}

ADCを設定

このセクションでは、ADCのセットアップ方法を示します。ここで示すConfigureADC()関数は、後のサンプルプログラムで使用します。

  • pdl_user.hファイルで、以下を有効にします。

  • main.cで以下のグローバル変数を定義します。

ADCのグローバル変数

//ADC globals
stc_adcn_t       *pstcAdc = (stc_adcn_t *)&ADC0;
stc_adc_config_t stcConfig;                  
stc_adc_prio_t   stcPrioCfg;
uint16_t         ADC_Val          = 0;   //ADC Voltage Reading
uint32_t         ADC_READ         = 0;   //ADC FIFO Data  
uint32_t         Sample_Count     = 10;
  • 上のセクションの変数を使用して、以下の関数でADCを設定することができます。

ConfigureADC()

 void ConfigureADC(void)
{
    /*Wipe structures*/
    PDL_ZERO_STRUCT(stcConfig);
    PDL_ZERO_STRUCT(stcPrioCfg);
     
    /*Initialize priority conversion*/
    stcPrioCfg.bPrioExtTrigStartEnable = FALSE; //Disable External trigger
    stcPrioCfg.bPrioTimerStartEnable = FALSE;   //Disable Timer trigger start
    stcPrioCfg.enPrioTimerTrigger = AdcNoTimer; //Disable Trigger timer
    stcPrioCfg.u8PrioFifoDepth = 0;             //Set FIFO depth = 1 reading
    stcPrioCfg.u8PrioLevel1AnalogChSel = 0;
    stcPrioCfg.u8PrioLevel2AnalogChSel = 19;    //Select ADC input pin AN19
     
    stcConfig.u32SamplingTimeSelect.u32AD_CHn = 0; //Sample on channel 0 
    stcConfig.enSamplingTimeN0 = Value8;    //ST N0 Config bits
    stcConfig.u8SamplingTime0 = 8u;         //ST value for 0
    stcConfig.enSamplingTimeN1 = Value8;    //ST N1 Config bits
    stcConfig.u8SamplingTime1 = 8u;         //ST value for 1
    stcConfig.u8ComparingClockDiv = 3u;     //Frequency division ratio
    stcConfig.pstcPrioInit = &stcPrioCfg;  
}
  • ConfigureADC関数が呼び出されると、以下のコードでADCを起動し、変換を行い、データを取り出すことができます。

ADCを操作

  /*Start ADC*/
    if ( Adc_Init(pstcAdc, &stcConfig) == Ok)        //Init ADC0
    {
        Adc_EnableWaitReady(pstcAdc);               //Enable ADC0 & wait for initialization
    }
  
    Adc_SwTriggerPrio(pstcAdc);                     //Trigger ADC0
        while (1)
        {
            if (TRUE == Adc_GetIrqFlag(pstcAdc, AdcPrioIrq)) //Wait for ADC conversion
            {
                Adc_ClrIrqFlag(pstcAdc, AdcPrioIrq);
                break;
            }
        }
         
  ADC_READ = Adc_ReadPrioFifo(pstcAdc); //Read ADC FIFO
         
  ADC_Val = Adc_GetPrioData(pstcAdc, ADC_READ); //Get voltage reading

サンプルプログラム

このセクションには、PWMとADCの設定機能を使ったプログラム例を掲載しています。このサンプルプログラムを使用するには、FM_PDL_2.0.1 IAR サンプルプロジェクトの main.c と pdl_user.h ファイルをこのセクションに含まれるものに置き換えるだけです。さらに、このセクションでは、プログラムの動作を示すフローチャートと、main.cファイルのすべてを詳細に記述したコードブロックも掲載しています。

ソースファイル:

main.c(4.2 KB)

pdl_user.h(63.9 KB)

フローチャート:

プログラムフローチャート

コードブロック:

サンプルプログラムのコード
Main.c

/*
*
* FM0+ Example program
* This program reads the analog voltage on AN19 and uses it to adjust the PWM output on TIOA5
*
*This example was based in part on the FM0+ examples by Edison Zhang, Spansion Corporation.
*
**/ 
 
/*Includes*/
#include "pdl_header.h"
 
/*Defines*/
#define User_Timer  BT5
               
/*Globals*/ 
 
//PWM globals
uint16_t Pulse_Value =  9999;     //Duty Cycle Value
stc_bt_pwm_config_t stcPwmConfig; //PWM Configuration Structure
 
//ADC globals
stc_adcn_t       *pstcAdc = (stc_adcn_t *)&ADC0;
stc_adc_config_t stcConfig;                  
stc_adc_prio_t   stcPrioCfg;
uint16_t         ADC_Val          = 0;   //ADC Voltage Reading
uint32_t         ADC_READ         = 0;   //ADC FIFO Data  
uint32_t         Sample_Count     = 10;  
 
/*Function prototypes*/
void ConfigurePWM(void); 
void ConfigureADC(void);
    
/*Main*/
int32_t main(void)
{
    
   /* Initialize GPIO pin as PWM pin..aka map the base timer to the correct IO port  */
    SetPinFunc_TIOA5_1_OUT();
     
    /*Configure ADC*/
    ConfigureADC();
     
    /*Configure and Start PWM*/
    ConfigurePWM();
     
     
    /*Start ADC*/
    if ( Adc_Init(pstcAdc, &stcConfig) == Ok)        //Init ADC0
    {
        Adc_EnableWaitReady(pstcAdc);               //Enable ADC0 & wait for initialization
    }
     
     
    /* Read ADC and adjust Duty Cycle*/
    while(1)
    {         
         
        Adc_SwTriggerPrio(pstcAdc);                 //Trigger ADC0
        while (1)
        {
            if (TRUE == Adc_GetIrqFlag(pstcAdc, AdcPrioIrq)) //Wait for ADC conversion
            {
                Adc_ClrIrqFlag(pstcAdc, AdcPrioIrq);
                break;
            }
        }
         
        ADC_READ = Adc_ReadPrioFifo(pstcAdc); //Read ADC FIFO
         
        ADC_Val = Adc_GetPrioData(pstcAdc, ADC_READ); //Get voltage reading
         
        Pulse_Value = 9999 - ADC_Val*2; //Scale Duty Cycle to ADC reading
         
        Bt_Pwm_WriteDutyVal(&User_Timer,Pulse_Value);//Write new Duty Cycle
         
         
     };
  
}
 
void ConfigurePWM(void)
{
   /*Wipe structure*/
    PDL_ZERO_STRUCT(stcPwmConfig);
     
  /*Configure and Initialize PWM timer*/
    stcPwmConfig.enPres = PwmPres1Div4;              //20Mhz/4 = 5Mhz PWM clock
    stcPwmConfig.enMode = PwmContinuous;             //Enable continous mode
    stcPwmConfig.enExtTrig = PwmExtTrigDisable;      //Disable External Trigger
    stcPwmConfig.enOutputMask = PwmOutputNormal;     //Normal Output (no Mask)
    stcPwmConfig.enOutputPolarity = PwmPolarityLow;  //Initial Polarity Low
    stcPwmConfig.enRestartEn = PwmRestartEnable;     //Restart Enabled 
  
    Bt_Pwm_Init(&User_Timer , &stcPwmConfig);        //Init PWM with new Config 
     
     
    /* Set I/O mode */
    Bt_ConfigIOMode(&User_Timer, BtIoMode0);
     
     
    /* Set cycle and duty value*/
    Bt_Pwm_WriteCycleVal(&User_Timer, 9999); // Cycle = 200us
    Bt_Pwm_WriteDutyVal(&User_Timer,  Pulse_Value); // Duty = start at 100%
             
    /*Enable Counter Operation*/
    Bt_Pwm_EnableCount(&User_Timer);
     
    /*Enable Software Trigger/Start PWM timer*/
    Bt_Pwm_EnableSwTrig(&User_Timer);
 
} 
 
void ConfigureADC(void)
{
    /*Wipe structures*/
    PDL_ZERO_STRUCT(stcConfig);
    PDL_ZERO_STRUCT(stcPrioCfg);
     
    /*Initialize priority conversion*/
    stcPrioCfg.bPrioExtTrigStartEnable = FALSE; //Disable External trigger
    stcPrioCfg.bPrioTimerStartEnable = FALSE;   //Disable Tiimer trigger start
    stcPrioCfg.enPrioTimerTrigger = AdcNoTimer; //Disable Trigger timer
    stcPrioCfg.u8PrioFifoDepth = 0;             //Set FIFO depth = 1 reading
    stcPrioCfg.u8PrioLevel1AnalogChSel = 0;
    stcPrioCfg.u8PrioLevel2AnalogChSel = 19;    //Select ADC input pin AN19
     
    stcConfig.u32SamplingTimeSelect.u32AD_CHn = 0; //Sample on channel 0 
    stcConfig.enSamplingTimeN0 = Value8;    //ST N0 Config bits
    stcConfig.u8SamplingTime0 = 8u;         //ST value for 0
    stcConfig.enSamplingTimeN1 = Value8;    //ST N1 Config bits
    stcConfig.u8SamplingTime1 = 8u;         //ST value for 1
    stcConfig.u8ComparingClockDiv = 3u;     //Frequency division ratio
    stcConfig.pstcPrioInit = &stcPrioCfg;  
}

サンプルプログラムをテスト

  • 開発ボードがUSBでPCに接続され、ドライバが正しくインストールされていることを確認します。

  • 開発ボード上で、ジャンパが以下のように設定されていることを確認してください。

Jumper Position
J1 Open
J2 Open
J3 2-3
J4 1-2
  • IARのプロジェクトメニューから「Rebuild All」を選択します。プロジェクトがエラーなくビルドされることを確認します。

  • プロジェクトが正しくビルドされたら、ツールバーにある緑色の矢印の「Download and Debug」ボタンをクリックするか、単に「Ctrl+D」を押してください。

  • 初めてボードをプログラムするときは、おそらく次のようなウィンドウがポップアップ表示されます。

  • これは、各メモリゾーンをクリックし、「Use Factory」を選択するだけで解決します。3つのゾーンすべてについてこの操作を実行したら、「Ok」をクリックください。

  • ボードがデバッグモードに入ったら、F5キーを押してプログラムを実行します。LED4は、ポテンショメータRP1が反時計回りの最大位置にあるとき、最も明るく輝きます。RP1を時計回りに回すと、LED4は暗くなり、最終的に消灯します。

  

ご質問・ご意見

この記事がCypressのFM0+マイクロコントローラの導入にお役に立てば幸いです。
このページや他のページの情報についてのご質問やフィードバックは、TechForumまでお寄せください:TechForum




オリジナル・ソース(English)