概要
PICシリーズのマイコンには、古くからさまざまなバリエーションでオペアンプモジュールが搭載されてきました。これらのモジュールは、ゲイン帯域積(GB積)やスルーレート、内蔵されている機能などが製品によって異なります(fig.1参照)。
今回紹介する PIC18F26/46/56Q71 シリーズに搭載されているオペアンプは、以下のような特徴を備えており、非常に高機能なのが特長です。
汎用的な3端子オペアンプ構成
通常のオペアンプとして動作する標準的な構造を採用しています。
5.5 MHzのゲイン帯域幅
高速なアナログ信号処理が可能で、幅広い用途に対応できます。
複数の入力端子
非反転入力(OPAxIN+)、反転入力(OPAxIN−)が複数用意されており、柔軟な回路構成が可能です。
専用の外部出力端子(OPAxOUT)
出力を外部に取り出すための専用ピンが用意されています。
内蔵抵抗ラダーによるプログラマブルゲイン
内部に構成された抵抗ネットワークを用いて、ソフトウェアでゲイン設定が可能です。
入力ソースの柔軟な選択
正入力・負入力ともに、さまざまな内部/外部ソースから選択できます。
出力ドライブのハードウェア制御機能
以下のようなモードを持ち、出力の挙動を制御できます:
- ユニティゲイン(1倍)強制モード
- レールドライブ(電源電圧振幅)強制モード
- ピーク検出モード
- トラフ(谷)検出モード
- トライステート(高インピーダンス)モード
入力オフセット電圧の補正機能
ソフトウェアで補正値を設定する方式と、自動で補正を行う方式の両方に対応しています。
ADCとの内部接続が可能
OPAをADCの入力前段に接続することで、プログラマブルゲインアンプとして利用できます。
DACとの内部接続が可能
OPAの入力にDAC出力を接続することで、DACの基準電圧源としても使用できます。
PICシリーズのオペアンプのタイプ
| 機能/タイプ | ベーシック タイプ | オーバーライド機能タイプ | ゲイン付き多機能オペアンプ | 高速タイプ | 超高速タイプ |
|---|---|---|---|---|---|
| シリーズ | PIC16F1716など | PIC16F1764など | PIC18F56Q71など | dsPIC33CH/ dsPIC33CK | dsPIC33A |
| GB積(MHz) | 3.5 | 3 | 5.5 | ? / 20 | 100 |
| スルーレート(V/μs) | 3 | 3 | 6 | ? / 40 | 40 |
| オフセット調整 | × | × | 〇 | × / × | 〇 |
| ユニティゲイン設定 | 〇 | 〇 | 〇 | × / × | 〇 |
| 内蔵ゲイン設定 | × | × | 〇(8ステップ) | 〇(4ステップ) / × | × |
| FVR(固定電圧リファレンス)連携 | ○ | ○ | × | × / × | × |
| DAC連携 | × | ○ | ○ | × / × | × |
| オーバーライド機能 | × | ・通常 ・ユニティゲイン ・トライステート | ・通常 ・ユニティゲイン ・トライステート ・ピーク検出 ・トラフ検出 | × / × | × |





オペアンプ(オペレーショナルアンプ、英: Operational Amplifier)は、電子回路の基本的な部品の一つで、「増幅器(アンプ)」の一種です。小さな電圧差を大きく増幅する能力を持ち、アナログ回路では非常によく使われます。
更新履歴
| 公開/変更日 | 更新内容 |
| 2025.04.24 | 初版公開 |
| 2025.09.16 | リンク追加、誤記修正 |
| 2025.09.17 | ピーク検出モード記事追加 |
関連リンク
内部リンク
| 記事 | リンク | |
| 第1回 | 8bitPICシリーズ① PRGモジュールの使い方 | 8bitPICシリーズ①PRGモジュールの使い方 – ぴくおの電子工作的な何かWP |
| 第2回 | 8bitPICシリーズ② PWMモジュールの使い方 | 8bitPICシリーズ②PWMモジュールの使い方 – ぴくおの電子工作的な何かWP |
| 第3回 | 8bitPICシリーズ③ SMTモジュールの使い方 | 8bitPICシリーズ③SMTモジュールの使い方 – ぴくおの電子工作的な何かWP |
| 第4回 | 8bitPICシリーズ④ Timerモジュールの使い方 | 8bitPICシリーズ④Timerモジュールの使い方 – ぴくおの電子工作的な何かWP |
| 第5回 | 8bitPICシリーズ⑤ Angular Timer モジュールの使い方 | 8bitPICシリーズ⑤Angular Timer モジュールの使い方 – ぴくおの電子工作的な何かWP |
| 第6回 | 8bitPICシリーズ⑥ CLB(Configurable Logic Block)モジュールの使い方 | 8bitPICシリーズ⑥CLB(Configurable Logic Block)モジュールの使い方 – ぴくおの電子工作的な何かWP |
| 第7回 | 8bitPICシリーズ⑦ オペアンプモジュールの使い方 | 8bitPICシリーズ⑦オペアンプモジュールの使い方 – ぴくおの電子工作的な何かWP |
| 第8回 | 8bitPICシリーズ⑧コンテキスト切り替え機能付きADC(ADCCC)モジュールの使い方 | 8bitPICシリーズ⑧コンテキスト切り替え機能付きADC(ADCCC)モジュールの使い方 – ぴくおの電子工作的な何かWP |
| 第9回 | ||
| 第10回 |
外部リンク
| サイト | リンク先 |
| PIC18F56Q71データシート | PIC18F56Q71 | Microchip Technology |
| テクニカルブリーフ | Using the Operational Amplifier on PIC16 and PIC18 TB3280 |
| PIC18F56Q71 マイクロコントローラと MCC Melody を使用した OPA、ADC、PWM による LED 電流制御 | microchip-pic-avr-examples/pic18f56q71-led-current-control-opamp at 1.0.1 |
| 超音波距離検出機能を備えたアナログ内蔵による信号増幅の微調整 | microchip-pic-avr-examples/pic18f56q71-ultrasonic-range-detection-mplab-mcc at 1.0.0 |
ハードウェアブロック図
以下にオペアンプモジュールのブロック図を示します。なお、本図にはオーバーライド機能に関する回路は省略されています。

