STM32研究ノート_3 プログラミング基礎;アームコアアーキテクチャ

プログラミングの基礎

Keil エディターの設定

画像-20230413000523924

タブやスペースが適切に見えるかどうかに関係なく、コンパイラごとに設定が異なり、スペースの方が安全です。

ユーザー キーワード: 入力すると強調表示されます。

画像-20230413001147591

コードのヒント: (後の記号は、数文字の後にキーワードを表示するという意味です)

画像-20230413001314821

上記の 4 つの構成は global.prop ファイルに保存され、後でこのファイルを再インストールして保存することで構成を保存できます。

共通操作

シフトタブは全体的に左に移動し、ダイレクトタブは右に移動します。

関数変数のクイック ポジショニング: マジック ワンド出力ブラウズ情報。右クリックで goto 定義にジャンプします。

クイック コメント: // 記号があり、コード セグメントを選択した後、ワンクリックですばやくコメントできます。

ヘッダー ファイルをすばやく開く: ヘッダー ファイル名を右クリックし、ドキュメント xxx.h を開きます。

探す:画像-20230413011326761

交換は交換です。

ビルド出力ウィンドウでエラーをダブルクリックして、過去をすばやく見つけます。

ウィンドウ ビューをデフォルトの状態に戻す方法: window à Reset View to Defaults + Reset

C言語の基礎

stdint.h

c99 の標準ライブラリ ファイル。

画像-20230413020428445

画像-20230413020443388

ビット操作

& | ~ ^ << >> これ以上言うことはありません。

特定のビットに値を割り当てます: 1. 最初 & 他のビットを保持、この位置は 0、次に | 他のビットを保持、この位置は 1.temp &= 0xFFFFFFBF; temp |= 0x00000040;

  1. temp &= ~(1<<6); temp |= 1<<6;

マクロ定義

#define PI 3.14159

画像-20230413131117716

#define __set_task_state(tsk, state_value)   \
  do {
      
       (tsk)->state = (state_value); }  while (0)

プログラムが期待どおりに実行されるように、必ず do while(0) を使用してください。

マクロ定義に do{……}while(0) 形式を使う理由_ポテトパパのブログ - CSDN ブログ

マクロ定義は、制御フローへの影響を回避します. たとえば、マクロによって定義された関数で戻ることはより危険です.

画像-20230413131450340

マクロ定義は、(SQUARE(a++)) などのパラメーターの変更を避けるためにパラメーターを渡します。

画像-20230413131533236

画像-20230413022443594

外部

extern で宣言された関数または変数は、別のファイルで定義されていることを意味します。

画像-20230413022918348

typedef

typedef unsigned char uint8_t;

構造体

画像-20230413023046175

画像-20230413023139081

ポインタ

char *ptr="234";

コード仕様

タブは 4 文字に設定されています。

列の後に 80 文字の行。

画像-20230413033058738

画像-20230413033117662

比較的独立したコード ブロックの場合は、変数の間に空白行を追加します。

1 行に複数行のステートメントを記述しないでください。if 文も同様で、if 文の後に文が 1 つしかない場合でも、怠けて中括弧を追加しないでください。while の後に実行文がない場合は、中かっこは必要ありません。

左括弧は新しい行で始まります。

if、swich、case、for、do、while の後にスペースを追加します。

sizeof、typedof、alignof の後にスペースはありません。

ポインターの * は、データ型ではなく、変数名の近くにあります。

= + - < > * / % | & ^ <= >= == != ? : 左右にスペースを追加します。

単項演算子の後にスペースがありません & * + - ~ ! sizeof typeof alignof __attribute__ が定義されています。

++ – . -> 前後のスペースなし。

コンマとセミコロンの後にはスペースのみが続きます。

コメント /* content */ と content の間にスペースを追加します。

注釈仕様

画像-20230413034927343

画像-20230413034952309

画像-20230413035001669

星の数は 100 でなければなりません。行で区切られたコードの先頭。

関数の注釈:

画像-20230413035526319

画像-20230413035535796

画像-20230413035938271

画像-20230413035945902

コードのコメント:

画像-20230413040034734

コードの前に長すぎます。

識別子の命名: アンダースコアで区切られた小文字、これは Unix スタイルです。

一般的な反意語:

画像-20230413120036503

ループ変数は ijk を許可します。グローバル変数またはポインターであることを示すために、g_ p_ で始めることができます。

u8 u16 u32 の代わりに、次を使用します。

画像-20230413120241744

関数は変数のような名前です。

マクロ名はすべて大文字で、単語はアンダースコアで区切られています。

関数: 関数は 1 つの関数のみを実装します。

関数は空白行で区切られ、関数の後に export が続きます。

画像-20230413120402318

組み込み開発 Linux では goto を使用することが多く、これはクリーニング操作に非常に便利です。

関数のネストは推奨されません > 4 レイヤー。

この関数は、入力パラメーターの合理性を適切に処理する必要があり、エラーが発生した場合でもエラー メッセージを正確に返すことができます。

このファイルのスコープ内でのみ定義された関数変数は、静的に装飾されます。

変数を複数回使用しないことが最善です。

画像-20230413122654031

グローバル変数の使用を減らし、グローバル変数とローカル変数の重複を避けます。

初期値を使用するために、できるだけ初期化してください。直接代入または ?: 代入。

グローバル変数の初期化位置を明確にし、不要なデータ型変換を減らします。

カーネル アーキテクチャ

