« PIC/16F1705のDAC(DAコンバータ)を使ってみた(ソース付き) | トップページ | GE-612T vs GM-5157T 1PPS対決(GPS受信モジュール) »

2014年11月22日 (土)

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Ωの入力抵抗で受けています。
電源ノイズが乗るのもわかっていただけると思います。
L100s64spc

オペアンプでバッファされたDAC出力です。
こちらはDAC出力直接つなげば波形が大きくくずれてしまうはずの10KΩという低い抵抗で受けています。
L100s64vf10kspc

きれいです。DACの出力よりきれいです (^^)

ちなみにDACの出力を直接10kΩで受けたもの。
L100s6410kspc

悲惨です (^^;;

--------

ソースです。

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受信モジュール) »

趣味の電子工作」カテゴリの記事

コメント

やっとこの辺までたどり着きました^^
PicKit2では書き込みができない石なので「からくり工房」さんのところの方法を取りました。
質問なのですが、これを動作させるときは、クリスタルやセラロックなどの外部クロック入力は不要なのでしょうか。

正弦波を出せればいいということであれば内蔵発振器で十分ですよ。
周波数の確度や安定性を求めるならクリスタルを使うべきでしょうが。
じつは実際の実験に使うものを作っておりそろそろ記事にしようと思っていたところでした (^^;;
この記事はクロック500kHzでやっていますが32MHzにしてこの記事と同じサンプル64点で3kHzくらいが限度でした。タイマー割り込みを使うと割込みのオーバーヘッドで周波数が伸ばせないような気がしてやめにしたのですがどうなんでしょう。
アセンブラーで書くというのがいちばんいいのでしょうが面倒で....
そう言えば私も(PICkit3なのに)PICkit2と思い込んでいて一生懸命ググりました (^^;;

マニュアルを読んでいてReset直後は500kHzですよ、って書いてありました^^;
つまらない質問してすみませんm(u_u)m
ループ内だけ、asm("hoge hoge"); でひたすら書くというのはどうなんでしょうか?
ここのところずっとMPLABと格闘してましたがやっと光が見えてきました^^。

じつはCのソースにどうやってアセンブラーを埋め込むかわかっていませんでした (^^;;
もうちょっとちゃんと勉強してみます。
やっぱり周波数の確度・安定度はほしいわけで水晶にしようと思いました。
8MHzの水晶がないので10MHzをつないだらちゃんと40MHzで動いている模様です (^^)

この記事へのコメントは終了しました。

トラックバック


この記事へのトラックバック一覧です: PIC/16F1705のオペアンプをDACのバッファとして使ってみた:

« PIC/16F1705のDAC(DAコンバータ)を使ってみた(ソース付き) | トップページ | GE-612T vs GM-5157T 1PPS対決(GPS受信モジュール) »

フォト

サイト内検索

  • 記事を探されるんでしたらこれがいちばん早くて確実です。私も使ってます (^^;; 検索窓が表示されるのにちょっと時間がかかるのはどうにかしてほしいです。

新着記事

リンク元別アクセス数

  • (アクセス元≒リンク元、原則PCのみ・ドメイン別、サイト内等除く)

人気記事ランキング

  • (原則PCのみ、直近2週間)
無料ブログはココログ