レジスタ
下記にオペアンプに関するレジスタとビット名、機能について示します。
| レジスタ名 | ビット名 | 機能 | 初期値 |
| OPAxCON0 | EN | オペアンプ有効化ビット 0 = 無効 , 1 = 有効 | 0 |
| CPON | チャージポンプ有効化ビット オンにすると消費電流は増加しますが、Vdd近くまで信号を扱えます。 0 = 無効 , 1 = 有効 | 0 | |
| UG | ユニティゲイン選択ビット 0 = 反転入力はOPAxIN- pin 1 = 反転入力はOPAxOUT | 0 | |
| OPAxCON1 | GSEL[2:0] | ゲイン設定(R1 : R2) 0 = 15 : 1 1 = 14 : 2 2 = 12 : 4 3 = 8 : 8 4 = 6 : 10 5 = 4 : 12 6 = 2 : 14 7 = 1 : 15 | 0 |
| RESON | レジスタラダー有効化ビット 0 = 無効 , 1 = 有効 | 0 | |
| NSS[2:0] | 負入力ソース選択 0 = OPAxIN0- 1 = OPAxIN1- 2 = OPAxIN2- 3 = OPAxIN3- 7 = Vss | 0 | |
| OPAxCON2 | NCH[2:0] | 反転入力チャンネル選択 0 = 未接続 1 = 内蔵抵抗ラダー 2 = OPAxIN- 3 = Vss 4 = DAC1 5 = DAC2 6 = DAC3 | 0 |
| PCH[2:0] | 非反転入力チャンネル選択 0 = Vss 1 = 内蔵抵抗ラダー 2 = OPAxIN+ 3 = Vdd/2 4 = DAC1 5 = DAC2 6 = DAC3 | 0 | |
| OPAxCON3 | FMS[1:0] | フィードバックモード選択 0 = 未接続 1 = Vdd 2 = OPAxOUT | 0 |
| INTOE | 出力モード 0 = 出力ピン 1 = DAC / ADC | 0 | |
| PSS[1:0] | 正入力ソース選択 0 = OPAxIN0+ 1 = OPAxIN1+ 2 = OPAxIN2+ 3 = OPAxIN3+ | 0 | |
| OPAxCON4 | PTRES | ピーク/トラフ検出リセットビット 0 = リセットしない 1 = リセットする | 0 |
| OFCST | 自動入力オフセット電圧キャリブレーション開始ビット 0 = 開始しない 1 = 開始する | 0 | |
| OFCSEL[1:0] | 入力オフセット電圧ソース選択 0 = OPAxOFFSETレジスタに格納されている工場出荷時に較正された入力オフセット電圧の値 1 = OPAxOFFSETレジスタに書き込まれた値 2 = 自動入力オフセット電圧較正シーケンスの結果 | 0 | |
| OPAxHWC | OREN | オーバーライド有効化ビット 0 = 無効 , 1 = 有効 | 0 |
| HWCH[2:0] | オーバーライドハードウェア制御ビットHigh 0 = 基本設定 / ユーザ定義フィードバック 1 = ピーク検出/ ユーザ定義フィードバック 2 = トラフ検出/ ユーザ定義フィードバック 3 = トライステート出力 4 = 基本設定 / ユニティゲインフィードバック 5 = ピーク検出/ ユニティゲインフィードバック 6 = トラフ検出/ ユニティゲインフィードバック 7 = Vdd | 0 | |
| ORPOL | オーバーライドソース反転ビット 0 = 非反転 1 = 反転 | 0 | |
| HWCL[2:0] | オーバーライドハードウェア制御ビットLow 0 = 基本設定 / ユーザ定義フィードバック 1 = ピーク検出/ ユーザ定義フィードバック 2 = トラフ検出/ ユーザ定義フィードバック 3 = トライステート出力 4 = 基本設定 / ユニティゲインフィードバック 5 = ピーク検出/ ユニティゲインフィードバック 6 = トラフ検出/ ユニティゲインフィードバック 7 = Vss | 0 | |
| OPAxORS | OPAxORS | オーバーライドソース 31 = LOGIC_HIGH 30 = LOGIC_LOW 29 = CLC8_OUT 28 = CLC7_OUT 27 = CLC6_OUT 26 = CLC5_OUT 25 = CLC4_OUT 24 = CLC3_OUT 23 = CLC2_OUT 22 = CLC1_OUT 21 = ZCD_OUT 20 = CMP2_OUT 19 = CMP1_OUT 18 = NCO1_OUT 17 = PWM3S1P2_OUT 16 = PWM3S1P1_OUT 15 = PWM2S1P2_OUT 14 = PWM2S1P1_OUT 13 = PWM1S1P2_OUT 12 = PWM1S1P1_OUT 11 = CCP2_OUT 10 = CCP1_OUT 9 = TU16B_OUT 8 = TU16A_OUT 7 = TMR4_OUT 6 = TMR3_OUT 5 = TMR2_OUT 4 = TMR1_OUT 3 = TMR0_OUT 2 = SOSC 1 = LFINTOSC 0 = OPAXORPPS | 0 |
| OPAxOFFSET | OFFSET[7:0] | オフセット調整値 | 0 |
共通ソースコード
今回の記事すべてに共通するソースコードを示します。
#pragma config FEXTOSC = ECH // External Oscillator Selection->EC (external clock) above 8 MHz
#pragma config RSTOSC = HFINTOSC_64MHZ // Reset Oscillator Selection->HFINTOSC with HFFRQ = 64 MHz and CDIV = 1:1
//CONFIG2
#pragma config CLKOUTEN = OFF // Clock out Enable bit->CLKOUT function is disabled
#pragma config PR1WAY = ON // PRLOCKED One-Way Set Enable bit->PRLOCKED bit can be cleared and set only once
#pragma config BBEN = OFF // Boot Block enable bit->Boot block disabled
#pragma config CSWEN = ON // Clock Switch Enable bit->Writing to NOSC and NDIV is allowed
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable bit->Fail-Safe Clock Monitor enabled
#pragma config FCMENP = ON // Fail-Safe Clock Monitor - Primary XTAL Enable bit->Fail-Safe Clock Monitor enabled; timer will flag FSCMP bit and OSFIF interrupt on EXTOSC failure.
#pragma config FCMENS = ON // Fail-Safe Clock Monitor - Secondary XTAL Enable bit->Fail-Safe Clock Monitor enabled; timer will flag FSCMP bit and OSFIF interrupt on SOSC failure.
//CONFIG3
#pragma config MCLRE = EXTMCLR // MCLR Enable bit->If LVP = 0, MCLR pin is MCLR; If LVP = 1, RE3 pin function is MCLR
#pragma config PWRTS = PWRT_OFF // Power-up timer selection bits->PWRT is disabled
#pragma config MVECEN = OFF // Multi-vector enable bit->Interrupt contoller does not use vector table to prioritze interrupts
#pragma config IVT1WAY = ON // IVTLOCK bit One-way set enable bit->IVTLOCKED bit can be cleared and set only once
#pragma config LPBOREN = OFF // Low Power BOR Enable bit->Low-Power BOR disabled
#pragma config BOREN = SBORDIS // Brown-out Reset Enable bits->Brown-out Reset enabled , SBOREN bit is ignored
//CONFIG4
#pragma config BORV = VBOR_1P9 // Brown-out Reset Voltage Selection bits->Brown-out Reset Voltage (VBOR) set to 1.9V
#pragma config ZCD = OFF // ZCD Disable bit->ZCD module is disabled. ZCD can be enabled by setting the ZCDSEN bit of ZCDCON
#pragma config PPS1WAY = ON // PPSLOCK bit One-Way Set Enable bit->PPSLOCKED bit can be cleared and set only once; PPS registers remain locked after one clear/set cycle
#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit->Stack full/underflow will cause Reset
#pragma config LVP = ON // Low Voltage Programming Enable bit->Low voltage programming enabled. MCLR/VPP pin function is MCLR. MCLRE configuration bit is ignored
#pragma config XINST = OFF // Extended Instruction Set Enable bit->Extended Instruction Set and Indexed Addressing Mode disabled
//CONFIG5
#pragma config WDTCPS = WDTCPS_31 // WDT Period selection bits->Divider ratio 1:65536; software control of WDTPS
#pragma config WDTE = OFF // WDT operating mode->WDT Disabled; SWDTEN is ignored
//CONFIG6
#pragma config WDTCWS = WDTCWS_7 // WDT Window Select bits->window always open (100%); software control; keyed access not required
#pragma config WDTCCS = SC // WDT input clock selector->Software Control
//CONFIG7
#pragma config BBSIZE = BBSIZE_16384 // Boot Block Size Selection bits->Boot Block size is 16384 words
//CONFIG8
#pragma config SAFSZ = SAFSZ_NONE // SAF Block Size Selection bits->NONE
//CONFIG9
#pragma config WRTB = OFF // Boot Block Write Protection bit->Boot Block not Write protected
#pragma config WRTC = OFF // Configuration Register Write Protection bit->Configuration registers not Write protected
#pragma config WRTD = OFF // Data EEPROM Write Protection bit->Data EEPROM not Write protected
#pragma config WRTSAF = OFF // SAF Write protection bit->SAF not Write Protected
#pragma config WRTAPP = OFF // Application Block write protection bit->Application Block not write protected
//CONFIG10
#pragma config CPD = OFF // Data EEPROM Code Protection bit->Data EEPROM code protection disabled
//CONFIG11
#pragma config CP = OFF // PFM Code Protection bit->PFM code protection disabled
#define OPAMP_OPACON0_EN_DISABLE ( 0 )
#define OPAMP_OPACON0_EN_ENABLE ( 1 )
#define OPAMP_OPACON0_CPON_PUMP_OFF ( 0 )
#define OPAMP_OPACON0_CPON_PUMP_ON ( 1 )
#define OPAMP_OPACON0_UG_DISABLE ( 0 )
#define OPAMP_OPACON0_UG_ENABLE ( 1 )
#define OPAMP_OPACON1_GSEL_15R_1R ( 0 )
#define OPAMP_OPACON1_GSEL_14R_2R ( 1 )
#define OPAMP_OPACON1_GSEL_12R_4R ( 2 )
#define OPAMP_OPACON1_GSEL_8R_8R ( 3 )
#define OPAMP_OPACON1_GSEL_6R_10R ( 4 )
#define OPAMP_OPACON1_GSEL_4R_12R ( 5 )
#define OPAMP_OPACON1_GSEL_2R_14R ( 6 )
#define OPAMP_OPACON1_GSEL_1R_15R ( 7 )
#define OPAMP_OPACON1_RESON_DISABLE ( 0 )
#define OPAMP_OPACON1_RESON_ENABLE ( 1 )
#define OPAMP_OPACON1_NSS_OPAXIN0M ( 0 )
#define OPAMP_OPACON1_NSS_OPAXIN1M ( 1 )
#define OPAMP_OPACON1_NSS_OPAXIN2M ( 2 )
#define OPAMP_OPACON1_NSS_OPAXIN3M ( 3 )
#define OPAMP_OPACON1_NSS_VSS ( 7 )
#define OPAMP_OPACON2_PCH_VSS ( 0 )
#define OPAMP_OPACON2_PCH_GSEL ( 1 )
#define OPAMP_OPACON2_PCH_PSS ( 2 )
#define OPAMP_OPACON2_PCH_VDDDIV2 ( 3 )
#define OPAMP_OPACON2_PCH_DAC1 ( 4 )
#define OPAMP_OPACON2_PCH_DAC2 ( 5 )
#define OPAMP_OPACON2_PCH_DAC3 ( 6 )
#define OPAMP_OPACON2_NCH_NC ( 0 )
#define OPAMP_OPACON2_NCH_GSEL ( 1 )
#define OPAMP_OPACON2_NCH_PSS ( 2 )
#define OPAMP_OPACON2_NCH_VSS ( 3 )
#define OPAMP_OPACON2_NCH_DAC1 ( 4 )
#define OPAMP_OPACON2_NCH_DAC2 ( 5 )
#define OPAMP_OPACON2_NCH_DAC3 ( 6 )
#define OPAMP_OPACON3_PSS_OPAXIN0P ( 0 )
#define OPAMP_OPACON3_PSS_OPAXIN1P ( 1 )
#define OPAMP_OPACON3_PSS_OPAXIN2P ( 2 )
#define OPAMP_OPACON3_PSS_OPAXIN3P ( 3 )
#define OPAMP_OPACON3_INTOE_DISABLE ( 0 )
#define OPAMP_OPACON3_INTOE_ENABLE ( 1 )
#define OPAMP_OPACON3_FMS_NC ( 0 )
#define OPAMP_OPACON3_FMS_VDD ( 1 )
#define OPAMP_OPACON3_FMS_OUT ( 2 )
#define OPAMP_OPACON4_OFCSEL_FACTORY ( 0 )
#define OPAMP_OPACON4_OFCSEL_OPAXOFFSET ( 1 )
#define OPAMP_OPACON4_OFCSEL_AUTO ( 2 )
#define OPAMP_OPACON4_OFCST_NOT_PRGRS ( 0 )
#define OPAMP_OPACON4_OFCST_START ( 1 )
#define OPAMP_OPACON4_PTRES_NO_RESET ( 0 )
#define OPAMP_OPACON4_PTRES_RESET ( 1 )
#define OPAMP_OPAHWC_HWCL_BASIC_USER_DEF_FB ( 0 )
#define OPAMP_OPAHWC_HWCL_PEAK_USER_DEF_FB ( 1 )
#define OPAMP_OPAHWC_HWCL_TROUGH_USER_DEF_FB ( 2 )
#define OPAMP_OPAHWC_HWCL_TRISTATE ( 3 )
#define OPAMP_OPAHWC_HWCL_BASIC_UG ( 4 )
#define OPAMP_OPAHWC_HWCL_PEAK_UG ( 5 )
#define OPAMP_OPAHWC_HWCL_TROUGH_UG ( 6 )
#define OPAMP_OPAHWC_HWCL_VSS ( 7 )
#define OPAMP_OPAHWC_ORPOL_NOT_INVERT ( 0 )
#define OPAMP_OPAHWC_ORPOL_INVERT ( 1 )
#define OPAMP_OPAHWC_HWCH_BASIC_USER_DEF_FB ( 0 )
#define OPAMP_OPAHWC_HWCH_PEAK_USER_DEF_FB ( 1 )
#define OPAMP_OPAHWC_HWCH_TROUGH_USER_DEF_FB ( 2 )
#define OPAMP_OPAHWC_HWCH_TRISTATE ( 3 )
#define OPAMP_OPAHWC_HWCH_BASIC_UG ( 4 )
#define OPAMP_OPAHWC_HWCH_PEAK_UG ( 5 )
#define OPAMP_OPAHWC_HWCH_TROUGH_UG ( 6 )
#define OPAMP_OPAHWC_HWCH_VDD ( 7 )
#define OPAMP_OPAHWC_OREN_DISABLE ( 0 )
#define OPAMP_OPAHWC_OREN_ENABLE ( 1 )
#define OPAMP_OPAORS_ORS_LOGIC_HIGH ( 0x1F )
#define OPAMP_OPAORS_ORS_LOGIC_LOW ( 0x1E )
#define OPAMP_OPAORS_ORS_CLC8_OUT ( 0x1D )
#define OPAMP_OPAORS_ORS_CLC7_OUT ( 0x1C )
#define OPAMP_OPAORS_ORS_CLC6_OUT ( 0x1B )
#define OPAMP_OPAORS_ORS_CLC5_OUT ( 0x1A )
#define OPAMP_OPAORS_ORS_CLC4_OUT ( 0x19 )
#define OPAMP_OPAORS_ORS_CLC3_OUT ( 0x18 )
#define OPAMP_OPAORS_ORS_CLC2_OUT ( 0x17 )
#define OPAMP_OPAORS_ORS_CLC1_OUT ( 0x16 )
#define OPAMP_OPAORS_ORS_ZCD_OUT ( 0x15 )
#define OPAMP_OPAORS_ORS_CMP2_OUT ( 0x14 )
#define OPAMP_OPAORS_ORS_CMP1_OUT ( 0x13 )
#define OPAMP_OPAORS_ORS_NCO1_OUT ( 0x12 )
#define OPAMP_OPAORS_ORS_PWM3S1P2_OUT ( 0x11 )
#define OPAMP_OPAORS_ORS_PWM3S1P1_OUT ( 0x10 )
#define OPAMP_OPAORS_ORS_PWM2S1P2_OUT ( 0x0F )
#define OPAMP_OPAORS_ORS_PWM2S1P1_OUT ( 0x0E )
#define OPAMP_OPAORS_ORS_PWM1S1P2_OUT ( 0x0D )
#define OPAMP_OPAORS_ORS_PWM1S1P1_OUT ( 0x0C )
#define OPAMP_OPAORS_ORS_CCP2_OUT ( 0x0B )
#define OPAMP_OPAORS_ORS_CCP1_OUT ( 0x0A )
#define OPAMP_OPAORS_ORS_TU16B_OUT ( 0x09 )
#define OPAMP_OPAORS_ORS_TU16A_OUT ( 0x08 )
#define OPAMP_OPAORS_ORS_TMR4_OUT ( 0x07 )
#define OPAMP_OPAORS_ORS_TMR3_OUT ( 0x06 )
#define OPAMP_OPAORS_ORS_TMR2_OUT ( 0x05 )
#define OPAMP_OPAORS_ORS_TMR1_OUT ( 0x04 )
#define OPAMP_OPAORS_ORS_TMR0_OUT ( 0x03 )
#define OPAMP_OPAORS_ORS_SOSC ( 0x02 )
#define OPAMP_OPAORS_ORS_LFINTOSC ( 0x01 )
#define OPAMP_OPAORS_ORS_OPAXORPPS ( 0x00 )
void Clock_Init(void)
{
// Set the CLOCK CONTROL module to the options selected in the user interface.
OSCCON1 = (0 << _OSCCON1_NDIV_POSN) // NDIV 1
| (6 << _OSCCON1_NOSC_POSN); // NOSC HFINTOSC
OSCCON3 = (0 << _OSCCON3_SOSCPWR_POSN) // SOSCPWR Low power
| (0 << _OSCCON3_CSWHOLD_POSN); // CSWHOLD may proceed
OSCEN = (0 << _OSCEN_EXTOEN_POSN) // EXTOEN disabled
| (0 << _OSCEN_HFOEN_POSN) // HFOEN disabled
| (0 << _OSCEN_MFOEN_POSN) // MFOEN disabled
| (0 << _OSCEN_LFOEN_POSN) // LFOEN disabled
| (0 << _OSCEN_SOSCEN_POSN) // SOSCEN disabled
| (0 << _OSCEN_ADOEN_POSN) // ADOEN disabled
| (0 << _OSCEN_PLLEN_POSN); // PLLEN disabled
OSCFRQ = (8 << _OSCFRQ_HFFRQ_POSN); // HFFRQ 64_MHz
OSCTUNE = (0 << _OSCTUNE_TUN_POSN); // TUN 0x0
ACTCON = (0 << _ACTCON_ACTEN_POSN) // ACTEN disabled
| (0 << _ACTCON_ACTUD_POSN); // ACTUD enabled
FSCMCON = (0 << _FSCMCON_FSCMFEV_POSN) // FSCMFEV detected
| (0 << _FSCMCON_FSCMFFI_POSN) // FSCMFFI enabled
| (0 << _FSCMCON_FSCMPEV_POSN) // FSCMPEV detected
| (0 << _FSCMCON_FSCMPFI_POSN) // FSCMPFI enabled
| (0 << _FSCMCON_FSCMSEV_POSN) // FSCMSEV detected
| (0 << _FSCMCON_FSCMSFI_POSN); // FSCMSFI enabled
}
設定例1) ユニティゲインモード
ユニティゲインとは
ユニティゲインアンプ(利得1倍)は、入力信号をそのまま出力するだけに見えますが、次のような場面で大いに活躍します。
・高入力インピーダンス
センサーや前段回路からの信号を“そっと”取り込み、負荷をかけずに次段へ渡せる。
・低出力インピーダンス
大電流ドライブやケーブル長のある伝送でも電圧降下を抑えられる。
・信号の分配
1つの信号源を複数の回路へ分配するバッファとして。
・アイソレーション(絶縁)
前段の動作点やバイアスに影響なく信号だけを伝送。
内部ブロック図

