TrueSTUDIO 用 L152CD_UART1 の説明 V001 2014/10/22 UART( 非同期シリアル通信 ) で送受信を行う STM32L152C-DISCO のプロジェクトサンプルです STM32L152C-DISCO は STMicroelectronics 社製の Cortex-M3 ARM CPU である STM32L152RCT6 を搭載した基板です 試用版の開発ツール Atollic TrueSTUDIO for ARM Lite で作成したプロジェクトです ビルド可能なプログラムのコードサイズが 32Kbyte 以内の制限があります プログラムの開始番地は 0x08000000 です デバッグが可能です 目次 1. 使用する信号... 2 1.1. UART 信号... 2 1.2. RS232C ドライバ... 2 1.3. RS232C ケーブル接続図... 3 2. UART 通信確認のための接続例... 3 3. プログラム実行時の動作... 4 4. UART 通信の動作確認... 4 4.1. アプリケーション Access_SerialPort の起動画面... 4 4.2. COM ポートの選択... 5 4.3. 送信データのエコーバック... 6 4.4. 基板上の LED LD4( 青 ) の点灯 / 消灯... 7 5. プロジェクトの構成... 8 5.1. プロジェクト L152CD_UART1 の起動画面... 8 5.2. 追加したソース フォルダとファイル... 8 5.3. UART1 通信データの利用... 9 1) データ送信... 9 2) データ受信... 9 3) UART 送受信の例... 10 4) UART 受信データの処理の例... 10 6. 主なモジュールの説明... 11 6.1. ソース フォルダ src 内のファイル... 11 6.2. HandleCLK... 12 6.3. HandleGPIO... 12 6.4. HandleTIM... 13 6.5. HandleUART... 14 6.6. Communicate_UART... 15 6.7. UserPrograms... 16 1
1. 使用する信号 1.1. UART 信号 UART 通信に使用する信号と接続相手との接続は以下の通りです UART 信号表 番号 CPU 機能名 CPU 信号名 基板コネクタピン番号 方向 接続相手の信号名 1 USART1_TX PA9 CN10-21 --- > RxD 2 USART1_RX PA10 CN10-33 < --- TxD 3 GND GND CN10-20 < --- > GND UART 信号を CMOS レベルどうしでそのまま接続してシリアル通信を行うことができます UART 信号に RS232C ドライバを接続して RS232C レベルの信号どうしで接続すれば RS232C 通信を行うことができます 1.2. RS232C ドライバ RS232C ドライバの例を以下に示します RS232C ストレートケーブル接続の場合の DSUB-9S への接続例を以下に示します この例では DSUB-9S には TxD, RxD, GND の 3 本の信号以外は接続されません 番号 RS232C ドライバ 方向 ドライバ側 D-SUB 9S 1 RS1_TxD --- > 2 2 RxD 2 RS1_RxD < --- 3 3 TxD 3 GND < --- > 5 5 GND ストレートケーブル側 D-SUB 9P 2
DSUB-9S DSUB-9P DSUB-9S 1.3. RS232C ケーブル接続図 NUCLEO-L152RE RS232C ドライバ 接続機器 (PC など ) 図 1.3. ストレートケーブル 2. UART 通信確認のための接続例アプリケーション Access_SerialPort を使用して UART( 非同期シリアル通信 ) によりデータの送受信の確認 およびコマンド文字列を送信して STM32L152C-DISCO 上の LED LD4( 青 ) の点灯 / 消灯を行います 動作確認を行うための接続は以下のようになります この例は RS232C レベルで UART 信号を接続しています PC A USB ケーブル : 電源供給および ST-LINK のため USB ポート STM32L152C-DISCO MiniB RS232C ドライバ RS232C 変換ケーブル DSUB-9S 図 2. 3
3. プログラム実行時の動作 1) プログラムを実行すると基板上の LED LD3( 緑 ) が 1 秒点灯 2 秒消灯で点滅します 2) UART1 のチャンネルでデータ受信待ちを行います 3) データを受信するとそのデータをそのまま送信します ( エコーバック ) 4) 受信データが LED 点滅のコマンドであった場合 以下のように動作します 番号 受信コマンド 動作 1 LD4 ON\0 LD4( 青 ) 点灯 2 LD4 OFF\0 LD4( 青 ) 消灯 4. UART 通信の動作確認 UART( 非同期シリアル通信 ) のツール Access_SerialPort アプリケーションを使用して データの送受信の確認 およびコマンド文字列を送信して STM32L152C-DISCO 上の LED LD4( 青 ) の点灯 / 消灯を行います 4.1. アプリケーション Access_SerialPort の起動画面まず PC と STM32L152C-DISCO とを RS232C インターフェースで接続してください アプリケーション Access_SerialPort を起動すると以下のダイアログが表示されます RS232C ケーブルを接続している場合 COM( シリアルポート ) を検索しました と表示されます 4
4.2. COM ポートの選択 COM 選択の ComboBox で COM を選択します 確認のメッセージが表示されるので よい場合は [ はい (Y)] ボタンをクリックします 5
この例では COM4 に設定しました とメッセージが表示されています 4.3. 送信データのエコーバック送信データの TextBox に ASCII 文字列を入力して [ 送信 ] ボタンをクリックすると CPU 基板にデータが送信されます CPU 基板はデータを受信して そのデータをそのまま PC に送信します PC が受信したデータは受信データの部分に表示されます 上記の例では 送信データに How are you? と入力して [ 送信 ] ボタンをクリックした結果 エコーバックのデータが受信データの欄に表示されています 6
4.4. 基板上の LED LD4( 青 ) の点灯 / 消灯基板上の LED LD4( 青 ) の点灯 / 消灯コマンドは以下のようになります 番号 受信コマンド 動作 1 LD4 ON\0 LD4( 青 ) 点灯 2 LD4 OFF\0 LD4( 青 ) 消灯 この例では LD3 ON&00 とセットします 0x20 未満 0x7F 以上のコードは &xx の形で入力します &00 は 0x00 です <CR> の 0x0D なら &0D とします & 自体を入力する場合は &26 と入力してください LD4 ON&00 を入力して [ 送信 ] ボタンをクリックした結果 STM32L152C-DISCO は LD4( 青 ) を点灯します また 受信データ LD4 ON&00 をエコーバック送信します 受信データの欄にはエコーバックされたデータが表示されます LD4( 青 ) を消灯したい場合は LD4 OFF\0 を送信します 7
5. プロジェクトの構成 5.1. プロジェクト L152CD_UART1 の起動画面 TrueSTUDIO で作成したプロジェクト L152CD_UART1 を開いた状態を以下に示します 左側のプロジェクト エクスプローラーの L152CD_UART1 を展開した状態です 5.2. 追加したソース フォルダとファイル追加したソース フォルダとファイルについて簡単に説明します 1) Communicate_UART ( ソース フォルダ ) a) Communicate_UART.h Communicate_UART.c ( ファイル ) 接続相手との通信処理を記述しています データを受信して 受信データをそのまま送信します ( エコーバック ) 受信データを判定して LD4( 青 ) の点灯 / 消灯を行います 2) Handles ( ソース フォルダ ) Peripheral の設定などを行っています a) HandleCLK.h HandleCLK.c ( ファイル ) 内部クロック HSI を使用するための設定を記述しています HSI( 周波数 16MHz) を入力して PLL により 32MHz にしてシステムクロック SYSCLK として使用します b) HandleGPIO.h HandleGPIO.c ( ファイル ) GPIO 入出力の初期設定を記述しています c) HandleTIM.h HandleTIM.c ( ファイル ) タイマ割り込みを使用するために タイマの初期設定を記述しています 1mSec ごとにタイマ割り込みが発生するように設定しています d) HandleUART.h HandleUART.c ( ファイル ) UART の初期化と UART 送受信の処理を記述しています 8
3) UserPrograms ( ソース フォルダ ) LED のための処理を記述しています a) UserPrograms.h UserPrograms.c ( ファイル ) Status LED : LD3( 緑 ) に使用している GPIO の初期設定と点滅処理を記述しています LD4( 青 ) に使用している GPIO の初期設定を記述しています 5.3. UART1 通信データの利用 1) データ送信ソースフォルダ Handles の下の HandleUART.c で宣言しているバッファ GLB_uint8_Tx1_Buffer に送信データをセットしてます そして引数に送信データ数をセットして 以下のモジュールを呼び出すとデータを送信することができます -- // UART1 送信処理 : 送信 Buffer に送信データがセットされた状態で Call される -- // uint16_t uint16_sendlength : 送信データ数 // 戻り値 : // 0 : 送信終了 // 1 : エラー -- void SendUART1(uint16_t uint16_sendlength); 2) データ受信引数に受信データを格納するバッファのポインタを指定して 以下のモジュールを呼び出します 戻り値の受信 byte 数が 1 以上の場合 データが受信されています -- // UART1 受信処理 -- // uint8_t *puint8_receivebuffer : 受信データを格納する Buffer のポインタ // 戻り値 : // -1 : 受信なし // 0 : 受信なし // 1 以上 : 受信 byte 数 -- int16_t ReceiveUART1(uint8_t *puint8_receivebuffer); 9
3) UART 送受信の例ソースフォルダ Communicate_UART の下のファイル Communicate_UART.c に UART1 送受信の例が記述されています //------------------------------------------------------------ // UART1 通信処理 //------------------------------------------------------------ // 戻り値 : // -1 : 処理中 // 0 : 終了 //------------------------------------------------------------ int16_t Communicate_UART1(void); 4) UART 受信データの処理の例以下のモジュールで受信データを判定して 処理を行っています ---- // 受信コマンド判定および実行 ---- // 引数 // uint16_t uint16_receivelength : 受信データ数 // uint8_t *puint8_receivedata : 受信データが格納された Buffer のポインタ // uint8_t *puint8_senddata : 応答送信データを格納する Buffer のポインタ // 戻り値 : 応答送信データ数 ---- uint16_t ExecuteCommandUART(uint16_t uint16_recievelength, uint8_t *puint8_receivedata, uint8_t *puint8_senddata); 10
6. 主なモジュールの説明 6.1. ソース フォルダ src 内のファイルソース フォルダ src 内のファイルでプログラムを追加した主なファイルについて簡単に説明します 1) main.c a) main 関数プログラムはここから開始します 主に初期化処理関数を呼び出しています int main(void) b) システムクロックの設定システムクロック SYSCLK の設定を行います 内部クロック HSI を PLL を使用して 32MHz に設定します ------------------ // HSI を選択して PLL Clock を System Clock として使用する : SYSCLK = 32MHz ------------------ SetHSICLK32MHz(); c) 使用するクロックの初期化 //----------------------- // 周辺クロックの初期化 //----------------------- RCC_Configuration(); d) GPIO の初期化 //----------------------- // GPIO 初期化 //----------------------- Init_GPIOs(); e) Status LED と LD4 ポートの初期化 //-------------------------------------- // Status LED ポート初期化 : LD3( 緑 ) //-------------------------------------- InitializePortStatusLED(); //-------------------------------------- // LD4( 青 ) ポート初期化 //-------------------------------------- InitializePortLD4(); 11
f) UART の初期化 //----------------------------------------------------------- // UART1 通信パラメータ初期化 : 通信速度 9600bps //----------------------------------------------------------- InitializeCommunicate_UART1((uint32_t)9600); g) TIM6 の初期化と割り込み許可 ------ // TIM6 初期化 ------ InitializeTIMx(TIM6, RCC_APB1Periph_TIM6, (uint16_t)definterval_1msec); EnableIrqTIMx(RCC_APB1Periph_TIM6, TIM6_IRQn); // TIM6 Enable Interrupt ------ 2) stm32f4xx_it.h stm32f4xx_it.c このファイルに割り込み処理を記述します 本プロジェクトサンプルでは TIM11 のタイマ割り込み処理と UART1 の割り込み処理を記述しています 6.2. HandleCLK 動作クロックに内部クロック HSI : 16MHz を選択し PLL により 32MHz にして使用します ------------------ // HSI を選択して PLL Clock を System Clock として使用する : SYSCLK = 32MHz ------------------ void SetHSICLK32MHz(void); 6.3. HandleGPIO GPIO を初期化します 1) 低消費電力モード時の GPIO 初期化最初は 使用しない GPIO ピンをアナログ入力モードに初期化します ---------------- // 低消費電力モード時の GPIO 初期化 ---------------- void InitializeGPIOs_LowPower(void); 12
2) GPIO の初期化必要な GPIO の初期化を行います //--------------------------------------------- // GPIO 初期化 //--------------------------------------------- void Init_GPIOs(void); 6.4. HandleTIM 1) TIM6 の初期化タイマ割り込みのために TIM6 を初期化してインターバルをセットします 1mSec ごとに割り込みがかかるように設定しています 以下の関数の引数に TIM6 用のパラメータを指定して TIM6 を初期化します -------------- // TIMx 初期化 -------------- // TIM_TypeDef *TIMx : TIM 選択 : TIM6 or TIM7 // uint32_t RCC_APB1Periph_TIMx : specifies the APB1 peripheral to gates its clock. // uint16_t uint16_interval : TiMx のインターバル設定値 -------------- void InitializeTIMx(TIM_TypeDef *TIMx, uint32_t RCC_APB1Periph_TIMx, uint16_t uint16_interval); 2) タイマ割り込み許可以下の関数の引数に希望する TIMx 用のパラメータを指定して割り込みを許可します ------------------- // TIMx 割り込み許可 ------------------- // uint32_t RCC_APB1Periph_TIMx : specifies the APB1 peripheral to gates its clock. // uint8_t TIMx_IRQn : STM32 specific Interrupt Numbers ------------------- void EnableIrqTIMx(uint32_t RCC_APB1Periph_TIMx, uint8_t TIMx_IRQn); 13
6.5. HandleUART 1) UART の初期化 //------------------------------------------------- // UART1 初期化 //------------------------------------------------- // uint32_t uint32_baudrate : 通信速度 bps //------------------------------------------------- void InitializeUART1(uint32_t uint32_baudrate); 2) UART 送信送信 Buffer に格納されたデータを指定データ数送信します -- // UART1 送信処理 : 送信 Buffer に送信データがセットされた状態で Call される -- // uint16_t uint16_sendlength : 送信データ数 // 戻り値 : // 0 : 送信終了 // 1 : エラー -- void SendUART1(uint16_t uint16_sendlength); 3) UART 受信受信待ちを行いデータを受信したら 受信 Buffer に格納します -- // UART1 受信処理 -- // uint8_t *puint8_receivebuffer : 受信データを格納する Buffer のポインタ // 戻り値 : // -1 : 受信なし // 0 : 受信なし // 1 以上 : 受信 byte 数 -- int16_t ReceiveUART1(uint8_t *puint8_receivebuffer); 14
6.6. Communicate_UART 1) UART の初期化 //----------------------------------------------------------- // UART1 通信パラメータ初期化 //----------------------------------------------------------- // uint32_t uint32_baudrate : 通信速度 //----------------------------------------------------------- void InitializeCommunicate_UART1(uint32_t uint32_baudrate); 2) UART 通信処理 UART の受信待ちを行い 受信データを判定して LED の点滅間隔の変更を行います 受信データはエコーバックします //------------------------------------------------------------ // UART1 通信処理 //------------------------------------------------------------ // 戻り値 : // -1 : 処理中 // 0 : 終了 //------------------------------------------------------------ int16_t Communicate_UART1(void); 3) 受信コマンドの実行 ---- // 受信コマンド判定および実行 ---- // 引数 // uint16_t uint16_receivelength : 受信データ数 // uint8_t *puint8_receivedata : 受信データが格納された Buffer のポインタ // uint8_t *puint8_senddata : 応答送信データを格納する Buffer のポインタ // 戻り値 : 応答送信データ数 ---- uint16_t ExecuteCommandUART(uint16_t uint16_recievelength, uint8_t *puint8_receivedata, uint8_t *puint8_senddata); 15
6.7. UserPrograms UserPrograms.h には LED に使用する GPIO に対する定義を記述してあります 以下に UaerPrograms.c に記述している関数の説明を記します 1) LED に使用する GPIO の初期化 ( 共通処理 ) GPIO 番号とピン番号を指定して I/O を初期化します // LED ポート初期化 // GPIO_TypeDef *GPIOx : GPIO ポート指定 // uint16_t GPIO_Pin_x : GPIO ピン指定 void InitializePortLED(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin_x); 2) LED の点滅処理 ( 共通処理 ) GPIO 番号とピン番号などを指定して希望の LED の点滅処理を行います // LED 点滅 : 点灯 / 消灯切り替え // 点灯 / 消灯を切り替えると同時に点灯時間 / 消灯時間をセットする // GPIO_TypeDef *GPIOx : GPIO ポート指定 // uint16_t GPIO_Pin_x : GPIO ピン指定 // int16_t *pint16_onoff : ON/OFF 状態 // 0 : OFF // 1 : ON // uint16_t *puint16_timer : 点灯時間 / 消灯時間をセットする変数のポインタ // uint16_t uint16_timeon : 点灯時間 // uint16_t uint16_timeoff : 消灯時間 void BlinkLED(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin_x, int16_t *pint16_onoff, uint16_t *puint16_timer, uint16_t uint16_timeon, uint16_t uint16_timeoff); 16
3) LED に使用する I/O の初期化 a) StatusLED : LD3( 緑 ) // Status LED ポート初期化 : LD3( 緑 ) void InitializePortStatusLED(void); b) LD4( 青 ) // LD4( 青 ) ポート初期化 void InitializePortLD4(void); 4) StatusLED : LD3( 緑 ) の点滅 // Status LED 点滅 : LD3( 緑 ) : 点灯 / 消灯切り替え // TIMx 割り込み内で GLB_uint16_BlinkTimerStatusLED をデクリメントする // GLB_uint16_BlinkTimerStatusLED が 0 になった時 呼び出される // 点灯 / 消灯を切り替えると同時に点灯時間 / 消灯時間をセットする // uint16_t uint16_timeon : 点灯時間 // uint16_t uint16_timeoff : 消灯時間 void BlinkStatusLED(uint16_t uint16_timeon, uint16_t uint16_timeoff); 17
有限会社りばいぶ 電子工作のための 飛石伝ひ 改訂履歴 V001 2014/10/22 初版 18