Arduinoでモーターを動かせたので、その回路をそのままNUCLEO-F411REで使ってみよう。
NUCLEOはArduinoと同じピン配置のコネクタを持っているので、そのまま移し替えられるはずだ。
D9はPC7、A0はPA0だ。
PA0はAnalog_GPIOだとして、PC7はどれにすればよいのだ?
STM32では、PWMはタイマの項目になるらしい。
http://visualgdb.com/tutorials/arm/stm32/pwm/
Duty比は、PeriodとPulseで決まるらしい。
この設定だと、こうなった。
93.028 ÷ (93.028 + 139.97) = 40%くらい
200 ÷ 500 = 40%
おお、比率はあってる。
プリスケーラの40000は、まねしただけなのだけど、どういう関係なのだ?
STM32F4 PWM tutorial with TIMERs - STM32F4 Discovery
タイマのtickが、デフォルト周波数 / (prescaler+1)になる。
TIM3は、APB1につながっているので、デフォルト周波数はAPB1のものになろう。
などと探すまでも無く、Clock ConfigurationにTimer clocksが載っていた。
今は84MHzになっている。
tick = 84MHz / (40001) = 2100Hzくらい
PWM周波数=tick / (Period+1)なので、
pwm = 2100くらい / 501 = 4.19Hzくらい
4.19Hzは239msecくらいだ。
93.028 + 139.97は233msecくらいで、5msecくらい違うのだが、誤差の範囲でよいのか?
tick換算すると10tickくらいになってしまうのだが。
値が適当すぎたので、もうちょっと計算しやすい値にしよう。
tick = APB1 / (Prescaler+1) = 84MHz / 8400 = 10kHz
PWM = tick / (Counter Period+1) = 10kHz / 500 = 20Hz
周期 = 1 / 20Hz = 50msec
Duty比 = Pulse / (Counter Period+1) = 200 / 500 = 40%
で、1周期50msec、Hなのは50msecの40%で20msecになるはず!
19.54ms + 29.311ms = 48.9msecくらいなので、ちょっと短いか。。。
元が内蔵16MHzだと、そこまで精度が出ないということか?
最大4%くらいか。
短い方に振れると、50msecが48msecくらいになるな。
うん、こんなもんとしておこう。
ここまでのソースは、こちら。
機器の構成は、こうなる。
SWはチャタリングするし、ポテンショメーターも値がバタバタするので、ヒステリシスを持たせたい。
今はタスクの先頭でPWM開始を行っているだけだが、SW2つとADCもここに集めてしまって、input/output用タスクにした方がよいだろうか。
あるいは、ここはタスク間通信で制御要求されたものをoutputするだけにして、inputは別タスクにした方がよいだろうか。
inputのごとにそれぞれタスクを作るというやり方もある。
タスクが多くなるとメモリも使うし、ディスパッチが増えて効率が悪くなる。
かといって1つのタスクに機能を詰め込むと、OS使ってるのにわかりづらい…となってしまう。
難しいねぇ。
このくらいだったらどれでもよさそうなので、SWとVOLをタスク分けしてみようか。
SWは同じタイミングで全部読み取りたいけど、VOLとはタイミングを変えたいのだ。
1つにまとめてもできるけど、まあ、分けた方がきれいな気がする。
私の設計って、いつもながら適当よね。。。
というわけで、次回は定周期で値を読み取るタスクにしていこう。
0 件のコメント:
コメントを投稿
コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。
注: コメントを投稿できるのは、このブログのメンバーだけです。