ソースコード
int main(void)
{
INTERRUPT_GlobalInterruptDisable();
Clock_Init();
ANSELAbits.ANSELA1 = 1; //OPA1OUT
ANSELAbits.ANSELA2 = 1; //OPA1IN0+
OPA1CON0bits.EN = OPAMP_OPACON0_EN_DISABLE;
OPA1CON0bits.CPON = OPAMP_OPACON0_CPON_PUMP_ON;
OPA1CON0bits.UG = OPAMP_OPACON0_UG_ENABLE;
OPA1CON1bits.GSEL = OPAMP_OPACON1_GSEL_15R_1R;
OPA1CON1bits.RESON = OPAMP_OPACON1_RESON_DISABLE;
OPA1CON1bits.NSS = OPAMP_OPACON1_NSS_OPAXIN0M;
OPA1CON2bits.PCH = OPAMP_OPACON2_PCH_PSS;
OPA1CON2bits.NCH = OPAMP_OPACON2_NCH_NC;
OPA1CON3bits.PSS = OPAMP_OPACON3_PSS_OPAXIN0P;
OPA1CON3bits.INTOE = OPAMP_OPACON3_INTOE_DISABLE;
OPA1CON3bits.FMS = OPAMP_OPACON3_FMS_NC;
OPA1CON4bits.OFCSEL = OPAMP_OPACON4_OFCSEL_FACTORY;
OPA1CON4bits.OFCST = OPAMP_OPACON4_OFCST_NOT_PRGRS;
OPA1CON4bits.PTRES = OPAMP_OPACON4_PTRES_NO_RESET;
OPA1HWCbits.HWCL = OPAMP_OPAHWC_HWCL_BASIC_USER_DEF_FB;
OPA1HWCbits.ORPOL = OPAMP_OPAHWC_ORPOL_NOT_INVERT;
OPA1HWCbits.HWCH = OPAMP_OPAHWC_HWCH_BASIC_USER_DEF_FB;
OPA1HWCbits.OREN = OPAMP_OPAHWC_OREN_DISABLE;
OPA1ORS = OPAMP_OPAORS_ORS_OPAXORPPS;
OPA1OFFSET = 0u;
OPA1CON0bits.EN = OPAMP_OPACON0_EN_ENABLE;
while(1)
{
}
}
結果
オシロスコープのDDS機能を使って、±1Vの振幅に2.5Vのオフセットを加えたサイン波を出力。この信号をオペアンプの非反転入力(OPA1IN0+端子)に接続しています。オペアンプはユニティゲイン(利得1倍)の構成で動作させ、その出力をモニタしました。
下の波形は、以下の3つの信号を示しています:
CH1:DDSから出力された入力信号(オペアンプの非反転入力)
CH3:オペアンプの出力
Ref:入力(CH1)と出力(CH3)の差分(CH1 – CH3)
手持ちのオシロスコープには周波数応答特性を自動で測定する機能がないため、周波数を手動で変更しながら測定。
その結果、100kHzはもちろん、5MHzの高周波信号を入力しても、オペアンプはユニティゲイン(利得1倍)構成で問題なく動作していることが確認できました。


