モータの鳴らし方byHanDen

電子工作の初心者がモータを演奏したりVVVF音を再現したりする方法を紹介するブログ ホビー向けの電子工作を基礎から書いていきます 記事のミス等のお問い合わせはTwitterにてお願いします。 当ブログを参考に製作をする際は必ず自己責任にて行ってください 当ブログを参考にしたことによる損害等の責任は一切負いません ドメイン取得につきURLを http://vvvf.blog.jp から http://blog.henden.net に変更しました

2018年01月

回路編第13回 ゲート抵抗の選び方

前回まではゲートドライバICの使い方の紹介をしてきましたが、今回はMOSFETのゲート部に取り付けるゲート抵抗の大きさの選び方のお話をしたいと思います。

 

 一般的にはMOSFETのゲート抵抗は数Ωから数百Ω程度と割と広い範囲で言われています。もちろん、この範囲の広さには理由があって、回路の用途や仕様などで取り付けるゲート抵抗が大きく変わるからです。

 通常ゲート抵抗が大きくなると、半導体のスイッチング速度が遅くなり、ゲート抵抗を小さくするとスイッチング速度は速くなります。このスイッチング速度がゲート抵抗を決める大きなカギとなります。まずは、スイッチング速度が速い場合と遅い場合のメリットデメリットを紹介しましょう。

スイッチング速度が速い場合

メリット

スイッチング損失が小さくなる

スイッチング周波数を高くできる

デッドタイムの設定時間を短くできる

 

デメリット

VOUT端子のアンダーシュートが大きくなる恐れがある

主回路に発生するサージ電圧が大きくなる(主にモータなどインダクタ成分のある負荷の場合)

出力にリンギングが発生しやすくなる

 

スイッチング速度が遅い場合

メリット

VOUT端子へのアンダーシュートが小さくなる

主回路に発生するサージ電圧が小さくなる

 

デメリット

デッドタイムの設定時間を長くする必要がある

スイッチング損失が大きくなる

スイッチング周波数を上げにくくなる

 

軽くまとめるとこのようなメリットとデメリットがあります。簡潔に言うと、極端にスイッチング速度が速くても遅くてもだめというわけです。この中でも特に注意しなければならないのが、デッドタイムの時間とスイッチング時間の関係です。デッドタイムの時間に対してスイッチング時間が遅い場合、ハイサイドとローサイドのMOSFETが同時にONになるタイミングができて、過大な電流が流れる恐れがあります。言葉だけではわかりにくいと思うので、実際にダメなパターンのゲート電圧波形を見てみましょう。
1

画像の黄色線がローサイド側のMOSFETのゲート電圧、水色線がハイサイド側のゲート電圧で縦の白線の内側がデッドタイムとなっております。

デットタイムは1usを入れていますが、デッドタイムの終わり(右側の白線)の時点ではローサイド側のゲート電圧が8Vぐらい残っていることがわかります。今回使用しているMOSFETのスレッショルド電圧は2V程度なので、デッドタイム終了時点でもローサイド側MOSFETONになっていることは明らかです。逆にハイサイド側のMOSFETONにし始めた(デッドタイム終了時)ほぼ同時にスレッショルド電圧を超えています。これによって、図のオレンジで示した時間はハイサイド側とローサイド側の両方のMOSFETが同時にONになっているというわけです。

このようにハイサイド側とローサイド側のMOSFETが同時にONになってしまうと、その間は過大な電流(貫通電流)MOSFETに流れることとなり、大きな損失が発生するほか、最悪MOSFETが故障します。そのため、ハイサイドとローサイドの両方が同時にONになることは防ぐようにゲート抵抗を決めなければなりません。(少なくともパワー回路では)

 

今回はケースファンやステッピングを演奏する低圧のMOSFETを使用した場合で「ある程度のゆとりをもって貫通電流が流れない程度」のスイッチング時間とした場合のゲート抵抗の選定をしたいと思います。

 今回はゲート抵抗を110Ω、47Ω、10Ωの場合のゲート電圧の波形とVOUT端子の波形を見て、そこからゲート抵抗の選定を行いたいと思います。

まずは、ゲート抵抗110Ωの場合から

ローサイドの立ち下り、ハイサイド立ち上がり時のゲート電圧
2

※オシロのオフセットの設定ミス?で基準電位がちょっとずれているので、Vminが負電圧になっています。

 

ローサイド立ち上がり、ハイサイド立ち下り時のゲート電圧
3


VOUT端子の立ち下り時(ローサイドがONになるとき)
4

VOUT端子の立ち上がり時(ハイサイドがONになる時)
5

波形からみて明らかにハイサイドと両サイドが同時にONになっていることが明らかですね。つまり、デッドタイム1μsに対してスイッチング速度が遅すぎるということです。結果、貫通電流が流れることにより大きな損失が発生し、MOFETの破損につながります。つまり、大きな問題があるというわけです。また、貫通電流の影響か何かで、MOSFETハイサイドの立ち上がり時のVOUT端子とゲート電圧にオーバーシュートが発生しています。

 

次にゲート抵抗が47Ωの場合です。

ローサイドの立ち下り、ハイサイド立ち上がり時のゲート電圧
6

ローサイド立ち上がり、ハイサイド立ち下り時のゲート電圧
7

VOUT端子の立ち下り時(ローサイドがONになるとき)
8

VOUT端子の立ち上がり時(ハイサイドがONになる時)
9

先ほどの110Ωの場合に比べると、ゲート電圧の立下り立ち上がりは速くなりました。ですが、この状態でもまだ、ハイサイドとローサイドが同時にONになって貫通電流が流れてしまう瞬間があります。貫通電流が流れる時間はかなり短くなったので、損失もそこまで大きくないとは言えますが、完璧とは言えないでしょう。

また、VOUT端子のハイサイド立ち上がり時のオーバーシュートも大幅に減少しています。

 

最後にゲート抵抗が10Ωの場合です。

ローサイドの立ち下り、ハイサイド立ち上がり時のゲート電圧
10

ローサイド立ち上がり、ハイサイド立ち下り時のゲート電圧
11

VOUT端子の立ち下り時(ローサイドがONになるとき)
12

VOUT端子の立ち上がり時(ハイサイドがONになる時)13

先ほどの47Ωの場合に比べてゲート電圧の立下り立ち上がりはさらに速くなりました。今回の場合は、デッドタイムが終了する立下りの初めから1μs立った時点で、ゲート電圧は1V程度まで降下しており、ハイサイドとローサイドのMOSFETが同時にONになることはなくなりました。また、VOUT端子の波形を見ても特に、アンダーシュートは見られず、オーバーシュートはわずかにあるものの、大きさ的にも問題がないレベルと見れます。

 

110Ω、47Ω、10Ωの3種類の波形から、今回の条件であるMOSFETを「EKI04027」ゲートドライバを「L6384E」を用いたときのゲート抵抗の最適値を求めます。
貫通電流対策とVOUT端子のアンダーシュートの観点から、ゲート抵抗は3つのなかでは10Ωが最も良いと見れます。ゲート電圧の波形からゲート抵抗の最適な範囲としては10Ωから20Ω程度だと言えるでしょう。

 

ゲート抵抗の値は、使用するMOSFETのゲート容量やスレッショルド電圧、ゲート駆動電源の電圧によって変動します。実際にゲート抵抗を選定する際にはこのことを考慮したうえで設計しなければなりません。MOSFETのゲート部はコンデンサの特性を持っていることから、MOSFETのゲート電圧の立下り波形は以下の式で近似できます。
14

この式である程度の近似はできますが、MOSFETのゲート部の内部抵抗やゲートドライバの最大電流などにより、ゲート電圧の計算値は低めに出てしまいます。(今回の条件ではオシロの波形に比べて、計算値は1~2V程度高めに出ています)MOSFETのゲート部の内部抵抗に関しては、上の式のゲート抵抗に足し合わせることで計算が可能ですが、ゲートドライバの最大電流の考慮はできません。(数式はあるかもしれないけど…)

