プログラミングの基礎
Keil エディターの設定
タブやスペースが適切に見えるかどうかに関係なく、コンパイラごとに設定が異なり、スペースの方が安全です。
ユーザー キーワード: 入力すると強調表示されます。
コードのヒント: (後の記号は、数文字の後にキーワードを表示するという意味です)
上記の 4 つの構成は global.prop ファイルに保存され、後でこのファイルを再インストールして保存することで構成を保存できます。
共通操作
シフトタブは全体的に左に移動し、ダイレクトタブは右に移動します。
関数変数のクイック ポジショニング: マジック ワンド出力ブラウズ情報。右クリックで goto 定義にジャンプします。
クイック コメント: // 記号があり、コード セグメントを選択した後、ワンクリックですばやくコメントできます。
ヘッダー ファイルをすばやく開く: ヘッダー ファイル名を右クリックし、ドキュメント xxx.h を開きます。
探す:
交換は交換です。
ビルド出力ウィンドウでエラーをダブルクリックして、過去をすばやく見つけます。
ウィンドウ ビューをデフォルトの状態に戻す方法: window à Reset View to Defaults + Reset
C言語の基礎
stdint.h
c99 の標準ライブラリ ファイル。
ビット操作
& | ~ ^ << >> これ以上言うことはありません。
特定のビットに値を割り当てます: 1. 最初 & 他のビットを保持、この位置は 0、次に | 他のビットを保持、この位置は 1.temp &= 0xFFFFFFBF; temp |= 0x00000040;
temp &= ~(1<<6); temp |= 1<<6;
マクロ定義
#define PI 3.14159
#define __set_task_state(tsk, state_value) \
do {
(tsk)->state = (state_value); } while (0)
プログラムが期待どおりに実行されるように、必ず do while(0) を使用してください。
マクロ定義に do{……}while(0) 形式を使う理由_ポテトパパのブログ - CSDN ブログ
マクロ定義は、制御フローへの影響を回避します. たとえば、マクロによって定義された関数で戻ることはより危険です.
マクロ定義は、(SQUARE(a++)) などのパラメーターの変更を避けるためにパラメーターを渡します。
外部
extern で宣言された関数または変数は、別のファイルで定義されていることを意味します。
typedef
typedef unsigned char uint8_t;
構造体
ポインタ
char *ptr="234";
コード仕様
タブは 4 文字に設定されています。
列の後に 80 文字の行。
比較的独立したコード ブロックの場合は、変数の間に空白行を追加します。
1 行に複数行のステートメントを記述しないでください。if 文も同様で、if 文の後に文が 1 つしかない場合でも、怠けて中括弧を追加しないでください。while の後に実行文がない場合は、中かっこは必要ありません。
左括弧は新しい行で始まります。
if、swich、case、for、do、while の後にスペースを追加します。
sizeof、typedof、alignof の後にスペースはありません。
ポインターの * は、データ型ではなく、変数名の近くにあります。
= + - < > * / % | & ^ <= >= == != ? : 左右にスペースを追加します。
単項演算子の後にスペースがありません & * + - ~ ! sizeof typeof alignof __attribute__ が定義されています。
++ – . -> 前後のスペースなし。
コンマとセミコロンの後にはスペースのみが続きます。
コメント /* content */ と content の間にスペースを追加します。
注釈仕様
星の数は 100 でなければなりません。行で区切られたコードの先頭。
関数の注釈:
コードのコメント:
コードの前に長すぎます。
識別子の命名: アンダースコアで区切られた小文字、これは Unix スタイルです。
一般的な反意語:
ループ変数は ijk を許可します。グローバル変数またはポインターであることを示すために、g_ p_ で始めることができます。
u8 u16 u32 の代わりに、次を使用します。
関数は変数のような名前です。
マクロ名はすべて大文字で、単語はアンダースコアで区切られています。
関数: 関数は 1 つの関数のみを実装します。
関数は空白行で区切られ、関数の後に export が続きます。
組み込み開発 Linux では goto を使用することが多く、これはクリーニング操作に非常に便利です。
関数のネストは推奨されません > 4 レイヤー。
この関数は、入力パラメーターの合理性を適切に処理する必要があり、エラーが発生した場合でもエラー メッセージを正確に返すことができます。
このファイルのスコープ内でのみ定義された関数変数は、静的に装飾されます。
変数を複数回使用しないことが最善です。
グローバル変数の使用を減らし、グローバル変数とローカル変数の重複を避けます。
初期値を使用するために、できるだけ初期化してください。直接代入または ?: 代入。
グローバル変数の初期化位置を明確にし、不要なデータ型変換を減らします。
カーネル アーキテクチャ
コアは ARM メーカーによって認定されており、ペリフェラルは他社によって追加されています。基板上の全体が黒い STM32 は、アーム会社のアーキテクチャと開発された半導体会社の間の協力の結果です。
F1 アーキテクチャ
アクティブ ユニットは、パッシブ ユニットへの通信を開始できます。
バスマトリクスを境にして左側がアクティブユニット、右側がパッシブユニットです。
ICodeはバスマトリクスを介さずにFLASHに直結されており、その中にプログラムが格納されているため、プログラムへのアクセスが非常に高速です。
ICode バスは、図の IBus に対応します。
周辺機器は、さまざまな周辺機器のニーズを満たすために、さまざまな周波数に分割されています。
皮質 M3 コア:
左上と右上がトレースデバッグ、左下がダウンロードです。
SDIO とクロック:
APB ペリフェラル:
Iコード:
また、時間厳守のコースウェアでは詳しく説明されていない内容もあります。上から順に、電源、電源管理、外部水晶発振器、ウォッチドッグ タイマーです。
さらに、相互接続された開発ボードは、ネットワーク モジュールのアクティブ ユニットも追加しますが、私たちのものはそうではありません。
F4 アーキテクチャ
ARM Cortex-M4 では、FSMC は外部メモリ インターフェイスを表す組み込みペリフェラルです。FSMC は、メモリ、LCD ディスプレイ、およびその他の外部デバイスへの接続をサポートし、高速データ転送とメモリ拡張を可能にして、ほとんどの組み込みシステムの要件を満たします。——ChatGPT
CCM は高速なアクセス速度でデータを保存しますが、DMA をサポートしていません。
バスクロック周波数:
AHB1/2:168/180MHz(最大)
APB1:42/45MHz(最大)
APB2:84/90MHz(最大)
システムの概略図は基本的にF1のものと同様です。
F7 アーキテクチャ
アドレス範囲
32 ビット マイクロコントローラ、32 ビット アドレス バス。
メモリセルはバイト単位でアドレス指定されます。つまり、バイト単位でアドレス指定される 2^32 個のストレージ ユニットがあります。
各ストレージ ユニットのアドレス指定範囲: 0x0000_0000~0xFFFF_FFFF。
メモリマップ
メモリ自体にはアドレスがなく、それにマップしました。
最初の 3 つは学習の焦点です。
登録マップ
レジスタはシングルチップマイクロコンピュータの内部制御構造であり、最終的な分析の目的は、レジスタを制御してシングルチップマイクロコンピュータを制御することです。
主に周辺レジスタの研究を行っています。レジスタ アドレスを命名するプロセスは、レジスタ マッピングと呼ばれます。0x4001080c -> GPIOA_ODR など。
stm32 GPIO には、グループごとに 16 の IO ポートがあり、51 の 2 倍です。
名前: GPIOx_ODR。
アドレス オフセット: 最小アドレス 00 に基づいてオフセット値を追加します。
レジスタのリセット値: 0x0000_0000。
Register Bit Table: 各ビットのオフセット、名前、および許可を表示します。
ビット機能の説明: たとえば、1 はオン、0 はオフです。
レジスタの操作: 直観に反する方法は、レジスタ アドレスを直接操作することです。
*(unsigned int *)(0x4001_080c)=0xFFFF;
登録マップ:
#define GPIOA_ODR *(unsigned int *)(0x4001_080c)
GPIOA_ODR=0XFFFF;
しかし、数十万のレジスタがある場合、アドレスとマッピングをどのように計算するのでしょうか?
登録アドレス計算
- バス ベース アドレス/ペリフェラル ベース アドレス、BUS_BASE_ADDR。
- バス ベース アドレスのオフセット PERIPH_OFFSET に基づくペリフェラル。
- ペリフェラル アドレスに対するレジスタのオフセット REG_OFFSET、つまり上図の各レジスタのオフセット (0C)。
3 つの合計は、バス ベース アドレスを計算します。
バスベースアドレス: APB1 0X4000_0000、APB2 0X4001_0000、AHB 0X4001_8000。
メモリ マップでは、次のことがわかります。
たとえば、GPIOA、ペリフェラル ベース アドレス 0X4001_0000、オフセット 0X800. = 0X4001_0800.
レジスタ GPIOA CRH の 1 つは、GPIOA ペリフェラル ベース アドレスのオフセット アドレス 0X04 = 0X4001_0804 に基づいています。
バッチでレジスタ構造を定義すると非常に便利です。
左側では、構造も連続して格納されるため、7*4 の連続空間を定義します。
次に右のウェイで開始ポインタを定義し、アドレスを上から下に徐々に増やして格納します。
詳細は stm32f103xe.h ファイルにあります。最初の数行の内容が block0 block1 に対応していることがわかります。