設定例2) 非反転増幅/外部固定ゲインモード
非反転増幅器とは
非反転増幅器(利得=1+R₂/R₁)は、オペアンプの基本的かつもっともよく使われる増幅回路の一つです。以下のような特徴があります。
・調整可能なゲイン
抵抗比を変えるだけで簡単に増幅度(1倍以上)を設定できる。ただし、1倍未満は設定不可
・高入力インピーダンス
非反転端子はほぼ理想的に高インピーダンス。センサーなどの前段に優しい。
・低出力インピーダンス
大電流ドライブやケーブル長のある伝送でも信号をしっかり押し出せる。
・精密増幅が可能
精密抵抗を使えば、安定した正確なゲインが得られる。
内部ブロック図

ソースコード
int main(void)
{
INTERRUPT_GlobalInterruptDisable();
Clock_Init();
ANSELAbits.ANSELA1 = 1; //OPA1OUT
ANSELAbits.ANSELA2 = 1; //OPA1IN0+
ANSELAbits.ANSELA4 = 1; //OPA1IN1-
OPA1CON0bits.EN = OPAMP_OPACON0_EN_DISABLE;
OPA1CON0bits.CPON = OPAMP_OPACON0_CPON_PUMP_ON;
OPA1CON0bits.UG = OPAMP_OPACON0_UG_DISABLE;
OPA1CON1bits.GSEL = OPAMP_OPACON1_GSEL_15R_1R;
OPA1CON1bits.RESON = OPAMP_OPACON1_RESON_DISABLE;
OPA1CON1bits.NSS = OPAMP_OPACON1_NSS_OPAXIN1M;
OPA1CON2bits.PCH = OPAMP_OPACON2_PCH_PSS;
OPA1CON2bits.NCH = OPAMP_OPACON2_NCH_PSS;
OPA1CON3bits.PSS = OPAMP_OPACON3_PSS_OPAXIN0P;
OPA1CON3bits.INTOE = OPAMP_OPACON3_INTOE_DISABLE;
OPA1CON3bits.FMS = OPAMP_OPACON3_FMS_NC;
OPA1CON4bits.OFCSEL = OPAMP_OPACON4_OFCSEL_FACTORY;
OPA1CON4bits.OFCST = OPAMP_OPACON4_OFCST_NOT_PRGRS;
OPA1CON4bits.PTRES = OPAMP_OPACON4_PTRES_NO_RESET;
OPA1HWCbits.HWCL = OPAMP_OPAHWC_HWCL_BASIC_USER_DEF_FB;
OPA1HWCbits.ORPOL = OPAMP_OPAHWC_ORPOL_NOT_INVERT;
OPA1HWCbits.HWCH = OPAMP_OPAHWC_HWCH_BASIC_USER_DEF_FB;
OPA1HWCbits.OREN = OPAMP_OPAHWC_OREN_DISABLE;
OPA1ORS = OPAMP_OPAORS_ORS_OPAXORPPS;
OPA1OFFSET = 0u;
OPA1CON0bits.EN = OPAMP_OPACON0_EN_ENABLE;
while(1)
{
}
}
結果
R1に10kΩ,R2に20kΩを接続し、出力を計測。入力周波数が100kHz程度では位相の遅れは目立ちません。