また、ゲート容量については、ゲート電荷量とゲート電圧から計算を行い算出した方が、正しい値と考えられるため、ゲート電荷量から計算をしています。(MOSFETのデータシートのゲート容量はゲート電圧0V時の容量が書かれているため)

また、ゲート駆動電圧が今回とほぼ同じ場合は、ゲート抵抗はゲート容量に逆数倍にすればそこそこ良い値となるでしょう。

 

今回は、不明瞭な点が多いゲート抵抗の値の選定方法を紹介しました。ゲート抵抗はスイッチング速度の要求する条件によって大きく変わりますが、趣味でモータドライバ回路などを設計する場合は今回の条件(貫通電流が流れない程度のスイッチング速度)に近い場合も多いと思うので、ある程度の参考にはなったと思います。(小電力である信号用とかの場合は話が変わってくるとは思いますが…)
今回でゲート駆動関連のお話はいったん終了とし、次からはしばらくマイコン系のお話をしたいと思います。


回路編第12回 ゲートドライバICの使い方ver2 その2

2018/09/28追記
本ページで紹介しているゲートドライバL6384E(DIP版)はどうやらディスコンになった模様です。SOP版については現状取り扱い終了の表示は出ていないので本記事を利用する場合はSOP版を使うまたは、一部仕様の変化を対処したうえでIR2302などほかのゲートドライバICの利用になると思います。

前回は、ゲートドライバICの全般的なお話をしてきましたが、今回は、実際にゲートドライバICを使った回路の設計のお話をしていきたいと思います。

まずは、今回使用するL6384E関連の資料を並べます。(STマイクロの資料はすべて英語です)

データシート:

http://www.st.com/content/ccc/resource/technical/document/datasheet/group0/d3/35/0e/fc/db/e1/45/52/CD00169715/files/CD00169715.pdf/jcr:content/translations/en.CD00169715.pdf

アプリケーションガイド:

http://www.st.com/content/ccc/resource/technical/document/application_note/5c/00/05/fd/e5/65/46/97/CD00004008.pdf/files/CD00004008.pdf/jcr:content/translations/en.CD00004008.pdf

技術資料(ヒントとコツ)

http://www.st.com/content/ccc/resource/technical/document/application_note/cd/92/16/b2/e7/fc/4d/97/CD00004191.pdf/files/CD00004191.pdf/jcr:content/translations/en.CD00004191.pdf

ブートストラップ回路の設計資料:

http://www.st.com/content/ccc/resource/technical/document/application_note/fa/ed/25/78/92/26/4c/44/CD00004158.pdf/files/CD00004158.pdf/jcr:content/translations/en.CD00004158.pdf

以上がSTマイクロの公式の資料です。

これに加えて、参考用にIR社のアプリケーションシートも紹介しておきます。

https://www.infineon.com/dgdl/AN-978.pdf?fileId=5546d46256fb43b301574c6029a97c36

こちらは日本語なので読みやすいかなと思います。

 

アプリケーションには設計に必要な情報がいろいろと書かれていますが、内容自体はとても難しいです。筆者も比較的重要だと思われる個所を主に読んで設計を行っています。(製品にするなら細かなところも必要だと思いますが、趣味レベルなら細かなところは無視してもいいかなと思っています。)筆者が重要だと考えている点は、ブートストラップ周りの部品選定と耐圧設計です。

 

まずは、ブートストラップ周りの部品を選びます

初めはブートストラップコンデンサの選定です。
前回紹介した数式にて計算を行います。(STの技術資料(ヒントとコツ)にもリーク電流などを考慮した数式がありますが、今回はIRの数式を使うこととします。)使用するゲートドライバは前述のとおりL6384EMOSFETは秋月で50円で売られている「EKI04027」を使います。また周波数はステッピングの最低パルス数を秒間100回として100[Hz]にします。(Qgは実使用が13Vでデータシートが10Vで大きな差がないので10Vで近似計算(あとで安全率を高めに見積もって打消))

式1
また、Vcc13.5V ダイオードの順方向電圧降下を0.6Vとして計算をします。ローサイドのMOSFETの順方向電圧降下はわずかなので0として計算します。

式2
これに安全率15をかけます。

式3
計算結果としては3.3uF4.7uF程度で十分ですが、積セラの容量低下と余裕を考慮して今回は10uFの積層セラミックコンデンサを使用することとしました。

次にダイオードの選定です。

電流値は以下の式で計算します。周波数は想定最大周波数の2kHzを入れました。

式4
また、耐圧をリカバリ時間は前回の通り以下の式で表せます。

式5
これより、安価なファストリカバリダイオードである「UF4007」を選定しました。

 

次に耐圧と動作電圧関係のお話です。

まずは耐圧の確認を行います。L6384Eのデータシートの4ページに書かれている最大絶対定格を見ます。

1
この表からVccの動作は範囲は-0.3~14.6Vであることがわかります。ゲートドライバに14.6Vを超える電圧を印可すると壊れてしまう恐れがあるので注意をしてください。この表記からゲートドライバの電源は14.6V以下なら何でもいいと思ってしまいます。しかし、実際には次の項目に注意しなければなりません。

2
3
データシートの7~8ページにまたがって書かれてる、DC operationの表に注目します。この表の上から2行目と3行目の「VCCth1:Vcc UV turn-on threshold」と「VCCth2: Vcc UV turn-off threshold」です。ゲートドライバICVccに印加される電圧が下がった時には、回路保護のため出力を停止する機能が搭載されています。この2つの項目は電圧が下がった時に出力を停止させる電圧(Vccth1)と電圧が回復した時に出力を復帰させる電圧(Vccth2)を示しています。そのため、ゲートドライバIC電源電圧は「Vccth1:出力復帰電圧」以上「Vcc(max):最大定格電圧」以下である必要があるというわけです。これを守らないとゲートドライバが動かないあるいは、破損するといった事故が発生する恐れがあります。

 

話を絶対最大定格の表に戻します。最大絶対定格の表の一番上のVOUT端子の電圧特性を確認します。ここには-3~VBOOT-18 と書かれています。なぜ、これを注意しなければならないかというと、ローサイド側のMOSFETONにした瞬間にアンダーシュートとしてVOUT端子に瞬間的に負の電圧が印可される場合があるからです。技術資料(ヒントとコツ)の12ページやIRのアプリケーションシートの8ページにこのことの記載があります。VOUT端子に-3Vを下回る負の電圧がかかるとコンデンサが過充電となり、ハイサイドドライバの耐圧である18Vを超え、結果的にゲートドライバICが破損する恐れがあるというわけです。

アンダーシュートにより発生する電圧は技術資料(ヒントとコツ)に計算方法が書かれていますが、配線のインダクタンスが正しく計算するのが難しいので、オシロスコープなどを使って実測するのが正確だと思います。この計測結果は次回の記事で紹介したいと思います。

アンダーシュートを減らすためにはスイッチング速度を遅くすること、そして配線のインダクタンスを減らす方法の2通りがあります。

前者のスイッチング速度はMOSFETのゲート抵抗により決まります。ゲート抵抗を大きくするとスイッチング速度が遅くなりアンダーシュートが減らせますが、ほかにも不都合が生じる恐れがあるため注意が必要です。ゲート抵抗の選定については次回の記事で紹介したいと思います。

配線のインダクタンスを減らす方法はIRのアプリケーションシートの8ページから9ページにかけて記載があるので確認をしてください。ここに書かれている内容をまとめると以下のようになります。

・配線はできるだけ短くする

・ゲートドライバICMOSFETはできるだけ近づける

・ブートストラップコンデンサの容量は0.47uF以上にする

・ゲートドライバの電源(Vcc)GNDの間にブートストラップコンデンサの10倍以上の容量のコンデンサを入れる

これくらいのことをすればアンダーシュートは減らせるというわけです。特に最後のVccGND間のコンデンサはゲートドライバ電源の瞬間的な電圧降下対策にもなるので入れることをお勧めします。

 

