忍者ブログ
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

さて!
前回はまず土台を作りました。

今回からシリアル通信を作っていきますが、

とりあえず基本のLEDチカチカをやってみましょうか。

大丈夫。すぐです。

ちなみに本シリーズはすでにpart5まで書き終わってるので、あとはアップを待つばかりです。誰得な記事ですが頑張って行きたいですね。

あ、文字化けあったらすみません。プログラム系は文字化けしやすいのですよね。

discoveryの回路図や取説読みますと
PB7が緑
PB6が青
となっているようです。


と、その前に

stm32f10x.hに飛びたいのですが
とりあえずmain.cの1行目に
#include "stm32l1xx.h"
と書いておきましょう。
いずれ必要になるので。

これで、この文字の上で右クリックすると
"stm32l1xx.h"を開くというメニューが出てきます。
これでEWARM上から簡単に移動ができるようになります。

基本的にはこのstm32l1xx.hがベースになります。
いわゆる用語集でこのルールに基づいて記述しないと動きません。
(直接値放り込めば動きますがまさかそれはしないと思いますので)

ついでに前回やらかしてくれたconf.hも見に行きましょうか。
5099行目にありますね。
同じく右クリックから開くで飛べます。

~conf.hは一括でincludeの管理をしてます。
とりあえず今回は~gpio.h、rcc.h、usart.h、misc.hしか使わないので
これ以外はコメントアウトしちゃいましょう。
軽量化!!


さて、マイコンの初期化をこれからしますが、
必要なことは
必要な機能にクロックの供給をはじめにします。

マイコンの中には様々な機能が盛り込まれていますが、
これを動かすにはなにはともあれクロックを各機能に供給してあげないといけません。
というかこれがARMの特徴でもあります。
機能毎に供給を止めたり与えたりできるので、
不要な機能には供給しないことで省電力化がしやすくなっているチップです。
これを管理しているのがRCCです。

main.cにはつらつらと書いていってもいいのですが
RCC_configuration()という関数を作って区切りをつけたいと思います。

メイン関数の中にこれを記述します。



#include "stm32l1xx.h"
int main(void){
RCC_configuration();
}

void RCC_configuration(void){
//ここにクロック供給を書く
}



こんなかんじですね。


でもってLEDはPB6とPB7なのでPBのポートにクロックを供給します。

ここでデータシートのブロックダイアグラムが出てきます。
GPIOBはAHBのバスラインにつながっているのが見えます。

なのでこのAHBからクロックの供給を受けます。

stm32l1xx_rcc.cの1068行目を見てみましょう

ここに
void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState)
という関数があります。

これに従うことでクロックを供給することが出来ます。
実際にはこう記述して引数を渡します。
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);

こういった記述のルールを探すには
・リファレンスマニュアルを読む
・解説本(ARMマイコン徹底入門)や解説サイト
・stm32l1xx.cを熟読する
と言った方法で見つけることが出来ます。
初心者には絶望的にパパっとは見つかりません。

ここで小技ですが
RCC_AHBPeriphClockCmd
の上で右クリックすると「~定義に飛ぶ」というコマンドがあります。
これでさっきの~rcc.cに飛べれば記述的に間違ってないと言えます。
もちろん便利機能なのでどんどん使っていきましょう。

これでクロックの供給が出来ました。

クロックを供給したあとは外に出ていくピンを指定する必要があります。

RCCと同様に
メイン関数の中に
GPIO_configuration();
という関数を作って外に飛ばします。


ここまでをまとめると



#include "stm32l1xx.h"
int main(void)
{
RCC_configuration();
GPIO_configuration();

}

void RCC_configuration(void){
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
}

void GPIO_configuration(void){
//ここに処理を書く
}



こんなかんじですね。

GPIOの設定をするには
MODEとPIN番号とspeedを指定しなければなりません。
これを行うには事前に設定を決めてから
同時に1回で書き込みます

この事前に設定を決めるために設定を貯める入れ物を作ります。

実はメーカー側で既に規定してくれています。

stm32l1xx_gpio.hの142行目にこれらの設定をする構造体(GPIO_InitTypeDefという名前の箱)があります。

プログラムの基本
int c

でcという名前の変数を作ることができるの同じで
GPIO_InitTypeDef GPIO_Initstructure;
と書くことで

GPIO_Initstructureというなまえの構造体でその形はGPIO_InitTypeDefで定義されたもの

とすることが出来ます。

で、MODE等にアクセスするには
GPIO_Initstructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
と書くことでできます。
右辺がわについてはstm32l1xx_gpio.hに定義されています。
MODEについてはプッシュプルやフローティング等色々ありますが
機能毎にこうしなさいという内容がリファレンスマニュアルに書かれています。

ほんとに各ファイルの.cや.hやマニュアルを開いて睨めっこしないと書けないのがわかると思います。
(ちなみに解説本などを買えばリスト化して書いてくれてるので分かりやすいです)

さて、設定を決めたのでこれを流し込みます。

そのコマンドが
GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
です。~gpio.cの188行目にあります。

Pin7についても同様ですが、
同じ入れ物を使えるので、ピン番号だけ書き換えた後に同じようにGPIO_Initを叩けば設定できます。