入力周波数が1MHzを超えると位相の遅れはが目立ってきました。

設定例3) 非反転増幅/内部可変ゲインモード
非反転増幅/内部可変ゲインモードとは
先ほどの非反転増幅器(利得=1+R₂/R₁)はゲインを動的に変更できない、もしくはアナログスイッチなどで切り替えるといった不便さが有ります。内部ゲインモードは、オペアンプ内部にゲイン抵抗が内蔵され8段階のゲインをソフトウェアから設定可能です。以下のような特徴とメリットがあります。
1.ソフトウェアで瞬時切替
- 外部アナログスイッチやジャンパ変更が不要。
- マイコンからワンコマンドでゲインを変更可能。
2.部品点数の削減
- 外付けの高精度抵抗やスイッチが不要になり、PCBレイアウトがシンプルに。
- 部品コスト・実装工数の低減。
3.高い精度・マッチング
- 内蔵抵抗はチップ内でマッチングが取りやすく、温度特性・ドリフトが小さい。
- 外付け抵抗を複数個そろえるよりも安定したゲイン設定が可能。
4.高速リプログラミング
自動ゲイン制御(AGC)的な使い方がしやすい。
動作中でもゲインを切り替えて、入力振幅に応じた最適利得を選択。
内部ブロック図

ソースコード
INTERRUPT_GlobalInterruptDisable();
Clock_Init();
ANSELAbits.ANSELA1 = 1; //OPA1OUT
ANSELAbits.ANSELA2 = 1; //OPA1IN0+
ANSELAbits.ANSELA4 = 1; //OPA1IN1-
OPA1CON0bits.EN = OPAMP_OPACON0_EN_DISABLE;
OPA1CON0bits.CPON = OPAMP_OPACON0_CPON_PUMP_ON;
OPA1CON0bits.UG = OPAMP_OPACON0_UG_DISABLE;
OPA1CON1bits.GSEL = OPAMP_OPACON1_GSEL_1R_15R;
OPA1CON1bits.RESON = OPAMP_OPACON1_RESON_ENABLE;
OPA1CON1bits.NSS = OPAMP_OPACON1_NSS_VSS;
OPA1CON2bits.PCH = OPAMP_OPACON2_PCH_PSS;
OPA1CON2bits.NCH = OPAMP_OPACON2_NCH_GSEL;
OPA1CON3bits.PSS = OPAMP_OPACON3_PSS_OPAXIN0P;
OPA1CON3bits.INTOE = OPAMP_OPACON3_INTOE_DISABLE;
OPA1CON3bits.FMS = OPAMP_OPACON3_FMS_OUT;
OPA1CON4bits.OFCSEL = OPAMP_OPACON4_OFCSEL_FACTORY;
OPA1CON4bits.OFCST = OPAMP_OPACON4_OFCST_NOT_PRGRS;
OPA1CON4bits.PTRES = OPAMP_OPACON4_PTRES_NO_RESET;
OPA1HWCbits.HWCL = OPAMP_OPAHWC_HWCL_BASIC_USER_DEF_FB;
OPA1HWCbits.ORPOL = OPAMP_OPAHWC_ORPOL_NOT_INVERT;
OPA1HWCbits.HWCH = OPAMP_OPAHWC_HWCH_BASIC_USER_DEF_FB;
OPA1HWCbits.OREN = OPAMP_OPAHWC_OREN_DISABLE;
OPA1ORS = OPAMP_OPAORS_ORS_OPAXORPPS;
OPA1OFFSET = 0u;
OPA1CON0bits.EN = OPAMP_OPACON0_EN_ENABLE;
while(1)
{
}
結果
内蔵ゲインモード16倍で動作確認

