ガレスタさんのDIY日記

電子回路、Web、組み込み、自作エフェクターを語るblog

CubeMX4.20のHSEクロック関連出力コードのバグ?

CubeMX4.20のコード出力バグッぽいの見つけたのでかいときます。
前までのVerで動いてたいのですがHSE(外部クロック)を選択した際動かなくなったのでいろいろ調べてたら海外で同じような事例を発見

http://www.openstm32.org/forumthread4665

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE;

のとこがなんかまずいみたいで

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;

とすればよいみたい

f:id:gsmcustomeffects:20170401235340p:plain

ここ毎回出力されるからこまるw

2017/5/8追記
現状のCubeMX4.21では改善されました

ZOOM MS50g,MS70CDRのMIDI制御について1

今回はZOOM社のマルチストンプのMIDI制御についてです。

一年前ぐらいにUSBHOSTでMIDI制御しましたがいろいろ発見があったので今回こうして書いているわけです。


続きを読む

Ac6 SystemWorkbench for STM32でメモリ使用量を%で出力する方法

コードサイズの出力

通常はコードサイズが出るだけだがXlinkerオプションに -print-memory-usageを追加することで現在どの程度フラッシュを使用しているかわかります。
f:id:gsmcustomeffects:20170418200028p:plain

プロジェクトのプロパティ

プロパティを開いてC/C++Build/Setting/MCU GCC Linker/Miscellaneousからオプションを追加します。

-print-memory-usage

を追加します

f:id:gsmcustomeffects:20170418200606p:plain

そのあとリビルドするとできる。

尚タイトルは試しでAc6でやっているのでそうなっているがEclipseベースIDEであれば何でもできると思う。

参考文献


gcc.gnu.org

この辺にも書いてあります

stackoverflow.com