最大定格に関する項目で注意しなければならないのは以上だと思います。あえて言うと、

VBOOT端子の耐圧(主回路の耐圧)がありますが、ここの耐圧は600V程度あるので基本的に、問題になることはないと思います。

 

次に入力端子周りの設計を行います。

入力端子はINDT/SD端子の2つがありそれぞれの入力は以下のように設計します。

IN端子

ハイサイド側のMOSFETONにするか、ローサイド側のMOSFETONにするかの切り替えを行う端子です。この端子にHが入力されるとハイサイド、Lが入力されるとローサイドがONになります。

内部的にプルダウン抵抗が搭載されており、外付けでプルダウン抵抗を取り付けなくても動作させることが可能です。ただし、抵抗値が非常に高いので状況に応じて外付けでプルアップ抵抗やプルダウン抵抗を取り付ける必要があります。(入力にフォトトランジスタ出力のフォトカプラを取り付けた場合は、外付けでプルダウン抵抗を取り付けないと立下り動作が遅くなりすぎて使いもになりません)また、入力がシュミットトリガになっているので入力状態の安定性が高くなります。

 

DT/SD端子

出力のシャットダウンとデットタイムの設定端子です。

出力をシャットダウン(ハイサイドもローサイドもOFF)したいときは、この端子に閾値を下回る電圧を入力します。データシートのDC operation の表の一番下に書かれているVdtShutdown threshold)を確認すると0.5Vと書かれています。つまり、この端子に0.5V以下を入力すれば出力がシャットダウンされるというわけです。なお、出力をシャットダウンすると、モータは開放状態となります。

デッドタイムの設定は、この端子をGND間に接続する抵抗値の大きさによって決まります。抵抗値の大きさとデッドタイムとの関係のグラフはデータシートの11ページの「Figure.7 Deadtime vs. resistance」に書かれています。

6
   
また、DC operations の下から2つ目のdt(Deadtime seting range)にも主要な抵抗値とデッドタイムの対応が書かれています。今回はデッドタイムを1[us]にするのでRdt100[kΩ]を選定しました。

なお、この端子はデッドタイムの設定とシャットダウンを兼ねているので、両方の機能を使うためにはちょっと注意が必要です。シャットダウンを使用するためにトーテムポール出力になっているものを使用すると、デッドタイムの設定ができなくなります。そのため、オープンコレクタ出力のもの(フォトトランジスタ出力のフォトカプラなど)を接続する必要があります。

 

次に出力端子系の設計を行います。

VBOOT端子

 ハイサイドドライバの電源端子です。この端子にはブートストラップコンデンサの+側を接続します。また、条件によりブートストラップダイオードを取り付けます。

内蔵のブートストラップダイオードの情報が、アプリケーションガイドの17ページに書かれています。内蔵のブートストラップダイオード(厳密にはDMOSを含むらしい)は外付けダイオードに比べてリーク電流が小さいという特徴がありますが、周波数が高くなると電圧降下が高くと記載があります。高周波の場合はアプリケーションシートの17ページ下部の数式で計算が必要な模様です。また、ブートストラップコンデンサの容量が大きい場合(1~2uF以上)も外付けのダイオードの使用が必要ととらえられる記載があります。そのため、今回は外付けでブートストラップダイオードを取り付けます。

 

HVG端子

 ハイサイドドライバの出力端子です。ゲート抵抗を介してハイサイド側MOSFETのゲートに接続します。

VOUT端子

 ハイサイドドライバの基準電位となる端子です。ブートストラップダイオードの-側を接続するほか、ハイサイド側MOSFETのソース端子も接続します。ハーフブリッジやフルブリッジの場合は自動的にローサイド側のドレイン端子とも接続することになります。

LVG端子

 ローサイドドライバの出力端子で、ゲート抵抗を介してローサイド側MOSFETのゲートに接続します。

 

端子周りの設計はこのように行えばできるでしょう。では実際に設計した回路を紹介します。

7

今回筆者が設計したstepVVVFはコストカットのため入力のフォトカプラをトランジスタ出力のものを使っています。本当はもっと高速で動作する信号用のフォトカプラあるいはトーテムポール出力のフォトカプラを使用するべきですが、音楽を鳴らす周波数レベルでは問題がないためこのような構成にしました。接続は先ほどまでに紹介したとおりに接続を行っています。なお、MOSFET手前のRp1,2MOSFETのプルダウン抵抗でドライバICの不具合などでゲートがハイインピーダンスとなった時に、確実にゲートの電位をソースレベルに落とすためのものです。

 

以上で、ゲートドライバICを使った回路の設計は終わりです。次回はMOSFETのゲート抵抗をオシロスコープの波形を見ながら選んでみたいと思います。

回路編第11回 ゲートドライバIC(L6384E)の使い方ver2 その1

2018/09/28追記
本ページで紹介しているゲートドライバL6384E(DIP版)はどうやらディスコンになった模様です。SOP版については現状取り扱い終了の表示は出ていないので本記事を利用する場合はSOP版を使うまたは、一部仕様の変化を対処したうえでIR2302などほかのゲートドライバICの利用になると思います。

回路編を書くのはずいぶんと久しぶりですね。今回は、ゲートドライバICの使い方のお話をしたいと思います。ゲートドライバのお話はずいぶん前の記事でも紹介していましたが、わかりにくかったということで書き直しをしたいと思います。

 

今回使用するゲートドライバはSTマイクロ製の「L6384E」というゲートドライバです。このゲートドライバはRSコンポーネンツで20個以上買うと1つあたり約80円とDIPのゲートドライバの中では非常に安いのが特徴です。他にもデッドタイムの長さを調整する機能やブートストラップダイオードが内蔵されているなどいろいろと面白い使い方ができます。

 

まずはL6384Eのデータシートをご覧ください。(英語ですが…)

http://www.st.com/content/ccc/resource/technical/document/datasheet/group0/d3/35/0e/fc/db/e1/45/52/CD00169715/files/CD00169715.pdf/jcr:content/translations/en.CD00169715.pdf

 

とはいえ、今回はゲートドライバICの全般的な抽象的なお話をしたいと思います。

最初にゲートドライバの構造のお話をします。

データシートの3ページ目に内部の構造の簡易的な図があります。
1

内部の構造はざっと3つに分けられます。画像の青で囲んだロジック部、赤で囲んだハイサイドドライバ、黄色で囲んでローサイドドライバです。それぞれの部分別に機能の紹介をしたいと思います。

ロジック部 

入力信号をMOSFETを動作させる信号に変換を行う回路です。MOSFETON/OFFの遅れによる回路の一時的なショートを防ぐためのデッドタイムの挿入や入力ミスによるハイサイド側とローサイド側が同時にONにならないような処理も行っています。これらの機能によりパワー回路を安全に動作させることが可能になります。(例外でこれらのこれらの機能が搭載されないゲートドライバもあり、前回紹介したIR2110は例外に含まれます) 

入力端子は出力側であるハイサイドドライバやローサイドドライバとは絶縁されており、入力端子に5V程度を入力すればH状態として認識されるので、直接マイコンの端子に接続することも可能です。ですがGNDが共通であるほか、フォトカプラのような完全な絶縁とは言えないので、気になる場合はフォトカプラなどを使ってマイコン側と絶縁を行ってください。

また、入力端子は内部的にプルアップやプルダウンがされているものが多いので、必ずデータシートを確認してから回路設計をしなければなりません。

 

ハイサイドドライバ

ハイサイド側のMOSFETを駆動するための回路です。内部には下図のようなトーテムポール回路が組み込まれており、MOSFETを高速にON/OFFすることが可能になっています。
2

ロジック部からはレベル変換器を通して接続されているので負荷にかかる電圧(GNDとハイサイドドライバの基準電位との間の電位差)はかなりの電圧(600Vぐらいまでのが多い)に耐えるものが多くなっています。

ハイサイドドライバの電源は、ブートストラップにより供給されています。詳細は後で紹介します。

ローサイドドライバ

