皆さんのようなマイコン初学者の多くは“Lチカ”といわれるプログラムを最初に書きます.
この項ではマイコンの持つ最も基本的な機能であるGPIO(General Purpose Input Output;汎用入出力)を使用して,マイコンに接続されたLEDの点灯・点滅を制御しながら,GPIOの使い方を検討します.

この項で必要となる基礎知識

特になし

プログラムの仕様

STM32F103C8T6のGPIOには,ポートAからポートDまで,4つのポートがあります.
ポートAは0番ピンから15番ピン,
ポートBも0番ピンから15番ピン,
ポートCは13番ピンから15番ピン,
ポートDは0番ピンと1番ピンをもっています.
ここでは,ポートAの0番ピンをPA0,ポートCの13番ピンをPC13...などと呼ぶことにします.
このうち,PA13とPA14はSWDが,PC14とPC15,PD0とPD1は外部発振器がそれぞれ専有するので,これらのピンは使うことができません.それでもなお31ピンくらい残っているので十分だとは思いますが気をつけてください.

今回は,PC13に予め接続されているLEDを点滅させます.

GPIOの初期化

前回で学んだように,GPIOのペリフェラルを使うためにはクロックを供給しなければなりません.
これはAVRにはない操作で,見落としやすいので注意が必要です.
今回はGPIOCを使うので,GPIOCにクロックを供給するために,次の記述をmain関数内に追加します.(whileループの外)
  1. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);

次にGPIOを初期化します.
GPIOを初期化するには,GPIO_InitTypeDefという構造体のインスタンスを定義します.
次の記述をmain関数内に追加します.(whileループの外)
  1. GPIO_InitTypeDef GPIOInitStruct;
  2. GPIOInitStruct.GPIO_Pin = GPIO_Pin_13; // 13番ピンを
  3. GPIOInitStruct.GPIO_Speed = GPIO_Speed_50MHz; // GPIOの速さを50MHzに
  4. GPIOInitStruct.GPIO_Mode = GPIO_Mode_Out_PP; // 出力,プッシュプル
  5. GPIO_Init(GPIOC, &GPIOInitStruct); // 構造体のポインタを渡してGPIOCの初期化
ピン番号はGPIOInitStruct.GPIO_Pinで指定し,GPIOxはGPIO_Init()のところで指定します.
ピン番号の指定に用いる GPIO_Pin_13 は 0x2000 で定義されます.
GPIO_Pin_0 は 0x0001 で, GPIO_Pin_1 は 0x0002 …という風に定義されていて,0x0003 と書くことで1番ピンと2番ピンを同時に指定できます.同様に,0xFFFFで全てのピンを指定できます.(つまり論理和をとって複数指定できるということ)

点滅ゥ~

GPIOの初期化が完了したらLEDを点滅させていきます.
whileループの中に次の記述を追加します.
  1. GPIO_SetBits(GPIOC, GPIO_Pin_13);
  2. for(uint8_t i = 0; i < 1000000; i++)
  3. {
  4. __NOP();
  5. }
  6. GPIO_ResetBits(GPIOC, GPIO_Pin_13);
  7. for(uint8_t i = 0; i < 1000000; i++)
  8. {
  9. __NOP();
  10. }

GPIO_SetBits関数を呼び出して出力をHに,GPIO_ResetBitsを呼び出してLにします.
これらをひたすら呼び出し続けても一応点滅しますが,点滅が早すぎて人間の目にはわかりません.
そのため,それぞれの呼び出しのあとにビジーウェイトを設けて点滅を視認できるようにしてあります.
GPIOの出力を操作する関数には他にもGPIO_WriteBitやGPIO_Writeという関数もありますが,それらについてはこちらで触れます.

実行ゥ~

これでプログラムができたので実行します.前回と同様にDebugしてやればよいでしょう.

少なくとも次の記述があれば動きます.

  1. #include "diag/Trace.h"
  2. #include "stm32f10x_conf.h"
  3.  
  4. int main(int argc, char* argv[])
  5. {
  6. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
  7.  
  8. GPIO_InitTypeDef GPIOInitStruct;
  9. GPIOInitStruct.GPIO_Pin = GPIO_Pin_13;
  10. GPIOInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  11. GPIOInitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
  12. GPIO_Init(GPIOC, &GPIOInitStruct);
  13.  
  14. while (1)
  15. {
  16. GPIO_SetBits(GPIOC, GPIO_Pin_13);
  17. for(uint8_t i = 0; i < 1000000; i++)
  18. {
  19. __NOP();
  20. }
  21. GPIO_ResetBits(GPIOC, GPIO_Pin_13);
  22. for(uint8_t i = 0; i < 1000000; i++)
  23. {
  24. __NOP();
  25. }
  26. }
  27. }
最終更新:2016年11月22日 00:51