設定例4) 反転増幅/外部固定ゲインモード
反転増幅とは
非反転増幅回路は、オペアンプを使ったもっとも基本的な増幅回路の一つで、入力信号を“位相反転せず”に増幅できるのが特徴です。
1.高入力インピーダンス
非反転入力はオペアンプの内部で高インピーダンス設計。前段回路へほとんど負荷をかけません。
2.低出力インピーダンス
強力にドライブできるため、後段への信号伝送が安定します。
3.位相非反転
入力信号と同じ位相で出力されるため、フィードバック設計や多段増幅の安定化に有利。
4.ゲイン調整の容易さ
抵抗値を変えるだけで任意の増幅度(1倍未満も可)が得られ、設計がシンプル。
PICマイコンは単電源で動作するため、負電圧を扱うことができません。そのため、オペアンプの正入力にはオフセットを与える必要があります。
一般的には Vdd/2 を使用しますが、必要に応じて DACn の出力を中心電位として利用することも可能です。
内部ブロック図

設定例5) 反転増幅/内部可変ゲインモード
反転増幅/内部可変ゲインモードとは
先ほどと同様に反転増幅器と内部可変ゲインモードで使用可能です。
内部ブロック図

設定例6) コンパレータモード
コンパレータモードとは
オペアンプは通常、フィードバックをかけて使用します。
フィードバックをかけない使い方をすることで、コンパレータのように動作させることも可能ですが、応答速度が遅いなどの特性から、精度やスピードをあまり求めない用途に限られます。
内部ブロック図