これで、クロックの供給とピンへのヒモ付が完了しました。

マイコンはチップの中に機能があるので
外へ向かう機能の場合、ちゃんとピンへのヒモ付をしてあげないと飛び出すことが出来ません。

なのでUSARTに限らずどの機能を使うにも基本的には
・クロック供給(RCC)
・ピンの設定(GPIO)
の2つの手順は設定する必要があります。


ここまでをまとめると


#include "stm32l1xx.h"
int main(void)
{
RCC_configuration();
GPIO_configuration();

}

void RCC_configuration(void){
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
}

void GPIO_configuration(void){
GPIO_InitTypeDef GPIO_InitStructure;

GPIO_Initstructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOB, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOB, &GPIO_InitStructure);

}



こうなります。


で、実際のチカチカさせる部分はこう書きます

void LED_blue_toggle(void){
GPIOB->ODR ^= GPIO_Pin6;}

void LED_green_toggle(void){
GPIOB->ODR ^= GPIO_Pin7;}



これをメインルーチンのなかで呼び出します。
あとwhileで無限ループにしてLEDの処理を永久に回します。


最終的にこう

#include "stm32l1xx.h"
int main(void)
{
RCC_configuration();
GPIO_configuration();

while(1){
LED_blue_toggle();
LED_green_toggle();

}

void RCC_configuration(void){
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
}

void GPIO_configuration(void){
GPIO_InitTypeDef GPIO_InitStructure;

GPIO_Initstructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOB, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}

void LED_blue_toggle(void){
GPIOB->ODR ^= GPIO_Pin6;}

void LED_green_toggle(void){
GPIOB->ODR ^= GPIO_Pin7;}



しかし、コレでは動きません

メインの関数のからみて外にある外部関数を使う場合、
externの宣言をしておかないと「同じものとみなしてくれない」のです

ここでmain.hが登場します。

とりあえずmain.cにincludeしておきましょう。

呼び出し元を明確にするためにmain.cにdefineを書き込んでおきます。
#define MAIN_EXTERN

でもってmain.hのほうに以下の記述を入れておきます。

#ifdef MAIN_EXTERN

void RCC_configuration(void);
void GPIO_configuration(void);
void LED_blue_toggle(void);
void LED_green_toggle(void);

#else

extern void RCC_configuration(void);
extern void GPIO_configuration(void);
extern void LED_blue_toggle(void);
extern void LED_green_toggle(void);

#endif

これでヒモ付が出来ます。

さぁ、コンパイルしてボードを繋いでダウンロードしてみましょう。
ST-LINKの接続エラーが出る場合はUSBのポートをかえてみてください。
なんかドライバの方に原因があるそうですがようわからん。

実行をするとLEDが光るはずです。

が、消えているのが早すぎて目視ではわかりません。

一度ブレークしてステップインで動かしてみましょう。

これで付いたり消えたりが見えるはずです。

わざとディレイさせるにはsystickタイマーを覚えてからにしましょう。


最終的に

main.c

#define MAIN_EXTERN

#include "stm32l1xx.h"
#include "main.h"

int main(void)
{
RCC_configuration();
GPIO_configuration();

while(1){
LED_blue_toggle();
LED_green_toggle();
}
}

void RCC_configuration(void){
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
}

void GPIO_configuration(void){
GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOB, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}

void LED_blue_toggle(void){
GPIOB->ODR ^= GPIO_Pin_6;}

void LED_green_toggle(void){
GPIOB->ODR ^= GPIO_Pin_7;}




main.h


#ifdef MAIN_EXTERN

void RCC_configuration(void);
void GPIO_configuration(void);
void LED_blue_toggle(void);
void LED_green_toggle(void);

#else

extern void RCC_configuration(void);
extern void GPIO_configuration(void);
extern void LED_blue_toggle(void);
extern void LED_green_toggle(void);

#endif

こうなりました。
PR
COMMENT
name
title
text
color   Vodafone絵文字 i-mode絵文字 Ezweb絵文字
mail
URL
pass
secret
PREV ←  HOME  → NEXT
プロフィール
HN:
komyu/シュクレール/修造
性別:
非公開
自己紹介:
こうぶつはけものみみとのーびす(♀)とエリーン
主にROとTERAとラノベと雑多なkomyuの日記帳です。
新生FF14
TERA紋章しみゅ
ROサポートツール
タイムライン
RSSボットが記事更新をつぶやくのがほとんどっス…
ROキャラクター紹介


TERAキャラ紹介

シュクレール(バサ)



syuzo(エレ)



サケマス(アチャ)


その他サブ

ウリエルキゥィス(スレLv54)

Vermillion(サラLv56)

パズドラ

157,318,362
フレンド募集中
枠なきゃ増やす
最終プレイ3日以上になったら消す
カレンダー
10 2024/11 12
S M T W T F S
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
ツリーカテゴリ
ブログ内検索
最新コメント
[04/30 のな]
[03/22 NEIN]
[03/22 NEIN]
[10/31 イロイ]
[05/02 NONAME]
Copyright (C) 2024 のーびす監察日記 All Rights Reserved.
Photo by 戦場に猫 Template Design by kaie
忍者ブログ [PR]