ローサイド側のMOSFETを駆動するための回路です。ハイサイドドライバと同じくトーテムポール回路が組まれており高速にMOSFETを駆動させることができます。ハイサイド側とは異なりローサイドドライバの基準電位はGNDなのでレベルシフタは内蔵されていません。また、電源もゲートドライバICの電源をそのまま使っています。

 

ブートストラップの仕組み

 ブートストラップはコンデンサとダイオードを使ってハイサイドのゲート駆動電源を容易に作る方法です。ローサイド側を含めた全体の構造は下図のようになっています。
3

ゲート抵抗とかの周辺部品は見やすさを上げるために省略しています。

回路図よりローサイド側は特に何もありませんが、ハイサイド側にはダイオードとコンデンサが搭載されていることがわかると思います。これがブートストラップのミソと言える部品となります。

通常モータを駆動するときはPWMと呼ばれる疑似アナログ出力を使用します。PWMは高速でON/OFFを繰り返す信号です。ゲートドライバの入力にHigh(ON)を入力するとハイサイド側がONLow(OFF)を入力するとローサイド側がONになるので、ゲートドライバにPWMを入力するとハイサイドとローサイドが高速で切り替わることになります。

まずはローサイド側がONの時を考えます。
4

ローサイド側がONの時は図のようにOUTPUT端子の電位は0V(GNDと同電位)になります。すると、ブートストラップダイオードとブートストラップコンデンサを介してVccGNDを結ぶ回路が構成されます。充電されていない状態では、コンデンサにかかる電圧は0Vなので、ダイオードには順方向にVccの電圧がかかります。すると、ダイオードはONとなり電流が流れ、コンデンサに充電されるというわけです。この時の回路をもっと簡単に書くと下のようになりますね。
5

次にハイサイド側がONの状態を考えます。
6

ハイサイド側がONの時は図のようにOUTPUT端子はVDDとほぼ同電位になります。つまり、ハイサイド側の回路の基準電位がGNDレベルからVDDのレベルに引きあがられるということです。コンデンサが充電されていたとすると、ダイオードのカソード側の電圧は大体VDD+Vccとなるので、ダイオードはOFFになり、コンデンサの電荷はハイサイドドライバの電源となります。(ハイサイドドライバに電池のようなものがつながっていると考えたらわかりやすいかもしれません)この時の回路を簡単に書くと次のようになりますね。
7


最後にハイサイドもローサイドもOFFになっている状態を考えます。
8

両方の端子がOFFになっている場合はOUTPUT端子は分圧によって電位はおよそVDD/2になります。コンデンサが充電されていた場合は、ダイオードのカソード端子の電圧はVDD/2 + Vccとなるため、ダイオードはOFFとなります。そのためコンデンサはこれ以上充電されません。 コンデンサが空の場合も電流の流れる先がないため基本的に充電されません。

この状態はハイサイド側の基準電位がGNDレベルになっていないので、基本的にはハイサイド側がONの時の準備状態と考えればよいでしょう。

 

ブートストラップの原理はこのような感じになっています。簡潔にまとめると、ローサイドがONの状態の時にコンデンサを充電し、ローサイドがOFFになるとコンデンサが独立し、ハイサイドドライバの電源になるというわけです。

この原理からもお分かりだと思いますが、ブートストラップを使用するには、ハイサイドドライバの電源であるコンデンサを充電する時間を設ける必要があります。つまり、ずっとONにしておくことはできず、PWMを使って一定時間ローサイドがONになるようにしなければならないというわけです。

PS. MOSFETは絶縁ゲートなので一度ONにしたら、理論上は電流を流さなくてもずっとONになると言えますが、実際にはハイサイドドライバなどに電流が流れるため、ONにしている間は、わずかながらにもずっと電流が流れ続けます。なので充電されるまでコンデンサの電荷は減り続けるというわけです。

 

続いてブートストラップに使用する部品の選定方法を紹介したいと思います。

ブートストラップコンデンサの容量選定

