PIC/16F1705のオペアンプをDACのバッファとして使ってみた
さてきむしげさん(きむ茶工房ガレージハウス)から教えていただいたPIC16F1075なんですが、
Cost Effective 8-Bit Intelligent Analog Flash Microcontrollers
と銘打っているそうです。8bitのDAC(DAコンバータ)以外にもいくつか機能があるのですが、その一つ内蔵オペアンプについて書きます。
16F1705の全体像についてはきむしげさん(きむ茶工房ガレージハウス)の
「16F1705覚書」
が詳しいです。
“実用”に使うのであれば
「PIC16F1705の8ビットDACを使って(実用的)正弦波発振器を作る - 1」
が参考になると思います。またこのオペアンプの特性については
「オペアンプのオフセット電圧とバイアス電流の測定 - PIC16F1705」
「PIC16F1705のオペアンプの周波数特性」
にあります。
----
以前「PICのDAC(DAコンバータ)を使ってみた」に書いたようにPICのDAC出力には
出力抵抗が一番高くなるのは中くらいの電圧が出力されたときで(おそらく)40kΩくらいです。一方出力抵抗が一番低くなるのは出力電圧が最低のときでほぼ0kΩ、また出力電圧が最高のときで(おそらく)5kΩのようです。これらの間を出力抵抗は出力電圧に応じて連続的に変化していきます。
という特性があります。そしてこのため次段の入力抵抗が数百kΩから数MΩないと波形が歪みます。これは16F1705も同じでした(「PIC/16F1705のDAC(DAコンバータ)を使ってみた(ソース付き)」)
これについて
PICと言うと内部プルアップとかいたれりつくせりな印象があるんですが、ぜったいバッファが必要になりそうなDAC出力にバッファがついてないのはなぜなんでしょう。不思議です。
と書いたのですが、16F1705にもバッファはついていないもののオペアンプがついていますのでこれでバッファを作れそうです。
そしてこのオペアンプがまさしくいたれりつくせりの印象があります。
今回もソースを用意しました。
=======
16F1705のオペアンプを使うのは簡単でOPA1CONあるいは OPA2CON の OPAxEN ビットをセットするだけです。
OPA1CONの方をセットすれば10(IN+),9(IN-),8(OUT)がOPA2CONの方をセットすれば5(IN+),6(IN-),7(OUT)がオペアンプの入出力になります。IN+、IN-、OUTと端子を並べIN-、OUTを隣り合わせに置くというオペアンプによく見られる使いやすい配置です。
バッファつまりボルテージフォロワとして使うとなると位相余裕(Phase Margin)が気になりますがデータシートによると(OPAxSP = 1 (High GBWP mode)のとき)
GBWP(Gain Bandwidth Product) = 2MHz
Phase Margin = 40degrees
となっており問題なさそうです。というか設定のみでボルテージフォロワー(Unity Gain)として使うことができるようになっています。OPAxUGビットをセットするとIN+とOUTは内部的に接続されしかもIN-端子は解放されふつうの入出力ピンとして使用できるようになります。なんという心遣いでしょう (^^)
これであとはDAC出力をIN+端子に接続すればバッファとして使えそうですが、じつはその必要はありません。オペアンプの入力は設定でFVR、DAT、IN+のいずれかを選択できるのです。
つまりOPA1CONあるいはOPA2CONを適切に設定すればバッファされたDAC出力が得られるわけです。
これが“このオペアンプがまさしくいたれりつくせり”と書いた理由です。
------
まず前記事にも示したDAC出力のスペクトラムです。
これはDACの出力抵抗の変動の影響を避けるため7MΩの入力抵抗で受けています。
電源ノイズが乗るのもわかっていただけると思います。
オペアンプでバッファされたDAC出力です。
こちらはDAC出力直接つなげば波形が大きくくずれてしまうはずの10KΩという低い抵抗で受けています。
きれいです。DACの出力よりきれいです (^^)
ちなみにDACの出力を直接10kΩで受けたもの。
悲惨です (^^;;
--------
ソースです。
16F1705は初めてなので動かすのには最低何が必要なのかと考えながらコーディングしてみました。こう書いたら動いた、というだけでこれが正しいとか適切であるとかいう意味じゃありませんので念のため。
クロックの記述がありませんが、この場合500kHzになります。
回路的には/MCLRを10kでプルアップしてあるだけです。
DAC出力はオペアンプ2でバッファし7ピン(RC3/OPA2OUT)から取り出しています。今回はオペアンプ出力は10kΩの入力抵抗で受けています。
------
#include <pic.h> #include <math.h> #define _XTAL_FREQ 500000 // delay用クロック設定 // DAC1CON0 #define DAC1EN 0x80 #define DAC1OE2 0x10 #define DAC1PSS_VDD 0x00 #define DAC1NSS_VSS 0x00 // OPAxCON #define OPAxEN 0X80 #define OPAxSP_High 0x40 // 扱う周波数が高いときはこちらの方が安全でしょう。 #define OPAxSP_Low 0x00 #define OPAxUG_ON 0x10 #define OPAxCH_DAC 0x02 #pragma config WDTE = OFF void main() { static short lvl[64]; float PIx2=6.2832; unsigned short i; for( i=0; i<64; i++) lvl[i]=(int)(100.0*sin(PIx2*(float)i/64.0)+128.0); DAC1CON0 = DAC1EN | DAC1OE2 | DAC1PSS_VDD | DAC1NSS_VSS; OPA2CON = OPAxEN | OPAxSP_Low | OPAxUG_ON | OPAxCH_DAC; while(1) { DAC1CON1 = lvl[i & 0x3F]; i++; __delay_us(50); } } // 16F1075 // 01 VDD....(2) // 02 RA5/T1CKI/SOSCI/CLCIN3/OSC1/CLKIN // 03 RA4/AN3/T1G/SOSCO/OSC2/CLKOUT // 04 RA3/MCLR/VPP....(1) // 05 RC5/OPA2IN+/CCP1/RX // 06 RC4/OPA2IN-/CK/CLCIN1 // 07 RC3/AN7/C1IN3-/C2IN3-/OPA2OUT/CCP2/SS/CLCIN0 // 08 RC2/AN6/C1IN2-/C2IN2-/OPA1OUT // 09 RC1/AN5/C1IN1-/C2IN1-/OPA1IN-/SDI/SDA/CLCIN2 // 10 RC0/AN4/C2IN+/OPA1IN+/SCK/SCL // 11 RA2/AN2/DAC1OUT2/ZCD/T0CKI/COGIN/INT // 12 RA1/AN1/VREF+/C1IN0-/C2IN0-/ICSPCLK....(5) // 13 RA0/AN0/VREF-/C1IN+/DAC1OUT/ICSPDAT....(4) // 14 VSS....(3) // DAC1CON0 // #define DAC1EN 0x80 // #define DAC1OE1 0x20 // #define DAC1OE2 0x10 // #define DAC1PSS_FVR 0x08 // #define DAC1PSS_VREF 0x04 // #define DAC1PSS_VDD 0x00 // #define DAC1NSS_VREF 0x01 // #define DAC1NSS_VSS 0x00 // OPAxCON // #define OPAxEN 0X80 // #define OPAxSP_High 0x40 // #define OPAxSP_Low 0x00 // #define OPAxUG_ON 0x10 // #define OPAxUG_OFF 0x00 // #define OPAxCH_FVR 0x03 // #define OPAxCH_DAC 0x02 // #define OPAxCH_OPAxIN 0x00
関連
「記事目次・趣味の電子工作」
「PICのDAC(DAコンバータ)を使ってみた」
「PICのDAコンバータ(DAC)を使ってみた - 補足」
「PIC/16F1705のDAC(DAコンバータ)を使ってみた(ソース付き)」
「I2Cデバイス・アドレス一覧」
「同じアドレスのI2Cデバイスを使う」
「PICで平方根 - 白金薄膜抵抗で温度を測る」
「PICでI2C - ADコンバーター・MCP3425の使い方」
「PICでI2C - MPL115A2の大気圧計算法」
「I2C大気圧センサーLPS331の驚くべき分解能」
「I2C大気圧温度センサーLPS331 - 海面更生気圧を気象庁とくらべてみた」
「I2C大気圧センサーLPS331の分解能はほんとうに高いのか?(温度編)」
「PICでI2C - 1 (温度計を作る)」
「PICでI2C - 液晶(LCD)ディスプレイ(ACM1602N1-FLW-FBW)に表示する」
「PICでI2C - LCD(液晶)ディスプレイによる違い」
「サーミスタによる温度測定の精度」
「サーミスタ温度計の精度を調べる - 1」
「PICで作るお手軽サーミスタ温度計」
「炭素皮膜抵抗の温度係数を測定する話」
「ミニ恒温槽の作成に向けて - 1」
「ミニ恒温槽の作成に向けて - 魔法瓶の活用」
« PIC/16F1705のDAC(DAコンバータ)を使ってみた(ソース付き) | トップページ | GE-612T vs GM-5157T 1PPS対決(GPS受信モジュール) »
「趣味の電子工作」カテゴリの記事
- PICで作る100MHz周波数カウンタ検証用XOR(エクスクルーシブオア)逓倍器(2016.03.08)
- 150MHz(~200MHz?)周波数カウンター用プリスケーラー(1/4分周器)(2016.03.06)
- 測温抵抗体(Pt100、白金薄膜温度センサー)の抵抗値を温度に変換する(平方根を使わない)計算式(2016.03.01)
- GPS/JJY(標準電波)を基準周波数源とするためのPLLの詳細(2016.02.27)
- GPS受信モジュール1PPS対決 - GE-612T vs GM-5157A(2016.02.21)
コメント
この記事へのコメントは終了しました。
« PIC/16F1705のDAC(DAコンバータ)を使ってみた(ソース付き) | トップページ | GE-612T vs GM-5157T 1PPS対決(GPS受信モジュール) »
やっとこの辺までたどり着きました^^
PicKit2では書き込みができない石なので「からくり工房」さんのところの方法を取りました。
質問なのですが、これを動作させるときは、クリスタルやセラロックなどの外部クロック入力は不要なのでしょうか。
投稿: ほよほよ | 2015年1月30日 (金) 14時32分
正弦波を出せればいいということであれば内蔵発振器で十分ですよ。
周波数の確度や安定性を求めるならクリスタルを使うべきでしょうが。
じつは実際の実験に使うものを作っておりそろそろ記事にしようと思っていたところでした (^^;;
この記事はクロック500kHzでやっていますが32MHzにしてこの記事と同じサンプル64点で3kHzくらいが限度でした。タイマー割り込みを使うと割込みのオーバーヘッドで周波数が伸ばせないような気がしてやめにしたのですがどうなんでしょう。
アセンブラーで書くというのがいちばんいいのでしょうが面倒で....
そう言えば私も(PICkit3なのに)PICkit2と思い込んでいて一生懸命ググりました (^^;;
投稿: セッピーナ | 2015年1月30日 (金) 15時13分
マニュアルを読んでいてReset直後は500kHzですよ、って書いてありました^^;
つまらない質問してすみませんm(u_u)m
ループ内だけ、asm("hoge hoge"); でひたすら書くというのはどうなんでしょうか?
ここのところずっとMPLABと格闘してましたがやっと光が見えてきました^^。
投稿: ほよほよ | 2015年1月30日 (金) 16時44分
じつはCのソースにどうやってアセンブラーを埋め込むかわかっていませんでした (^^;;
もうちょっとちゃんと勉強してみます。
やっぱり周波数の確度・安定度はほしいわけで水晶にしようと思いました。
8MHzの水晶がないので10MHzをつないだらちゃんと40MHzで動いている模様です (^^)
投稿: セッピーナ | 2015年1月30日 (金) 20時27分