皆さんのようなマイコン初学者の多くは“Lチカ”といわれるプログラムを最初に書きます.
この項ではマイコンの持つ最も基本的な機能であるデジタル出力を使用して,マイコンに接続されたLEDの点灯・点滅を制御しながら,デジタル出力の使い方を検討します.
この項で必要となる基礎知識
今回使うデジタル出力の機能は,正確には“
GPIO(General Purpose Input Output;汎用入出力)”といいます.
プログラムの仕様
この講座で扱うマイコン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は外部発振器がそれぞれ専有するので,これらのピンは使うことができません.従って16ビットのパラレル通信はポートBでのみ可能です.それでもなお31ピンくらい残っているので十分だとは思いますが.
今回は,PC13に予め接続されているLEDを点滅させます.
GPIOの初期化
GPIOを使うためには,GPIOにクロックを供給しなければなりません.これはAVRにはない操作で,見落としやすいので注意が必要です.
今回はGPIOCを使うので,GPIOCにクロックを供給するために,次の記述をmain関数内に追加します.(whileループの外)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
まずはGPIOを初期化します.
GPIOを初期化するには,GPIO_InitTypeDefという構造体のインスタンスを定義します.
次の記述をmain関数内に追加します.(whileループの外)
GPIO_InitTypeDef GPIOInitStruct;
GPIOInitStruct.GPIO_Pin = GPIO_Pin_13; // 13番ピンを
GPIOInitStruct.GPIO_Speed = GPIO_Speed_50MHz; // GPIOの速さを50MHzに
GPIOInitStruct.GPIO_Mode = GPIO_Mode_Out_PP; // 出力,プッシュプル
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ループの中に次の記述を追加します.
GPIO_SetBits(GPIOC, GPIO_Pin_13);
for(uint32_t i = 0; i < 1000000; i++)
{
__NOP();
}
GPIO_ResetBits(GPIOC, GPIO_Pin_13);
for(uint32_t i = 0; i < 1000000; i++)
{
__NOP();
}
GPIO_SetBits関数を呼び出して出力をHに,GPIO_ResetBitsを呼び出してLにします.
それぞれの呼び出しのあとにビジーウェイトを設けて点滅を視認できるようにしてあります.
GPIOの出力を操作する関数には他にもGPIO_WriteBitやGPIO_Writeという関数もありますが,それらについては
こちらで触れます.
実行ゥ~
これでプログラムができたので実行します.前回と同様にDebugしてやればよいでしょう.
少なくとも次の記述があれば動きます.
#include "diag/Trace.h"
#include "stm32f10x_conf.h"
int main(int argc, char* argv[])
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitTypeDef GPIOInitStruct;
GPIOInitStruct.GPIO_Pin = GPIO_Pin_13;
GPIOInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIOInitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOC, &GPIOInitStruct);
while (1)
{
GPIO_SetBits(GPIOC, GPIO_Pin_13);
for(uint32_t i = 0; i < 1000000; i++)
{
__NOP();
}
GPIO_ResetBits(GPIOC, GPIO_Pin_13);
for(uint32_t i = 0; i < 1000000; i++)
{
__NOP();
}
}
}
最終更新:2017年11月25日 19:04