コアは ARM メーカーによって認定されており、ペリフェラルは他社によって追加されています。基板上の全体が黒い STM32 は、アーム会社のアーキテクチャと開発された半導体会社の間の協力の結果です。

画像-20230413193540763

F1 アーキテクチャ

画像-20230413194651347

画像-20230413194954346

アクティブ ユニットは、パッシブ ユニットへの通信を開始できます。

バスマトリクスを境にして左側がアクティブユニット、右側がパッシブユニットです。

ICodeはバスマトリクスを介さずにFLASHに直結されており、その中にプログラムが格納されているため、プログラムへのアクセスが非常に高速です。

画像-20230413195408442

ICode バスは、図の IBus に対応します。

画像-20230413195859793

周辺機器は、さまざまな周辺機器のニーズを満たすために、さまざまな周波数に分割されています。

皮質 M3 コア:

左上と右上がトレースデバッグ、左下がダウンロードです。

画像-20230413200045162

SDIO とクロック:

画像-20230413200248009

APB ペリフェラル:

画像-20230413200426202

Iコード:

画像-20230413200506259

また、時間厳守のコースウェアでは詳しく説明されていない内容もあります。上から順に、電源、電源管理、外部水晶発振器、ウォッチドッグ タイマーです。

画像-20230413200708790

さらに、相互接続された開発ボードは、ネットワーク モジュールのアクティブ ユニットも追加しますが、私たちのものはそうではありません。

F4 アーキテクチャ

画像-20230413201012608

ARM Cortex-M4 では、FSMC は外部メモリ インターフェイスを表す組み込みペリフェラルです。FSMC は、メモリ、LCD ディスプレイ、およびその他の外部デバイスへの接続をサポートし、高速データ転送とメモリ拡張を可能にして、ほとんどの組み込みシステムの要件を満たします。——ChatGPT

画像-20230413201237816

CCM は高速なアクセス速度でデータを保存しますが、DMA をサポートしていません。

バスクロック周波数:

AHB1/2:168/180MHz(最大)

APB1:42/45MHz(最大)

APB2:84/90MHz(最大)

システムの概略図は基本的にF1のものと同様です。

F7 アーキテクチャ

画像-20230413202136751

画像-20230413202154993

画像-20230413203743899

アドレス範囲

32 ビット マイクロコントローラ、32 ビット アドレス バス。

メモリセルはバイト単位でアドレス指定されます。つまり、バイト単位でアドレス指定される 2^32 個のストレージ ユニットがあります。

各ストレージ ユニットのアドレス指定範囲: 0x0000_0000~0xFFFF_FFFF。

メモリマップ

メモリ自体にはアドレスがなく、それにマップしました。

画像-20230413204709800

最初の 3 つは学習の焦点です。

画像-20230413204927606 画像-20230413204937494

画像-20230413204946174

登録マップ

レジスタはシングルチップマイクロコンピュータの内部制御構造であり、最終的な分析の目的は、レジスタを制御してシングルチップマイクロコンピュータを制御することです。

画像-20230413210100271 主に周辺レジスタの研究を行っています。

レジスタ アドレスを命名するプロセスは、レジスタ マッピングと呼ばれます。0x4001080c -> GPIOA_ODR など。

stm32 GPIO には、グループごとに 16 の IO ポートがあり、51 の 2 倍です。

画像-20230413210802320

名前: GPIOx_ODR。

アドレス オフセット: 最小アドレス 00 に基づいてオフセット値を追加します。

レジスタのリセット値: 0x0000_0000。

Register Bit Table: 各ビットのオフセット、名前、および許可を表示します。

画像-20230413211248709

ビット機能の説明: たとえば、1 はオン、0 はオフです。

レジスタの操作: 直観に反する方法は、レジスタ アドレスを直接操作することです。

*(unsigned int *)(0x4001_080c)=0xFFFF;

登録マップ:

#define GPIOA_ODR *(unsigned int *)(0x4001_080c)

GPIOA_ODR=0XFFFF;

しかし、数十万のレジスタがある場合、アドレスとマッピングをどのように計算するのでしょうか?

登録アドレス計算

  1. バス ベース アドレス/ペリフェラル ベース アドレス、BUS_BASE_ADDR。
  2. バス ベース アドレスのオフセット PERIPH_OFFSET に基づくペリフェラル。
  3. ペリフェラル アドレスに対するレジスタのオフセット REG_OFFSET、つまり上図の各レジスタのオフセット (0C)。

3 つの合計は、バス ベース アドレスを計算します。

バスベースアドレス: APB1 0X4000_0000、APB2 0X4001_0000、AHB 0X4001_8000。

画像-20230413212938834

画像-20230413212950580

メモリ マップでは、次のことがわかります。

画像-20230413213233899

たとえば、GPIOA、ペリフェラル ベース アドレス 0X4001_0000、オフセット 0X800. = 0X4001_0800.

レジスタ GPIOA CRH の 1 つは、GPIOA ペリフェラル ベース アドレスのオフセット アドレス 0X04 = 0X4001_0804 に基づいています。

バッチでレジスタ構造を定義すると非常に便利です。

画像-20230414003813622

左側では、構造も連続して格納されるため、7*4 の連続空間を定義します。

次に右のウェイで開始ポインタを定義し、アドレスを上から下に徐々に増やして格納します。

画像-20230414004250651 詳細は stm32f103xe.h ファイルにあります。

画像-20230414004919334

最初の数行の内容が block0 block1 に対応していることがわかります。

画像-20230414005711476

おすすめ

転載: blog.csdn.net/jtwqwq/article/details/130143921