AtollicTrueStudioでHex,binを生成する方法(自分用メモ

当たり前のことなので自分用メモとしておきます。

Hex,binの生成方法

プロジェクトのプロパティを選択

C/C++Buid>>Setting>>ToolSetting>>Other>>Output format

IntelHexを選択

f:id:gsmcustomeffects:20170417214842p:plain

あとはリビルド

コマンドから作る方法

C/C++Buid>>Setting>>BuildSteps>>PostBuild stepsで

arm-atollic-eabi-objcopy -O binary プロジェクト名.elf プロジェクト名.bin


を入力する

f:id:gsmcustomeffects:20170417215312p:plain

Debugフォルダに生成される

f:id:gsmcustomeffects:20170417215346p:plain

C言語可変引数マクロについて

マイコンのDEBUG関数関連見てて

#if defined(DEBUG_ENABLE)
#if defined(DEBUG_SEMIHOSTING)
#define DEBUGINIT()
#define DEBUGOUT(...) printf(__VA_ARGS__)
#define DEBUGSTR(str) printf(str)
#define DEBUGIN() (int) EOF

#else
#define DEBUGINIT() Board_Debug_Init()
#define DEBUGOUT(...) printf(__VA_ARGS__)
#define DEBUGSTR(str) Board_UARTPutSTR(str)
#define DEBUGIN() Board_UARTGetChar()
#endif /* defined(DEBUG_SEMIHOSTING) */

的な”・・・”を多用したやつ見かけて調べてみた。

可変引数と呼ばれているみたいだ。

gccでは __VA_ARGS__ という記述でできるみたい。

printfなんかは引数が変化するのでラッピングするのは結構難しいけどこれ使うと結構いい感じにできるっぽい

STM32でADCをやってみる2(DMAを使ったレギュラ変換)

前回は単一チャンネルの変換を行ったが今回はDMAを使ったものをやって行こうと思う。

とりあえずADCおさらい

ADCは変換終了フラグ(EOC)を見てDRレジスタを見に行くことで変換データを得ることができる。

f:id:gsmcustomeffects:20170409035725p:plain

上記の図のようにシーケンスの終了でもフラグが立つ(EOS)
二つのフラグを見てソフトウエア的に行うこともできるがタイミングがずれるとDRのデータが上書きされてしまう。

それを防ぐ仕組みにオーバーランというものある。
これはデータを保護できるがそのあとの変換値は破棄されてしまうので注意が必要だ

f:id:gsmcustomeffects:20170409040231p:plain

そのため複数チャンネルを変換する場合EOCフラグをトリガとしてDMAでレジスタ→メモリを実現したほうがソフト的な介在がなくなるので楽に処理できる。

マニュアル曰く(RM0316 345ページ)

変換されたチャネルの値は特定のデータレジスタに格納されるので、複数のチャネルの変換には
DMA の使用が便利です。これによって、ADCx_DR レジスタにすでに格納されているデータの損失を防ぐことができます。
DMA モードが有効なとき(ADCx_CFGR レジスタの DMAEN ビットがシングル ADC モードで 1 にセットされている場合、またはデュアル ADC モードで MDMAが0b00 以外に設定されている場合)、
各チャネルの変換後、DMA リクエストが生成されます。これにより、変換データを ADCx_DR レジスタからソフトウェアで選択した場所へ転送することができます。
これにもかかわらず、DMA が DMA 転送リクエストを時間内に処理できなかったためにオーバーランが発生した場合(OVR=1)、ADC は DMA リクエストの生成を停止し、新しい変換に対応するデータ
は DMA によって転送されません。
これは、RAM に転送されるすべてのデータを有効とみなすことができることを意味します。

要するにCH変換ごとにDMAリクエストが生成されるということ。
オーバーランが発生するとDMAがとまる。
OVRMODを適切に処理するか頻繁に止まるようならDMAを時間内に処理できるように変換自体の速度を下げておくなど工夫が必要だ。

DMAのモードには

  • DMA ワンショットモード(DMACFG=0)
  • DMA サーキュラモード(DMACFG=1)

の2つがあり

ワンショットは一回きりの転送になります

f:id:gsmcustomeffects:20170409042453p:plain

一方サーキュラは連続的にADCのCH変換が終わるたびにDMAリクエストが生成するので連続的なストリームが構成できる。

f:id:gsmcustomeffects:20170409042740p:plain

さっそくやっていく

CubeMXでADCを設定していく。

f:id:gsmcustomeffects:20170409043833p:plain

ADCの詳細設定

f:id:gsmcustomeffects:20170409043955p:plain

DMAの設定

f:id:gsmcustomeffects:20170409044035p:plain

ここでアドレスのインクリメントにチェックを入れておくといい感じに配列に格納できる。

ハードウエア

前回と同じでこれにPA_5、PA_4を追加して2CHを読んでいる点だ

f:id:gsmcustomeffects:20170408045403j:plain

コード

参考までに動いたコードを示しておく
ADC終了時に呼ばれるコールバック内にprintfを入れてUART出力している。


動作例

Teratermではこんな感じに2CH読めている。

f:id:gsmcustomeffects:20170409050119p:plain

Expressionではこんな感じ

f:id:gsmcustomeffects:20170409050225p:plain

まとめ

3日間ぐらいかけてADCやってみたんだけど何だかんだDMAを使ったのが一番簡単だねぇ
DMAといったら結構難しいイメージあったけどCubeMXのおかげでほとんど設定してくれるのでかなり楽ですね。

3日間一緒に検討してくれたリアルテック先生には感謝です。

realteck-blog.netlify.com

2017/5/18追記

お恥ずかしいお話なのですがオカダといろいろやってて複数のADCを使うとMainにブレーク立てても帰ってこないと2日間ぐらい悩みました。

f:id:gsmcustomeffects:20170518003058p:plain

んで上記の図のようにこいつのADCには低速チャネルもあるんです。
12ビット精度で変換する場合最低でも14サイクルかかります
f:id:gsmcustomeffects:20170518003238p:plain

高速の場合Cubeで19.5サイクルにすればよいのですが低速の部分も19.5にしてました・・・・・ほんと雑魚wwww

なので皆さんはこんなバカなことで時間とかしちゃだめですよ!

直すとちゃんと動くf:id:gsmcustomeffects:20170518003433p:plain