RCCの設定
マイコンを動かすのに必須なクロックの設定。
GPIOの続きとして、CubeIDEが生成するSystenClock_Config関数の中身を見ていく形で動きを追ってみます。
先に言っておきますが、SystemClock_Configとほとんど同じ動きになったのでそのまま使って良いと思います…
GPIOの時と同じ事を書きますが、本記事はSTM32G030シリーズでの内容になります。
RCCの設定に関してはGPIOとは違い、ハード的な仕様の違いがかなり大きいです。
私が見つけられた限りで大きな差異がある所も書きますが、もし参考にされる場合はご自身が使用するシリーズのマニュアルで必ず確認してください。
HSIのみを使う場合
クロックの逓倍機能を持たないC0シリーズではHSIまたはHSEを使うことになります。
今回確認したのはSTM32C011F4P6です。
↑CubeIDE上でのクロックツリー
内蔵クロックであるHSIが48MHz固定です。
なのでこの48MHzを分周することしかできません。
HSI設定ビット
FLASH->ACR
LL_FLASH_SetLatency()でアクセス。
コアクロック(HCLK)によってFlash領域へのアクセスに一定のウェイトが必要なので、その設定を行います。
↑G0シリーズマニュアルから引用
HSION
RCC->CRのHSIONビット。名前の通りHSIを有効化します。
LL_RCC_HSI_Enable()
しかしCRレジスタのリセット値でHSIONビットがセットされているように、初期状態でHSIは有効です。
なので省略しても動くとは思います。
HSITRIM
LL_RCC_HSI_SetCalibTrimming()
HSIの校正用。よくわかってないです
HSIDIV
HSIの分周比を決めます。
LL_RCC_SetHSIDiv()
HPRE
AHBクロックの分周比を決めます。
メモリーやDMAはAHBクロックです。
LL_RCC_SetAHBPrescaler()
SW
システムクロックのソースを決めます。
ここでHSI、HSE、LSE、PLL等、どのクロックを使うのか?を設定します。
LL_RCC_SetSysClkSource()
SWS
LL_RCC_SetSysClkSource()と対になるような関数としてLL_RCC_GetSysClkSource()があり、
この関数のチェック先がSWSビットです。
SWも読み込みはできますが、読み込み専用であるこちらのビットで確認するのがより確実でしょう。
SWSはSWと同じCFGRレジスタにあり、3~5ビットが割り当てられています。
なのでSW << 3と同じ値になればOKです、
PPRE
ペリフェラル(APB)へのクロック分周比を決めます。
LL_RCC_SetAPB1Prescaler()
HSIの場合設定する箇所は少ないです。
特にHSI48をそのまま使うなら実質HSIONビットやSysClkソースの設定くらいになるかもしれません。
PLLクロックを使う場合
HSIとの共通部分
FLASH、HSION、AHB、APB1、HPRE、PPRE、SWおよびSWSは共通です。
HSIをEnableにした後からPLLの設定に移ります。
PLLSRC
PLLのクロックソースを決めます。
LL_RCC_PLL_ConfigDomain_SYS()の第1引数。
シリーズによって大きく異なる部分
PLLM
PLLに入力するHSIクロックの分周比を決めます。
ここで小題にあるようにシリーズ毎の違いが大きく現れます。
まず今回メインとしているG0シリーズの場合です。
このシリーズではHSIが16MHzであり、
そしてPLLへの入力周波数は4~16MHzとなっています。
※RM0444、P166
次にSTM32F3シリーズのマニュアルRM0316を確認しました。
これによるとHSIは8MHzであり、PLL入力として利用するために2分周できます…という記述がありました。
※RM0316、P128
F3シリーズ全般ではないですが、例えばNucleoF303K8にも用いられているF303K8T6も該当します。
さらにハイパフォーマンスモデルのF4シリーズの場合、PLL(VCO?)への入力周波数は1~2MHzの範囲で、かつ2MHzが推奨されています。
※RM0090、P166
以上のようにPLLへの入力周波数の設定はシリーズ毎の差異が大きいです。
G0シリーズの場合HSIであるならそのまま、HSEを使うのであれば4MHz以上の発振回路を使うことだけ留意すれば良いですが、より高機能なシリーズを使う際には設定がまったく異なる点に注意してください。
PLLクロックの確定
PLLN
PLLの逓倍数を決めます。
G0では最小値が8、最大値が86と記載されています。
PLLNで逓倍された周波数は下限が64、上限が344MHzである必要があります。
PLLR
PLLの最終段で、分周します。
G0の場合、PLLR後の周波数が64MHz以下である必要があります。
最終的にPLLでのクロックは以下のように求められます。
PLL中間クロック = PLL入力クロック * (PLLN/PLLM)
→PLLMが1であるなら、PLL入力*PLLN
PLL出力クロック = PLLR中間クロック / PLLR
PLLの有効化
PLLON
HSIONビットと同様で、PLLを有効化します。
クロックが停止するディープスリープモードに入ると自動的にクリアされます。
PLLREN
PLLクロック出力を有効化します。
PLLRDY
0の時アンロック、1の時ロック状態でロックされるまで待ちます。
まとめ
PLLMの設定がもっとも大きく異なる点でしたが、LLライブラリ自体にも異なる点があり、
移植性が高いプログラムにするのはなかなか難しそうです。
最後に一連のレジスタを設定し、64MHzのクロックを出力するプログラムを置いておきます。
…が、最初にも言った通り、CubeIDEが生成するSystemClock_Conifgとほとんど同じのでそのまま使った方が良いのでは、とすら思います。
参考程度にでもなれば幸いです。

0 件のコメント:
コメントを投稿