L6384Eのデータシートにも容量計算の数式が書かれていますが、ハイサイドドライバの消費電流などが考慮されていない数式なので、今回もIRのアプリケーションシートに従った計算を行います。(アプリケーションシート:https://www.infineon.com/dgdl/Infineon-dt98-2j.pdf-AN-v01_00-JA.pdf?fileId=5546d46256fb43b3015756f4cf4643fb)

 2ページの式1からブートストラップコンデンサの最低の電荷の容量が求まります。
9
式1

Icbsはケミコンなどで発生するが、通常データシートに書かれていないので、計算できません。そのため、Icbs=0で計算を行い、最後の安全率の倍率を少し高めると良いと思います。
18/01/24追記 QgはVgsの電圧によって変化します。データシートのQg欄の条件を確認して、条件に書かれているVgsと実際に使用するVgsが離れている場合は、データシートのVgsとQgの関係グラフなどから適時補完をして下さい。(グラフがなければVgs2倍→Qg2倍で近似すればよいと思います。)

 

次にブートストラップコンデンサの容量に変換します。ページ3の式2を先ほど計算した値を使って表すと次のようになります。
式2

これによって、必要最低限のブートストラップコンデンサの容量が求まりました。しかし、この容量ではコンデンサの電圧変動が激しくなります。また、積層セラミックコンデンサの特性上、電圧が高くなると容量が減るといった問題もあります。容量が足りないとゲートを正しく駆動できずゲートドライバICにダメージを与える場合があるので、ブートストラップコンデンサの容量を選定するときは、安全率として上の式で計算した値の15倍程度をかけた容量のコンデンサを取りつけます。容量が多少大きくても不都合が生じないので、15倍して算出した容量のコンデンサがない場合は、容量が大きい側で近い値のコンデンサを選定してください。

 PS. IGBTなどゲート電荷量[C]がデータシートに書かれていない場合は、ゲート容量[F]×ゲートソース間電圧[V]=ゲート電荷量[C]でゲート電荷量の概算を算出してください。しかし、この式で計算をした値よりもゲート電荷量が大きい場合がある(両方書かれているデータシートより)ので、安全率として2程度をかけた値を使用すると良いと思います。

 

ブートストラップダイオードの選定

 ブートストラップダイオードの選定で特に考慮しなければならないので、ダイオードの耐圧と逆回復時間です。

 ダイオードの耐圧は主回路に印加される電圧以上でなければなりません。その理由は、ハイサイド側がONになった時には、下図のようにダイオードに主回路の電圧がそのまま印加されるためです。
10

次にダイオードの逆回復時間ですが、IRの資料によると逆回復時間は100[ns]以下である必要があるそうです。つまり、普通のダイオードではなくファストリカバリダイオードが必要というわけです。その理由を説明したいと思います。

回路がローサイド側からハイサイド側に切り替わる時は下図のように一気に電圧の向きが変わります。
11

このように電流の向きが変わる時には、瞬間的に逆方向に電流が流れてしまいます。この流れる時間が逆回復時間と呼ばれるものです。逆方向に電流が流れるときは、ダイオードで大きな抵抗が発生し、熱となります。逆回復時間が長いと、この発熱量が大きくなり場合によってはダイオードが破損する可能性があるというわけです。

この2つのほかにも耐電流の計算も必要です。先ほどの2つとまとめて以下に示します。
式3

ゲートドライバICのブートストラップに用いる回路部品の選定は以上のようなやり方で行えます。ゲートドライバの周辺回路の設計では、MOSFETのゲート抵抗の選定も非常に重要ですがこれは、次々回の記事でオシロスコープで測定した波形とともに検証していきます。次回は実際にL6384Eを例にゲートドライバICを使った回路の設計をしていきたいと思います。

制御編 第6回 Atmel Studioでのファイル作成とFuse設定

今回はプログラミングを始める最初の作業である、ファイルの作成とマイコンのFuse設定のお話をします。

 

まずは、デスクトップかスタートメニュのアイコンから「Atmel Studio 7」を起動させます。

 
32

起動したら、「ファイル」メニューの「新規作成」、「プロジェクト」をクリックして、ファイル作成画面へと進みます。

33
ここで、プログラムの種類を選びます。AVRマイコンのプログラミングでは「Executable Project」を選択します。Executable project にもC言語とC++言語の2つから選べます。必要に応じて選択をしてください。(通常はC言語の範囲のプログラミングが多いと思いますが、C++言語にしてもC言語の機能は基本的に使えるので特に気にしなければどちらでもよいです。)また、この時下部の「名前」のボックスにファイル名を、「場所」のボックスにはファイルの保存先を設定します。

34

次に、使用するマイコンの種類を選択します。今回は「ATmega328P」を使用するので、「ATmega328P」を選択します。選ぶときには、上部のプルダウンメニューから「ATmega」を選択すると、選択肢が減って選びやすくなります。または、次の右上の検索欄に「328」と入れて検索すると下図のように絞り込みができます。
35
基本的には、検索をした方が速いと思います。使用するマイコンが選べたら右下の「Ok」をクリックしてファイルの作成を完了させます。

 

続いてFuse設定を行います。

1

上部のツールバーから、図の↑でしめした、雷っぽいアイコンの「Device programing」をクリックして、マイコンへの書き込み画面を表示させます。

2

まずは、左上の「Tool」のプルダウンメニューから「STK500 COM*(*にはCOM番号が入ります)を選びます。次に、「Device」のプルダウンメニューから使用するマイコン(今回は「ATmega328P」)を選択します。そして、その右側の「Apply」ボタンをクリックしてデバイスへの接続を開始します。(厳密には接続が開始されるのは、次のステップ)

3

左側のメニューから「Fuses」(図の←)をクリックしてFUSE設定を開きます。この時にエラーが出た場合は、マイコンが正しく接続できていないので、各種設定や回路の確認を行ってください。

36

FUSE設定を開くとこのような感じの画面になります。画像はArduino UNOFUSE設定になります。Arduinoとしてマイコンを使う場合は基本的にはこの設定にしてください。一応、各設定の紹介をしておきます。なお、各設定の「.」の前はFUSEバイトの名前を指しており、後は設定の名前です。

BODLEVEL:マイコンに印加される電圧が下がった時に、マイコンをリセットする設定です。ここで設定された電圧を下回ると、マイコンがリセットされます。設定電圧は”1.8V”,”2.7V”,”4.3V”電圧低下によるリセットなしです。Arduinoでは”2.7V”に設定されています。

RSTDISABLE:マイコンのリセットピン(atmega328Pの場合PC6)の無効化の設定です。チェックをオンにすると、リセットピンは通常のポートとして使用できます。この際にリセットを行うには、低電圧リセットか電源をONにし直す必要があります。書き込み時などに不都合が生じるので、基本的にチェックは入れないでください。

DWEN:デバッグ機能を有効化する設定です。デバッガーがないとデバッグができないので、当ブログでは使用しません。うっかりチェックを入れるとISP通信ができなり、通常の書き込み機では書き込みが不能になるので注意してください

SPIEN:直列プログラミング(ISPによる書き込み)を許可する設定です。無効にするとISPでの書き込みができなくなり、通常の書き込み機では書き込みができなくなるので注意してください。

WDTON:ウォッチドッグタイマを常時有効化する設定です。

EESAVE:チップの消去時のEEPROMの内容を保護する設定です。

BOOTSZ:ブートローダの容量の設定です。選択肢は“256word”,”521word”,”1024word”,”2048word”です。

BOOTRST:起動時にブートローダなどを使用するかどうかの設定です。Arduinoの場合はチェックを入れないと、書き込みなどができなくなります。

CKDIV8:システムクロックを水晶からのクロックの1/8にする機能です。

CKOUT:システムクロックを外部にピン(atmega328pの場合PB0)に取り出す機能です。

SUT_CKSEL:起動時間とクロックの種別を選択します。外部に接続する水晶の有無やクロック数、電源の起動時間などに合わせて設定を行います。Arduinoの場合はAtmel Studioの一番下に出てくる、”(外部)低電力クリスタル発振器の8~16MHz, 起動遅延時間が16k×CK リセットからの負荷遅延14×CK+65ms (外部クリスタル発振子、低速上昇電源)Atmel Studio上の表記では”Ext. Crystal Osc. 8.0- MHz;Start-up time PWMDWN/RESET:16K CK/14 CK + 65ms”に設定されています。Arduinoとして使用しない場合でも8MHz以上の水晶やセラロックを使用する場合はこの設定を使用すればよいでしょう。外部クロックを使用しない場合は、くれぐれも外部クロック関連の設定にしないように気を付けてください。外部に水晶を使用しないとマイコンが使えなくなります。詳しい設定は、ATmega328PデータシートP28~31を参照してください。

 

FUSE設定はこんな感じです、基本的に設定変更をするのは、”BOODLEBEL”,”CKDIV8”,”SUT_CKSEL”3つでArduinoとして使う場合など、必要がある場合は”BOOTSZ”,”BOOTRST”も変更すればよいでしょう。ここの設定は下手に触るとマイコンが使えなくなるので慎重に行ってください

Arduinoとして使わない場合で特に事情がない場合は、初期状態から”BODLEBEL”2.7V ”CKDIV8”のチェックを外す、”SUT_CKSEK”を一番下の"Ext Crystal 8MHz 65ms”にしておけばいいと思います。(下の画像参照)
38

ちなみに、マイコンの種類が変わると、FUSE設定が多少変わるので、ATmega328(とその系統)を使わない場合はマイコンのデータシートのヒューズビットの設定を確認して設定を行ってください。よくわからない設定の変更は慎重に!(よくわからない設定の変更は控えておくのが安全です)

最後に参考程度に、FUSE設定のデータシートの抜粋を置いておきます。既定の設定などはここを参考にしてください。

 

37

次回からは本格的に、マイコンのプログラムに入っていって、最終的に音楽などを演奏できるようにしていきます。

制御編 第5回 AVRマイコンの環境づくり2 AtmelStudioの日本語化とAtmel Studioの初期設定

前回にAtmel Studio のインストールを行いましたが、そのままの状態では英語で使い勝手がよくないです。そのため今回はAtmel Studioの日本語化とそのあとの初期設定のお話をします。

Atmel StudioVisual Studio shell (isolate)というMicrosoft visual Studioのエディター機能のみを取り出したソフトウェアをベースに動いています。そのため、visual Studio shellの日本語版をインストールすると日本語化が可能と言えるのですが、実はAtmel Stduio 7ではそれができません。なぜかというと、Atmel Studio 7Visual Studio 2015 shell をベースに作られているのですが、 Visual Studio 2015 shellの単体での配布がされていないからです。ですが日本語化する方法があります。それは、日本語版のVisual Studio をインストールするということです。インストールするVisual StudioAtmel Studioのベースとなっている同じバージョンの無料版である「Visual Studio Community 2015」です。(同じ無料版のVisual Studio Express 2015でもできるっぽいですが、わざわざExpressをインストールする必要もないと思います)これをインストールすることで、Atmel Studioが日本語で使用できるようになります。(Visual Studio Language Packをインストールしたら使えそうに見えますが、インストールの段階でVisual Studioが見つかりませんって言われて跳ねられます)

 

まずは、Visual Studio Community 2015をダウンロードします。

Google検索で「Visual Studio Community 2015」と検索してリンクを進みと、下のようなページが表示されます。

18-1

このページの「ダウンロード」ボタンを押すと次のようなページに飛ばされます。(執筆時点では)

19

Visual Studio 2015のダウンロードボタンを押したはずなのに、なんと2017のダウンロードページに飛ばされてしまいます。(執筆時では)ですが、このページの下の方に古いバージョンのダウンロードへのリンクがあります。

20

ページ下部の「older versions」をクリックして古いバージョンの一覧へと進みます。(執筆時の一覧画面のURL: https://www.visualstudio.com/vs/older-downloads/

21

そのなかから、「2015」の欄の右側の「Download」をクリックしてVisual Studio 2015のダウンロードページへと進みます。この時にマイクロソフトアカウントへのログインが求められるので、ログインをしておきます。

22

このような画面が表示されるので、この中から「Visual Studio Community 2015」を探します。(図の□囲み)

23

そして、左側のプルダウンメニュー(上の図で”x86”と表示されているところ)からOSのビット数(32ビット版OSならx86 64ビット版OSならx64)を選びます。次に、中央のプルダウンメニューから”Japanese”を選びます。最後に右側のプルダウンメニューから”EXE”を選びます。(画像は、32ビット版OSの場合の選択になっています。)すべて選べたら、右側の「Download」をクリックしてダウンロードを始めます。

 

ダウンロードしたインストーラーを実行して、インストールを開始します。

24

HDDSSDの容量がひっ迫しているとかがない限りは、「既定」が選択されたまま、下部の「インストール」をクリックします。

25
しばらく待つと、このようにインストール完了画面が出るので、「今すぐ再起動」をクリックして再起動を行います。

 

次は、Atmel Studioの初期設定です。

デスクトップの赤いアイコンから、「Atmel Studio 7」を起動させます。(この時点では日本語が表示されないですが正常です)

26

Tools」メニューの一番下「Options」をクリックして、設定画面を開きます。

27

右側の一覧から「International Settings」を選択し、「Language」から「日本語」を選び下部の「OK」をクリックします。その後、一旦Atmel Studioを閉じてから再起動をします。

再起動して日本語になっていれば、日本化は成功です。次はライターの設定を行います。

28

上部の「ツール」メニューの上から4番目の「Add target(図の黄色部)をクリックして、ライターの追加画面に入ります。

29

Select tool」のプルダウンメニューから「STK500」を選びます。

30

するとシリアルポートを選ぶメニューが出てきます。前回のライターの初期設定の際にメモした「Programing Port」のCOM番号を「Select Serial port」のプルダウンメニューから選びます。

31

先ほどの「Select Serial port」が画面のように「Polulu USB AVR Programer V2 Programing Port(COM*)」と表示されていることを確認して、下部の「Apply」をクリックして設定を確定させます。

以上で初期設定は完了です。

次回はファイルの作成方法とFuse設定などを紹介したいと思います。

制御編 第4回 AVRマイコンの環境づくり1 ライターのドライバとAtmel Studioのインストール

前回まではマイコンのプログラミングで使うビット演算のお話をしてきましたが、今回からはAVRマイコンのプログラミングを行う環境づくりのお話をしたいと思います。

まずはAVRマイコンの書き込みに用いるライター(書き込み機)を選びます。少し前なら純正のライターである「AVRmkⅡ」を選ぶのですが、現在は販売中止になっており入手が困難になっています。現在購入可能な純正品としては、デバッグ機能が付いた「Atmel Ice Basic」などがありますが1万円を超えてしまいます。互換品をAmazonとか日本橋などを見ているといろいろありますが、純正の開発環境である「Atmel Studio」からは書き込みができないなど不都合があるものが多いです。そこで、筆者が使っているのはスイッチサイエンスで売られている「Pololu USB AVR Programmer v2」です。このライターは他の安いライターと違ってAVRマイコンの統合開発環境である「Atmel Studio」でプログラミングから書き込みができ、非常に便利です。

1

販売ページ:https://www.switch-science.com/catalog/2662/

そして、この販売ページから製造元の「Pololu」のサイト(下図)(https://www.pololu.com/product/3170/resources )へのリンクもあり、そのサイトに詳しい使い方が書かれています。(英語ですが)
2

まずこのサイトからドライバー(図の下側の←)をダウンロードします。また、上の←のリンクより、使用方法が見れます。

ダウンロードしたドライバーのインストーラーを実行します。

3

ウィザードに従ってインストールを行います。まずは「Next」で進みます。

4

次にインストール先を聞かれます。変更の必要があれば適時変更、なければそのまま「Next」で進みます。


5

次もそのまま「Next」で進みます。

6

Install」をクリックしてインストールを始めます。途中でドライバのインストールの確認画面が出てくるので「インストール」をクリックして、すべてのドライバのインストールを行います。

7

この画面が出たら完了です。

続いて、スタートメニュから「Polulu」フォルダの「Pololu USB AVR Programer v2…」を開きライターの初期設定を行います。
8

9

デバイスの設定画面で、初めに←1で示した個所に記載されている、「Programing Port」のCOM番号をメモしておきます。
次にライターからの電源供給の設定をします。マイコンに書き込みをするときには、マイコンに電源が供給されている必要があります。その電源をライターから供給する場合は図の←2の「Vcc Output」をEnableに変更します。書き込み時に外部から電源が供給されている場合は「Vcc Output」をDisableにします。この設定を間違えると書き込みができないことやライターが破損する恐れがあるため書き込みを行う回路の仕様をきちんと確認したうえで間違いのないようにしてください。

 

続いてAtmel Studioのインストールへ進みます。

Google検索で「Atmel Studio 7」で検索をして、「Atmel Studio 7 | Microchip Technology Inc …」のリンクを開きます。(執筆時点でのURL: https://www.microchip.com/avr-support/atmel-studio-7 )

9-1

10

このような感じの画面が開くので下の方に進みダウンロードリンクへと進みます。

11

Windows(x86/x64)」の中からAtmel Studio7.0をダウンロードします。筆者は下の「Atmel Studio 7.0 (build 1645) offline installer」をダウンロードしましが「web installer」をダウンロードしても同じです。(インストールの時に大きなファイルをダウンロードするか、先にダウンロードするかの違いです。)(ビルド番号は時期によって変わるので、その時々にあわしたものをダウンロードしてください)

ダウンロードしたファイルを実行してインストーラーを起動させます。

12

最初に、ライセンス条項の確認が出てくるので確認をしたら、「I agree to the license terms and conditions(図の↓)をクリックして、同意状態にした後、下部の「Next」で次に進みます。

13

インストールする項目の選択ですが、すべてインストールして問題ないので、そのまま「Next」をクリックします。

14

サンプルなどのインストールを行うかどうかについて聞かれますが、インストールしておいて問題ないのでそのまま「Next」をクリックします。

17

最後にパソコンの環境チェックがされ問題がなければすべての項目に「✓」が付きます。すべてに「✓」がついていることを確認して「Next」をクリックするとインストールが始まります。AtmelStudioも途中でドライバのインストール確認画面が出るので、すべて「インストール」をクリックしてすべてのドライバをインストールします。

環境チェックで以下のように跳ねられた場合は、その項目を修正してからインストールを行ってください。
16
筆者の場合はwindows updateの「KB2999226」がインストールされていないというエラーが出ました。筆者の環境ではWindowsUpdateからインストールできなかったため、画面に出ているURLから更新を手動でダウンロードしてインストールを行うと、エラーがなくなりました。

18

最後に、このような画面がでたらインストールは完了です。(環境次第でかなり時間がかかります)

Close」を押してセットアップを完了させると、Atmel Studioが起動します。ですが、現時点では英語のメニューとなっています。日本語化することが可能なので次回日本語化の紹介をします。

制御編 第3回 ビットシフト

 前回はビット演算のお話をしましたが、今回はビット演算の一部ともいえるビットシフトのお話をします。ビットシフトというのはその名の通り、ビットの位置を移動させる機能です。この機能は主に、値を読み込んだ時に高いビットの値のみを使いたいときや、通信データの作成の時に使います。ですが、使う機会はそんなに多くないのでさらっと行きたいと思います。

ではビットシフトをすると、どのようになるのかをお見せしましょう

操作前の値      10101010

右に4bitシフト  00001010

1回目の例は右向きに4bitシフトさせた例です。このように右向きにシフトさせると高い位置のビットにあったデータを低いビットに移動させることができます。ここで気を付けないといけないのは、ビットシフトさせて消えるビットと新たに出てくるビットがあることです。この例の場合は操作前の右側(下位)4ビットはシフトさせると消えていることがわかると思います。逆にシフトさせたあとの左側(上位)4ビットが新たに出てきてすべて0が入っていることがわかります。つまり、ビットシフトをさせるとシフトさせた方向寄りのシフトさせた数のビットが消えるというわけです。

次に左向きにシフトする例です。

操作前の値     10101010

左に4bitシフト  10100000

左向きにシフトすると左側(上位)4ビットが消えていることがわかりますね。

ちなみに、左向きのシフトはシフトしたビット分2倍されている(例のように右に4ビットシフトする場合は値を16倍している)とも考えることもできます。このように考えた場合、範囲外に出て消えるビットは「値がオーバーフローした」と考えることができます。同様に右向きの場合はシフトしたビット分1/2倍されていると言えます。

C言語でビットシフトを行う場合はこのように書きます。

右に4ビットシフトさせる場合

B = A >> 4; //(Aは操作前の値 Bはビットシフトさせた後の値)

左に4ビットシフトさせる場合

B = A <<4; //(Aは操作前の値 Bはビットシフトさせた後の値)

C言語の表記は見た目のままなので簡単かなと思います。

なお、int型などで負の数を表したときはいろいろとややこしいことになるようですが、マイコン関連の処理で使うことはまずないと思うので特に詳しいことは書きません。

 

では実際にビットシフトを使う例を示してみましょう。

例えば、PD5からPD7にスイッチが接続されていて、3つのスイッチで値を設定していると考えましょう。今回はPD5PD6のスイッチがHIGHになっていると考えます。そして、最終的に値は下位3ビット(0からまで)で表したいとします。
1

Atmega328PのデータシートのP67を見ると、ポートDのピンの状態を読み込こむレジスタはPINDであることがわかります。

まずは上位3ビットのみを取り出します。

PIND     10101010 (Aとする)

取り出すビット11100000 (Bとする)

A & B   10100000 (Cとする)

続いてビットシフトを行って上位3ビットにいる値を下位3ビットに移動させます。

C              10100000

右に5bitシフト  00000101

こうすると上位3ビットにスイッチを接続して値を設定しても、下位3ビットの値として取り出すことができます。これをC言語で表すとこのように書けます。

uint8_t B = PIND & 0xE0;//0xE0 = 0x11100000 (上位3ビット取り出し)

B= B >> 5;//左に5ビットシフト

(uint8_tは符号なしの8ビットの整数型(Arudinoでいうbyte型)を示しています。)

C言語でもそのままに表せますね。ちなみに、先に行っているビットを取り出す作業は今回の場合は必要ありませんが、必要となる場合も多いので安全のために処理に含めています。(本当に必要になるのは中間のビットを取り出してシフトさせる場合などです)

 

次に通信データ作成の場合を考えてみましょう。

通信の場合できる限り送信のデータ数を少なくしたい場合が多いです。特に1バイトで完結させることができるとプログラムがとても楽に書くことができます。そこで、1バイト(8ビット)にビット数の少ない複数のデータを挿入する方法を紹介します。

ABはそれぞれ4ビットのみで表せる値として、送信データはABの両方を含めて1バイトにしたい場合を考えます。

最初に、ABから下位4ビットのみを取り出します。(もしも上位4ビットにゴミが混ざっていた場合送信データがおかしくなるため)

A          00001110

取り出すビット00001111 (Abとする)

A & Ab  00001110 (Aとする)

B          10001010

取り出すビット00001111 (Bbとする)

B & Bb  00001010 (Dlとする)

この例の場合Bの最上位ビットにゴミの値が入っていますが、下位4ビットのみを取り出すことでこのゴミの値を除去できます。(普通はゴミの値なんて入らないと思いますが…)続いて、Aを上位ビットとするためにAを4ビット左側にシフトします。

A            00001110

左に4itシフト   11100000 (Dhとする)

こうすることでDl(元のB)Dh(元のA)でビットの位置が被らないことになります。そのため、DhDlOR(+でもいい)することで1つのデータに入れれます。

Dl      11100000 (Aとする)

Dh        00001010 (Bとする)

Dh | Dl  11101010 DATA

こうすることでDATAの上位4ビットはゴミを取り除いたAのデータが入っており、下位4ビットにはごみを取り除いたBのデータが入っていることがわかりますね。こうすることで桁が少ない複数の値を1つの値に収めることができるというわけです。これをC言語で書くとこのようになります。

A &= 0x0F;//下位4ビット取り出し(上位4ビットにあるゴミを除去)

B &= 0x0F;

A = A << 4;

uint8_t DATA = A | B;//DATA = A+B;も可

 

次にこのデータをもとのA,Bに戻す方法を紹介します。

まずはAを取り出すために、データAがある上位4ビットのみを抽出します。

DATA        11101010

取り出すビット 11110000 (Abとする)

DATA & Ab     11100000 A

これで、上位4ビットを抽出できたのでこれを下位4ビットにビットシフトさせます。

A              11100000

右に4itシフト    00001110 A

こうすることで元のデータAが取り出すことができました。続いてデータBを取り出します。データBは下位4ビットにいるので下位4ビットのみを抽出します。

DATA       11101010

取り出すビット00001111 (Bbとする)

DATA & Bb   00001010 B

データBはビットシフトを行っていないので抽出した値が元のデータBとなります。これらもC言語で表すとこのようになります。

uint8_t A = DATA & 0xF0;//データ抽出

A = A >> 4;//右に4ビットシフト

uint8_t B = DATA & 0x0F;//データ抽出

 

前回と今回でマイコンのプログラムで重要なビットの処理のお話をしてきました。このビットの処理は慣れるまではちょっと大変ですが、慣れると簡単に扱えるようになると思います。次回はAVRマイコンのプログラミングを行う環境設定のお話をしたいと思います。

制御編 第2回 マイコンで使うビット演算

 前回はマイコンのハードウェアの設計のお話をしましたが、今回からはマイコンのプログラミングについて書いていきたいと思います。まずは、マイコンのレジスタを叩く際に必須と言えるビット演算のお話をしたいと思います。

 

 マイコンをはじめとするコンピュータの世界はデジタル、つまり01しかない世界です。マイコンも例外ではなく大量の01の組み合わせで動いています。コンピュータの世界では1つの01のデータを1ビット、これを8つ組み合わせたものを1バイトと呼びます。つまり1バイト=8ビットというわけです。一般的にはビットはコンピュータのビット数(パソコンだと32ビットだとか64ビットとか言いますね)やシリアル系の通信速度(wifiとかLANの通信速度の〇〇bpsといいますね)で使われて、バイトは容量系の単位(RAM16GBとかROM64GBとかいいますね)に使われることが多いです。

 前置きはこの程度にしておきます。マイコンには変数などで使われる通常のメモリのほかに、レジスタという特殊なメモリ領域があります。このレジスタを使ってマイコンに搭載された機能である入出力などを操作します。今回使用するマイコンは8ビットのAVRマイコンなのでレジスタは基本的に8ビットになっています。例えばポートの出力状態を設定するレジスタにおいても最大8つのポートごとにレジスタが割り当てられているのです。このうち1つのポートだけを操作したい場合などに必要な概念がビット演算というわけです。

ビット演算の基礎の基礎としてまずは論理演算を紹介します。

AND(論理積)

and
and

ANDは論理積ともいえ、日本語で言うと「AかつB」、論理式で表すと”AB” ”AB"などとなります。つまり、掛け算なので入力にどれか1つでも0があった場合は出力が0となります。例えば01ANDすると出力は011ANDすると出力は1となります。C言語のプログラムでは“&&”と表します。

 

OR(論理和)

OR
or

ANDは論理和ともいえ、日本語で言うと「AまたはB」、論理式で表すと”A+B” ”AB”などとなります。つまり、足し算なので入力にどれか1つでも1があった場合は出力が1となります。例えば01ORすると出力は100ORすると出力は0となります。C言語のプログラムでは“||”と表します。

 

NOT(否定)

 NOT
not

NOTは否定ともいえ、日本語で言うと「Aではない」、論理式で表すと”Ā”などと表します。0が入力された場合は1が出力され、10以外)が入力されると0が出力されます。入力に対して出力が反転されるので、論理回路では反転を意味する”inverter”とも言われます。C言語のプログラムではでは”!”と表します。

 

NAND(否定論理積)
NAND
nand

NANDANDの出力にNOTをかけたものです。日本語で言うと「(AかつB)ではない」、論理式で表すと1などとなります。つまり、掛け算の否定なので入力にどれか1つでも0があった場合は出力が1となります。例えば01NANDすると出力は111NANDすると出力は0となります。C言語ではANDしたあとにNOTをかけて「例えば:!(A&&B)」実行します。論理回路ではよく使われますが、マイコンのプログラムの場合は使う機会は少ないかもしれないです。(特定のビットを0にするために入力にNOTをかけてからANDすることは多いですが…)

 

NOR(否定論理和)
NOR
nor

NORORの出力にNOTをかけたものです。日本語で言うと「(AまたはB)ではない」、論理式で表すと2などとなります。つまり、足し算の否定なので入力にどれか1つでも1があった場合は出力が0となります。例えば01NORすると出力は000NORすると出力は1となります。C言語ではORしたあとにNOTをかけて「例えば:!(A||B)」実行します。NANDと同じく論理回路ではよく使われますが、マイコンのプログラムの場合は使う機会は少ないかもしれないです。

 

XOR(排他的論理和)
XOR
xor

XORは排他的論理和と言われる、少し変わった論理演算です。論理式で表すと3となります。入力の1の数が奇数の時に1を出力し、1の個数が偶数の時に0を出力します。こちらは論理回路では使う機会が比較的少ないですが、マイコンのプログラムではそこそこ使います。

 

以上の6つが論理演算ではよく使われてます。基本的には前半の3つであるANDORNOTですべての論理演算が可能です。また、NANDNOR2つでもすべての論理演算が可能です。

 

次に今回の本題であるビット演算のお話をしたいと思います。ビット演算では先ほどまで紹介した論理演算をビット単位で行います。ビット単位でのビット演算を考えるため、まずは演算を行う数値を2進数で表します。2進数表記した値を1桁ずつ論理演算するとビット演算になります。まずは、ANDORNOTXORのプログラミングにおける記号とビット演算するとどのようになるかを紹介します。

AND

C言語での記号は”&” です。論理演算の記号である”&&”と間違えないように注意してください

A 10101010

B 11110000

A & B 10100000

 

OR

C言語での記号は”|” です。論理演算の記号である”||”と間違えないように注意してください

A 10101010

B 11110000

A | B 11111010

 

NOT

C言語での記号は”~” です。

A 10101010

~A 01010101

 

XOR

C言語での記号は”^” です。

A 10101010

B 11110000

A ^ B 01011010

 

C言語ではこの4つのビット演算を使用することができます。これらを使ってレジスタの特定のビットのみの抽出などを行っていきます。

まずはレジスタの例として、atmega328PのポートBの状態(HIGHLOWか)を設定するレジスタを使ってみたいと思います。

Atmega328Pのデータシート(https://avr.jp/user/DS/PDF/mega328P.pdf)のページ65の図の部分より、ポートBの出力状態を切り替えるレジスタは”PORTB”であることがわかります。
2

続いて下部のビットの一覧部を拡大します。
3

図のようにビット0PB0の状態 を制御、ビット1PB1の状態を制御…といったようになっており、各ビットに0を入れると対応するポートがLOW1を入れると対応するポートがHIGHになります。このように、1つのレジスタでPB0からPB7までの8つのピン(厳密にはPB6PC7はたいてい水晶を接続するので6ピンになることが多い)の状態を制御する仕様になっていることがわかると思います。そのため、1つのピンのみを制御しようとして、レジスタに直接値を入力するとPB0からPB7までのすべての状態が変わってしまい不都合が生じてしまいます。ここで必要なのがビット演算というわけです。特定のビットのみを操作したいときは、現在のレジスタの状態と操作するビットが立てられた(1にされた)値をビット演算で比較をします。現在のレジスタの状態はデータシートのビット一覧(上の図)のアクセス種別の表記より読み込みが可能であることがわかります。そのためこのような処理が可能というわけです。

特定のポート(ビット)のみを操作する方法を、例を使って紹介していきたいと思います。それぞれ操作する前の状態はわからない(テキトーな値)になっているとします。

1        PB4HIGHにしたいとき(ビット4のみを1にする)

現在の状態に操作するビットを立てた(1にした)値をORします。 

操作前のPORTB 10101010 (Aとする)

操作するビット  00010000 (Bとする)

A | B 10111010 PORTB

このようにすると元の状態が何であったとしても操作したいビットが確実に1に設定され、ほかのビットは何も影響を受けないことがわかると思います。これをC言語で省略せずに記述するとこのようになります。

PORTB = PORTB | 0b00010000;

ですが、操作するビットを2進数(プログラムでは”0b****”で示す)書いていては入力が大変で、読みにくいです。そのためこれを16進数(プログラムでは”0x**”で示す)に変換します。また、C言語での省略表記も合わせて使うとこのようになります。

PORTB |= 0x10;

先ほどの書き方に比べてとてもスマートになりますね。ですので、基本的にはこの書き方を使っていきたいと思います。

 

2        PB4のみをLOWにしたいとき(ビット4のみを0にする)

操作するビットを立てた(1にした)値にNOTをかけて反転させた値と現在の状態をANDします。

操作するビット 00010000 (Bとする)

~B 11101111 (操作するビットの反転)

操作前のPORTB    10111010 (Aとする)

操作するビットの反転  11101111 (~Bとする)

A & ~B   10101010 PORTB

こうすることで、操作したいビットが確実に0になり、ほかのビットは影響を受けません。C言語で書くと

PORTB = PORTB & (~0b00010000);

となり、省略系にして

PORTB &= ~0x10;

と表せます。

3        PB4のみ状態を入れ替える(ビット4が1だった場合0、0だった場合1にする)

現在の状態と操作するビットを立てた(1にした)値のXORをかけます。

操作前のPORTB 10101010 (Aとする)

操作するビット  00010000 (Bとする)

A ^ B 10111010 PORTB

元のビットの状態が逆のパターン

操作前のPORTB 10111010 (Aとする)

操作するビット  00010000 (Bとする)

A ^ B 10101010 PORTB

このようにすると操作したいビットの状態が入れ替わり、ほかのビットは影響を受けません。C言語で書くと

PORTB = PORTB ^ 0b00010000;

省略して

PORTB ^= 0x10;

と表せます。

レジスタの特定のビットのみを操作するときは基本的にはこの3つを使うことが多いと思います。ビット演算ではほかにも特定のビットのみを取り出したいときにANDを使うときもあります。方法としては元の値に取り出したいビットを立てた(1にした)値をANDします。

例えば、元の値から下4ビットのみを取り出す場合はこのようにします。

元の値    10101010 (Aとする)

取り出すビット00001111 (Bとする)

A & B   00001010

このようにすると上4ビットはすべて0で下4ビットは元の値がそのまま取り出せることがわかります。C言語で書くと以下のようになります。

C = A & 0b00001111; (元の値をA 下4ビットを取り出した値をCとしている)

省略して

C = A & 0x0F;

と表せます。(元の値がレジスタであったり、元の値を保持することが多いので、”A&=0x0F;”と書くことは少ないです。)

この方法はマイコンのレジスタから値を取り出す際や通信の際によく使う手法です。

ビット演算は以上として次回はビットシフトのお話をしたいと思います。

ギャラリー
  • HDDを演奏する楽器を作ってみた
  • HDDを演奏する楽器を作ってみた
  • HDDを演奏する楽器を作ってみた
  • HDDを演奏する楽器を作ってみた
  • 制作日記5 細かな基板を注文してみた
  • 制作日記5 細かな基板を注文してみた
  • 制作日記5 細かな基板を注文してみた
  • 制作日記5 細かな基板を注文してみた
  • 制作日記5 細かな基板を注文してみた
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計: