TIM1は外部へ信号を出力する.任意のデューティー比のパルスを生成する
----モータ制御回路入門----


タイマーというのは、カウンタでXXX回数えたら、割り込みを入れてくれる回路である、そんなことを書きました.
ここでは、それに反しまして、割り込みを発生しないタイマの使い方を解説します.

タイマーを使って、パルスを発生させたいとき、そのやりかたは、2つあります.
やり方1:  タイマーに等間隔で割り込んでもらって、割り込みルーチンでHIGH/LOWの信号を生成させる.
やり方2:  タイマーそのものにハードウエア的にHIGH/LOWの信号を生成させる.割り込みルーチンは不要.

ここでは、やり方2について説明します.だから割り込みはナシなんです.

表題がモーター制御回路となっていますが、もちろんやり方2でLEDをチカチカさせることもできます.
LEDチカチカの場合は周波数が目に見えるほど低い10Hzぐらいだっていうだけの違いにすぎませんから.
モーター制御回路の周波数は数100Hz以上です.


実はこの、周波数が低いか高いかが、やり方1を選ぶかやり方2を選ぶかの分かれ道になります.

やり方1では、
割り込みにともなうレジスタのスタック退避などのオーバーヘッドがありますし、たかがポートの論理操作ごときに数サイクルのマシンサイクルを消費しますので、動作速度が遅くなります.
また、UARTを併用していたりするとそちらの割り込みが入ってきて、ポート操作が手遅れになったりしかねません.
つまり、ソフトウエアが介在するやり方1だと、あまりにも高周波の信号発生はリスキーだということが一般に言えます.
モーター制御のような、物理的な実体の動きを司る制御回路には安全性の面であまりよろしくない.
わたし的には、やり方1では50Hzぐらいまでの信号生成までっていうのがわたしの脳内イメージです.

そこでやり方2が解決策として登場します.
やり方2は、ことポートの操作に関しては(初期化時を除いて)ソフトウエアの働きは不要です.
ハードウエアが勝手に信号を生成してくれるので、高信頼性です.
STM8S-DISCOVERYは源発振が16MHzですから、数MHzぐらいまでの信号発生が可能です.
モーター制御回路で数MHzっていうのはほとんど無いです.



TIM1でコンプリメンタリな1kHzを発生させる

1kHzというとそれなりに高速な信号ですので、目には見えません.
実際に観測するにはオシロスコープが必要になります.
コンプリメンタリとは、下記の波形のように、同じ周期同じ位相ですが極性が反転している信号同士のことをコンプリメンタリ信号と呼びます.


コンプリメンタリ信号は、モーター制御回路と深いつながりがあります.
モーター制御回路には下図の回路がよく使われます.これはH型をしているのでHブリッジと呼ばれます.
トランジスタを4つ使ってモーターへ流す電流方向を逆転させる作用があり、下左図を正転とすると、下右図は逆転となります.
トランジスタのベースに与える信号は、上側のPNPトランジスタをオンするには負極性パルスが、下側のNPNトランジスタをオンするには正極性パルスです.
この、正極性パルスと負極性パルスのペアが、コンプリメンタリ信号というわけです.
 

生成したいコンプリメンタリ信号の仕様をこの表のように決めます.

STM8S105C6
STM8S-DISCOVERYの場所
備考
波形出力ピン
TIM1_CH1    PC1  26ピン  ※1
CN2-2
PC1は基板上のSB3のジャンパ変更が必要   ※2
TIM1_CH1N  PB0  22ピン  ※1    (PC1のコンプリメンタリ)
CN3-10 option byte書き換えが必要   ※3
option byteとはなにかはこちらを読んでください
波形周波数
1kHz


波形duty
TIM1_CH1  30%

duty50%だと極性がわからんのであえて30%-70%とする
TIM1_CH1N  70%
デッドタイム
64uSec

デッドタイムとはなにかはこちらを読んでください
BREAK機能
あり

LOWでBREAKとする
BREAK入力ピン
TIM1_ETR   PB3  19ピン   ※1
CN3-7
option byte書き換えが必要   ※3

※1   STM8S105C6のピンアサインは、IC自体で決まっているので変更はできません.
ピンアサインがどうなっているかはこちら(pdf)を参照してください.

※2   オリジナルのSTM8S-DISCOVERY基板はTIM1_CH1はタッチパネル機能に使われており、オリジナルではCN2-2に接続されていません.
ハンダごてで改造が必要です.
下の写真のようにSB3のハンダジャンパーを付け替えてください.
写真がわかりにくいかもですが、@ABと3つのランドが並んでいるとして、@+Aをハンダでショートさせています.
(オリジナルのSTM8S-DISCOVERYではA+Bがハンダショートされています)
この改造によってTIM1_CH1がCN2-2に接続されます.


※3   PB0にTIM1_CH1Nをアサインするためには、option byteを書き換えなくてはいけません.
option byteのつぎの箇所を書き換えます.option byteの書き換え方法はこちらのページです.
afterでは、PB3=TIM1_ETR、PB0=TIM1_CH1Nに設定されていることがわかります.
before

after




ソースコードの解説

こちらからworkspaceをダウンロードしてください.
下記のソースコードはproject test06です.
--------------------------------
#include "stm8s.h"
void main(void)
{
  CLK_ClockSwitchConfig ( CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSE, DISABLE, CLK_CURRENTCLOCKSTATE_DISABLE );
  TIM1_DeInit();
  TIM1_TimeBaseInit( 15, TIM1_COUNTERMODE_UP, 1000, 0 );
  TIM1_OC1Init( TIM1_OCMODE_PWM1, TIM1_OUTPUTSTATE_ENABLE, TIM1_OUTPUTNSTATE_ENABLE, 300, TIM1_OCPOLARITY_HIGH, TIM1_OCNPOLARITY_HIGH, TIM1_OCIDLESTATE_RESET, TIM1_OCNIDLESTATE_SET );
  //TIM1_BDTRConfig( TIM1_OSSISTATE_ENABLE, TIM1_LOCKLEVEL_OFF, 0xff, TIM1_BREAK_DISABLE, TIM1_BREAKPOLARITY_LOW, TIM1_AUTOMATICOUTPUT_ENABLE);
  TIM1_Cmd(ENABLE);
  TIM1_CtrlPWMOutputs(ENABLE);
  while(1) {    }     // Main loop
}
--------------------------------

CLK_ClockSwitchConfig ( CLK_SWITCHMODE_AUTO, CLK_SOURCE_HSE, DISABLE, CLK_CURRENTCLOCKSTATE_DISABLE );
クロック設定をしています.クロック設定についてはこちらのページを参照して思い出してください.
この引数でこの関数をcallすると、外部水晶発振子の16MHzがCPUやタイマーに供給されることになります.
タイマに16MHzが供給されるということを憶えておきましょう.

TIM1_DeInit();
タイマTIM1を使います.初期化します.この初期化は不要かもしれませんが念のため入れておきます.

●TIM1_TimeBaseInit( 15, TIM1_COUNTERMODE_UP, 1000, 0 );
この関数の理解は重要です.この関数の 詳しい解説はこちらのページを参照してください.
ここから先に進むために理解しておくべきことは、16MHzが16分周されて1MHzになり、1MHzを1000カウントして1kHzになる、ということです.

●TIM1_OC1Init( TIM1_OCMODE_PWM1, TIM1_OUTPUTSTATE_ENABLE, TIM1_OUTPUTNSTATE_ENABLE, 300, TIM1_OCPOLARITY_HIGH, TIM1_OCNPOLARITY_HIGH, TIM1_OCIDLESTATE_RESET, TIM1_OCNIDLESTATE_SET );
この関数の使い方を知るのがこのページの最重要事項です.あとで解説します.

//TIM1_BDTRConfig( TIM1_OSSISTATE_ENABLE, TIM1_LOCKLEVEL_OFF, 0xff, TIM1_BREAK_DISABLE, TIM1_BREAKPOLARITY_LOW, TIM1_AUTOMATICOUTPUT_ENABLE);
コメントアウトしてあります.
デッドタイムを挿入したり、BREAK機能を使うときにはコメントを外します.
あとで解説します.

TIM1_Cmd(ENABLE);
TIM1_CtrlPWMOutputs(ENABLE);
タイマTIM1を動かします.PWM出力をオンします.



TIM1_OC1Init()とTIM1_BDTRConfig()の引数の解説

波形観測点:
TIM1_CH1     PC1(26pin)(CN2-2)  SB3のジャンパ変更が必要
TIM1_CH1N   PB0(22pin)(CN3-10)のoption byte操作が必要
TIM1_BKIN    PE3(37pin)(CN4-1)

project
TIM1_OC1Init()引数
TIM1_BDTRConfig()引数 出力信号
TIM1_CH1/TIM1_CH1N
なにが起きたかの解釈
test06
TIM1_OCMODE_PWM1,
TIM1_OUTPUTSTATE_ENABLE,
TIM1_OUTPUTNSTATE_ENABLE,
300,
TIM1_OCPOLARITY_HIGH,
TIM1_OCNPOLARITY_HIGH,
TIM1_OCIDLESTATE_RESET,
TIM1_OCNIDLESTATE_SET
callしない
1kHz
duty30%/duty70%
@源発振クロックは16MHzに設定されている.
Aそれを16分周して1MHzでカウンタが動く.
Aカウンタは0〜999までカウントアップしてグルグル回る.1MHzで1000カウントするので1kHzになる.
B閾値300でカウンタと比較した結果をパルスとして出す.
パルスを出すピンは、TIM1_CH1とTIM1_CH1Nだと決まっている.
BTIM1_CH1には、duty30%のパルスが出る.
BTIM1_CH1Nには、その反転パルスであるduty70%のパルスが出る.

この仕組みは下図のタイミングチャートに従っている.
カウンタは青い線のように0〜999まで動いている.
閾値は300に設定されている.
比較結果がTIM1_CH1とTIM1_CH1Nに出力されている.

test06b
TIM1_OCMODE_PWM1,
TIM1_OUTPUTSTATE_ENABLE,
TIM1_OUTPUTNSTATE_DISABLE,
300,
TIM1_OCPOLARITY_HIGH,
TIM1_OCNPOLARITY_HIGH,
TIM1_OCIDLESTATE_RESET,
TIM1_OCNIDLESTATE_SET
callしない 1kHz
duty30%/無信号(LOW)
クロック設定はtest06と同じだが、
1箇所DISABLEにした.
その結果、TIM1_CH1Nに信号が出なくなった.
test06c
TIM1_OCMODE_PWM1,
TIM1_OUTPUTSTATE_ENABLE,
TIM1_OUTPUTNSTATE_ENABLE,
300,
TIM1_OCPOLARITY_LOW,
TIM1_OCNPOLARITY_HIGH,
TIM1_OCIDLESTATE_RESET,
 TIM1_OCNIDLESTATE_SET
callしない 1kHz
duty70%/duty70%
クロック設定はtest06と同じだが、
1箇所LOWにした.
その結果、TIM1_CH1が反転した
test06d
TIM1_OCMODE_PWM1,
TIM1_OUTPUTSTATE_ENABLE,
TIM1_OUTPUTNSTATE_ENABLE,
300,
TIM1_OCPOLARITY_LOW,
TIM1_OCNPOLARITY_LOW,
TIM1_OCIDLESTATE_RESET,
TIM1_OCNIDLESTATE_SET
callしない 1kHz
duty70%/duty30%
クロック設定はtest06と同じだが、
2箇所LOWにした.
その結果、TIM1_CH1もTIM1_CH1Nも反転した
test06e
TIM1_OCMODE_PWM1,
TIM1_OUTPUTSTATE_ENABLE,
TIM1_OUTPUTNSTATE_ENABLE,
300,
TIM1_OCPOLARITY_HIGH,
TIM1_OCNPOLARITY_HIGH,
TIM1_OCIDLESTATE_RESET,
 TIM1_OCNIDLESTATE_SET
TIM1_OSSISTATE_ENABLE,
TIM1_LOCKLEVEL_OFF,
0xff,
TIM1_BREAK_DISABLE,
TIM1_BREAKPOLARITY_LOW,
TIM1_AUTOMATICOUTPUT_ENABLE
1kHz
duty30%/duty70%
DeadTime-63uSec
クロック設定はtest06と同じだが、
CTIM1_BDTRConfig()を追加した.
引数を0xFFにした結果、63uSecのデッドタイムが挿入されるようになった.
引数0xFFだとどうしてデッドタイムが63uSecになるのかは、Deadtime register (TIM1_DTR) の設定値とデッドタイム一覧表を参照のこと.
test06f
TIM1_OCMODE_PWM1,
TIM1_OUTPUTSTATE_ENABLE,
TIM1_OUTPUTNSTATE_ENABLE,
300,
TIM1_OCPOLARITY_HIGH,
TIM1_OCNPOLARITY_HIGH,
TIM1_OCIDLESTATE_RESET,
 TIM1_OCNIDLESTATE_SET
TIM1_OSSISTATE_ENABLE,
TIM1_LOCKLEVEL_OFF,
0xff,
TIM1_BREAK_ENABLE,
TIM1_BREAKPOLARITY_LOW,
TIM1_AUTOMATICOUTPUT_ENABLE
1kHz
duty30%/duty70%
DeadTime-63uSec

→TIM1_BKINをLOWにすると、
無信号 LOW/HIGH になる.
test06eにBREAK ENABLEを追加した.
BREAK機能とは、モーターの回転を緊急停止するときに使われる機能である.
TIM1_BKINピンがBREAK入力ピンだと決まっている.
TIM1_BREAKPOLARITY_LOWの引数が設定されているので、TIM1_BKINピンをLOWにするとBREAKがかかるように設定されている.
実際に、STM8S-DISCOVERYのCN4-1ピンをGNDに接触させると、
TIM1_CH1=LOW
TIM1_CH1N=HIGH
に固定されてモーターを停止させる.
test06g
TIM1_OCMODE_PWM1,
TIM1_OUTPUTSTATE_ENABLE,
TIM1_OUTPUTNSTATE_ENABLE,
300,
TIM1_OCPOLARITY_HIGH,
TIM1_OCNPOLARITY_HIGH,
TIM1_OCIDLESTATE_SET,
TIM1_OCNIDLESTATE_RESET
TIM1_OSSISTATE_ENABLE,
TIM1_LOCKLEVEL_OFF,
0xff,
TIM1_BREAK_ENABLE,
TIM1_BREAKPOLARITY_LOW,
TIM1_AUTOMATICOUTPUT_ENABLE
1kHz
duty30%/duty70%
DeadTime-63uSec

→TIM1_BKINをLOWにすると、
無信号 HIGH/LOW になる.
test06eのRESET/SETを逆にしてSET/RESETにした.
すると、BREAKしたときの無信号極性が逆になった.
test06h
TIM1_OCMODE_PWM1,
TIM1_OUTPUTSTATE_ENABLE,
TIM1_OUTPUTNSTATE_ENABLE,
300,
TIM1_OCPOLARITY_HIGH,
TIM1_OCNPOLARITY_HIGH,
TIM1_OCIDLESTATE_SET,
TIM1_OCNIDLESTATE_SET
TIM1_OSSISTATE_ENABLE,
TIM1_LOCKLEVEL_OFF,
0xff,
TIM1_BREAK_ENABLE,
TIM1_BREAKPOLARITY_LOW,
TIM1_AUTOMATICOUTPUT_ENABLE
1kHz
duty30%/duty70%
DeadTime-63uSec

→TIM1_BKINをLOWにすると、
無信号 LOW/LOW になる.
test06fからSET/SETに変更した.
すると、BREAKしたときの無信号がLOW/LOWになってしまった.HIGH/HIGHじゃないことに注意.

じつは、RESET/RESETにしてもBREAKしたときの無信号がLOW/LOWになってしまうのである.

無信号設定がコンプリメンタリじゃない場合は、LOW/LOWになってしまう仕様に留意されたい.
test06i
TIM1_OCMODE_PWM2,
TIM1_OUTPUTSTATE_ENABLE,
TIM1_OUTPUTNSTATE_ENABLE,
300,
TIM1_OCPOLARITY_HIGH,
TIM1_OCNPOLARITY_HIGH,
TIM1_OCIDLESTATE_RESET,
TIM1_OCNIDLESTATE_SET
TIM1_OSSISTATE_ENABLE,
TIM1_LOCKLEVEL_OFF,
0xff,
TIM1_BREAK_ENABLE,
TIM1_BREAKPOLARITY_LOW,
TIM1_AUTOMATICOUTPUT_ENABLE
1kHz
duty70%/duty30%
DeadTime-63uSec

→TIM1_BKINをLOWにすると、
無信号 LOW/HIGH になる.
test06fのPWM1をPWM2に変更した.
PWM2だと、パルス極性が反転する.

この仕組みは下図のタイミングチャートに従っている.
カウンタは青い線のように0〜999まで動いている.
閾値は300に設定されている.
比較結果がTIM1_CH1とTIM1_CH1Nに出力されている.(PWM1と極性が逆である)

ただし、BREAK時の無信号極性は、RESET/SETに従うことに留意されたし.

inserted by FC2 system