ソースコード
int main(void)
{
INTERRUPT_GlobalInterruptDisable();
Clock_Init();
ANSELAbits.ANSELA1 = 1; //OPA1OUT
ANSELAbits.ANSELA2 = 1; //OPA1IN0+
ANSELAbits.ANSELA4 = 1; //OPA1IN1-
OPA1CON0bits.EN = OPAMP_OPACON0_EN_DISABLE;
OPA1CON0bits.CPON = OPAMP_OPACON0_CPON_PUMP_ON;
OPA1CON0bits.UG = OPAMP_OPACON0_UG_DISABLE;
OPA1CON1bits.GSEL = OPAMP_OPACON1_GSEL_8R_8R;
OPA1CON1bits.RESON = OPAMP_OPACON1_RESON_ENABLE;
OPA1CON1bits.NSS = OPAMP_OPACON1_NSS_VSS;
OPA1CON2bits.PCH = OPAMP_OPACON2_PCH_PSS;
OPA1CON2bits.NCH = OPAMP_OPACON2_NCH_GSEL;
OPA1CON3bits.PSS = OPAMP_OPACON3_PSS_OPAXIN0P;
OPA1CON3bits.INTOE = OPAMP_OPACON3_INTOE_DISABLE;
OPA1CON3bits.FMS = OPAMP_OPACON3_FMS_VDD;
OPA1CON4bits.OFCSEL = OPAMP_OPACON4_OFCSEL_FACTORY;
OPA1CON4bits.OFCST = OPAMP_OPACON4_OFCST_NOT_PRGRS;
OPA1CON4bits.PTRES = OPAMP_OPACON4_PTRES_NO_RESET;
OPA1HWCbits.HWCL = OPAMP_OPAHWC_HWCL_BASIC_USER_DEF_FB;
OPA1HWCbits.ORPOL = OPAMP_OPAHWC_ORPOL_NOT_INVERT;
OPA1HWCbits.HWCH = OPAMP_OPAHWC_HWCH_BASIC_USER_DEF_FB;
OPA1HWCbits.OREN = OPAMP_OPAHWC_OREN_DISABLE;
OPA1ORS = OPAMP_OPAORS_ORS_OPAXORPPS;
OPA1OFFSET = 0u;
OPA1CON0bits.EN = OPAMP_OPACON0_EN_ENABLE;
while(1)
{
}
}
結果
今回は、閾値を2.5Vに設定し、入力信号がこのしきい値を超えるタイミングで出力が切り替わるかを確認しました。その結果、出力の立ち上がり・立ち下がりのいずれも約1μsの遅れが見られましたが、低速な信号の比較用途であれば十分実用的であることが分かりました。

設定例7)オーバーライド機能
オーバーライド機能とは
PIC18F26/46/56Q71 シリーズに搭載されているオペアンプは、出力オーバーライド機能が搭載されている事が大きな特徴です。
この機能は特定のイベントが発生した時に、別の出力に上書きすることが可能です。
たとえば、PWM信号(駆動信号)を計測対象に印加し、その応答を測定するようなアプリケーションを考えてみます。このとき、PWM信号の立ち上がりの瞬間に大きなノイズが発生することがあります。
そのノイズ、いわゆる「髭(ひげ)」にコンパレータが反応してしまい、本来意図しない信号として検出されてしまうことがあります。
このようなケースでは、PWMの立ち上がり部分のみを減衰させ、それ以外の区間ではOPAをユニティゲイン(ゲイン=1)で使用することで、ノイズをうまく抑制できます。結果として、コンパレータが髭に引っかからず、意図した信号だけを正確に取り出すことが可能になります。

動作例
今回の実験では、オペアンプの動作モードを活用し、入力信号に対してユニティゲイン(×1)と2倍ゲイン(×2)を非同期に切り替える構成を試しました。
切り替えには、内蔵クロック源の一つであるLFINT(32kHz)信号を使用しています。この非同期信号により、周期的にゲイン設定が自動で切り替わる動作を実現しています。
この構成により、比較的簡単な制御でゲイン切り替えが可能になるため、例えばセンサの信号レベルに応じた自動利得調整などにも応用が期待できます。

int main(void)
{
INTERRUPT_GlobalInterruptDisable();
Clock_Init();
OSCENbits.LFOEN = 1u;
ANSELAbits.ANSELA1 = 1; //OPA1OUT
ANSELAbits.ANSELA2 = 1; //OPA1IN0+
ANSELAbits.ANSELA4 = 1; //OPA1IN1-
OPA1CON0bits.EN = OPAMP_OPACON0_EN_DISABLE;
OPA1CON0bits.CPON = OPAMP_OPACON0_CPON_PUMP_ON;
OPA1CON0bits.UG = OPAMP_OPACON0_UG_DISABLE;
OPA1CON1bits.GSEL = OPAMP_OPACON1_GSEL_8R_8R;
OPA1CON1bits.RESON = OPAMP_OPACON1_RESON_ENABLE;
OPA1CON1bits.NSS = OPAMP_OPACON1_NSS_VSS;
OPA1CON2bits.PCH = OPAMP_OPACON2_PCH_PSS;
OPA1CON2bits.NCH = OPAMP_OPACON2_NCH_GSEL;
OPA1CON3bits.PSS = OPAMP_OPACON3_PSS_OPAXIN0P;
OPA1CON3bits.INTOE = OPAMP_OPACON3_INTOE_DISABLE;
OPA1CON3bits.FMS = OPAMP_OPACON3_FMS_OUT;
OPA1CON4bits.OFCSEL = OPAMP_OPACON4_OFCSEL_FACTORY;
OPA1CON4bits.OFCST = OPAMP_OPACON4_OFCST_NOT_PRGRS;
OPA1CON4bits.PTRES = OPAMP_OPACON4_PTRES_NO_RESET;
OPA1HWCbits.HWCL = OPAMP_OPAHWC_HWCL_BASIC_UG;
OPA1HWCbits.ORPOL = OPAMP_OPAHWC_ORPOL_NOT_INVERT;
OPA1HWCbits.HWCH = OPAMP_OPAHWC_HWCH_BASIC_USER_DEF_FB;
OPA1HWCbits.OREN = OPAMP_OPAHWC_OREN_ENABLE;
OPA1ORS = OPAMP_OPAORS_ORS_LFINTOSC;
OPA1OFFSET = 0u;
OPA1CON0bits.EN = OPAMP_OPACON0_EN_ENABLE;
while(1)
{
}
結果
狙い通り、LFINT信号に同期してゲインが切り替わっていることをオシロスコープ上で確認できました。

設定例8)ピーク検出、トラフ検出モード
ピーク検出とは
ピーク検出回路(ピークディテクタ回路)とは、入力信号の最大電圧(ピーク値)を検出して保持するためのアナログ回路です。一般的にはオペアンプやダイオードなどで構成されます。
これまでに多くの優れた先人たちによって、さまざまなピーク検出回路が考案されてきました。その中でも、もっともシンプルな構成のものは、オペアンプ、ダイオード、コンデンサの3つの要素から成り立っています。

PIC18F26/46/56Q71シリーズに搭載されているオペアンプには、ピーク(山)やトラフ(谷)を検出する機能があり、これらはオーバライド機能の一部として実装されています。
さらに、ピーク検出やトラフ検出をリセットする機能も備わっており、任意のタイミングや条件でこれらの検出状態をクリアすることが可能です。
このように、外部制御との連携によって柔軟な動作ができるため、非常に便利で応用範囲の広いモジュールとなっています。
ピーク検出動作例
ピーク検出モードでは、出力にコンデンサを接続して動作させます。
データシートなども確認しましたが、ピーク検出モードの内部ロジックは明確には記載されておらず、以下はあくまで推測になります。
オペアンプの出力側にスイッチがあり、ピーク電圧を検出するとスイッチが閉じ、電圧がそれを下回るとスイッチが開放される──そのような動作をしているのではないかと考えられます。
コンデンサの容量は、自己放電や接続する回路のインピーダンス、保持したい時間に応じて調整が必要です。
参考までに、実際の動作波形を以下に示します。

int main(void)
{
INTERRUPT_GlobalInterruptDisable();
Clock_Init();
OSCENbits.LFOEN = 1u;
ANSELAbits.ANSELA1 = 1; //OPA1OUT
ANSELAbits.ANSELA2 = 1; //OPA1IN0+
ANSELAbits.ANSELA4 = 1; //OPA1IN1-
OPA1CON0bits.EN = OPAMP_OPACON0_EN_DISABLE;
OPA1CON0bits.CPON = OPAMP_OPACON0_CPON_PUMP_ON;
OPA1CON0bits.UG = OPAMP_OPACON0_UG_DISABLE;
OPA1CON1bits.GSEL = OPAMP_OPACON1_GSEL_8R_8R;
OPA1CON1bits.RESON = OPAMP_OPACON1_RESON_ENABLE;
OPA1CON1bits.NSS = OPAMP_OPACON1_NSS_VSS;
OPA1CON2bits.PCH = OPAMP_OPACON2_PCH_PSS;
OPA1CON2bits.NCH = OPAMP_OPACON2_NCH_GSEL;
OPA1CON3bits.PSS = OPAMP_OPACON3_PSS_OPAXIN0P;
OPA1CON3bits.INTOE = OPAMP_OPACON3_INTOE_DISABLE;
OPA1CON3bits.FMS = OPAMP_OPACON3_FMS_OUT;
OPA1CON4bits.OFCSEL = OPAMP_OPACON4_OFCSEL_FACTORY;
OPA1CON4bits.OFCST = OPAMP_OPACON4_OFCST_NOT_PRGRS;
OPA1CON4bits.PTRES = OPAMP_OPACON4_PTRES_NO_RESET;
OPA1HWCbits.HWCL = OPAMP_OPAHWC_HWCL_PEAK_UG;
OPA1HWCbits.ORPOL = OPAMP_OPAHWC_ORPOL_NOT_INVERT;
OPA1HWCbits.HWCH = OPAMP_OPAHWC_HWCH_PEAK_UG;
OPA1HWCbits.OREN = OPAMP_OPAHWC_OREN_ENABLE;
OPA1ORS = OPAMP_OPAORS_ORS_LFINTOSC;
OPA1OFFSET = 0u;
OPA1CON0bits.EN = OPAMP_OPACON0_EN_ENABLE;
while(1)
{
}
}







記事についての注意点
本記事は慎重に内容を検討し正確さに努めておりますが、内容に誤りがあったとしても、この記事を参考にして生じた損害等については一切の責任を負いません。記事内容をそのまま無断転載することはお断りいたします。


コメント