ラベル PSoC5LP の投稿を表示しています。 すべての投稿を表示
ラベル PSoC5LP の投稿を表示しています。 すべての投稿を表示

2020年5月8日金曜日

PSoC5LPでDMA転送をする

しばらくぶりです。
世間も世間で大変なことになっておりますが、私も色々と大変なことになってなってきてしまいました。
おし!!PSoCに逃げ込むぞ!!

今回はPSoC5LPでDMA転送をしようと思います。
DMA転送なんじゃいなって言うところに触れる前にペリフェラルへのデータのアクセスについてちょっとおさらい。
 通常のペリフェラルのデータレジスタにアクセスする場合、CPUがペリフェラルのレジスタ番号を使ってデータを取ってきていました。端的に言ってしまえばCPUがレジスタ番号の0x0000番地にあるデータを取得するとかですね。また「ペリフェラル側でデータの用意出来たら、CPUにお知らせしてね。そうしたらCPUがペリフェラルのデータレジスタにアクセスするよ。」っていう割り込み処理(IRQ)を使ったデータレジスタへのアクセスがあります。どちらともペリフェラルからデータを取得する際に「CPUがデータを取得する」という事が発生します。
 「CPUがデータを取得する」というのは時として難しいケースもあります。例えばADCからの連続データを取得したいけど、表示や計算にもCPUパワーを使いたい時。ほかにもありますねSPI通信で大容量のデータをセンサーやモジュールに流し込みたい時等々。こういうケースは結構あります。そこで「CPUを使わないでデータの移し替えが出来ないかしら…。」って登場するのがDMA転送です。

DMA転送についてを触れようと思うと、話が膨らみすぎるのでポイントを絞って進めようと思います。
① DMAコントローラーの行えることについて
② DMAコントローラーが何を手がかりデータを転送しているかについて
③ DMAコントローラーはどのタイミングでデータの転送をするかについて
の3つで考えておくと良いと思います。あえてCPUとペリフェラル間の通信バスについては触れないです。優先順位や通信バスの規格の話になってややこしいので。

① DMAコントローラーの行えることについて
DMAコントローラーの行えることは4つあります。どれもデータを送ったり、受け取ったりすることです。
・メモリー(flashも含め)からペリフェラルにデータを送る。
・ペリフェラルにあるデータをメモリーへ送る。
・メモリーからメモリーへデータを送る(移す)。
・ペリフェラルからペリフェラルへデータを送る。

② DMAコントローラーは何を手がかりにしてデータの転送をしているか
これは3つあるのですがちょっと複雑です。
・ペリフェラルやメモリーに割り当てられているアドレス
・送るデータの総数
・1個当たりのデータ長さ
これらを頼りにDMAコントローラーはデータ転送をします。
これだけだとピンと来ないと思うので簡単に例を挙げようと思います。


ペリフェラル(送り元)からメモリー(送り先)にDMAが転送するとします。
送るデータの総数は32byte、1個当たりのデータは1byteとします。
送り先のメモリーはuint8_tで32byte分の配列になっていてます。(送り先のメモリーは配列じゃないと送れないです。)
DMAコントローラーはペリフェラルのアドレスは分かっているので、ペリフェラルから1個目のデータを取得します。DMAコントローラーは取得したデータをメモリーへ1個目格納します。格納が終わったらまたDMAコントローラーはペリフェラルからデータを取得してメモリーへ格納するわけですがちょっと問題ですね。メモリーのアドレスが分かっている1個目の配列にはもうデータが入っています。そこでDMAコントローラーは転送したデータの個数を数えることで次に格納するメモリーのアドレスを特定することが出来ます。
メモリー側の配列の1番目のアドレスが0x0001であれば、カウンタの値と合わせて2番目は0x0002、3番目のアドレス0x0003というようになります。

③ DMAコントローラーはどのタイミングでデータの取得を行うか
DMAコントローラーにデータの取得を伝えることを「DMA request」といいます。
このDMA requestはデータの送り元がDMAコントローラーに伝えることでDMA転送が開始されます。ペリフェラルでは内部割込みのピンがDMA requestを操作したり、メモリ間での転送はCPUがDMA requestを操作することもあります。
DMAコントローラーへDMA requestを伝えるタイミングはケースバイケースなのです。例を挙げておくと、通信系のペリフェラルで受信時にペリフェラル側のデータが溜まった時にDMA requestを行います。送信時ではペリフェラル側の送るデータが無い時にDMA requestを行います。

ここからは実際にPSoC5LPでDMA転送を行います。
今回はUARTの受信をDMA転送でSRAMに移すことをします。
コンポーネントの接続は次の通りです。


DMA requestは次の通りです。
UARTの場合Level edge設定じゃないとDMA requestがかかりません。


プログラムはFreeRTOSが入った状態で書きました。
現状のコードだとデバッガを当てないと通信テストが出来ないです。

void vGPStask()
{
    uint8_t gpsbuff[32];
   
    /* Defines for DMA_rx */
    #define DMA_rx_BYTES_PER_BURST 1 //1回のデータの長さ(byte単位)
    #define DMA_rx_REQUEST_PER_BURST 1 //request毎に転送
    #define DMA_rx_SRC_BASE (CYDEV_PERIPH_BASE) //転送元
    #define DMA_rx_DST_BASE (CYDEV_SRAM_BASE) //転送先
   
    /* Variable declarations for DMA_rx */
    /* Move these variable declarations to the top of the function */
    uint8 DMA_rx_Chan;
    uint8 DMA_rx_TD[1];
   
    /* DMA Configuration for DMA_rx */
    DMA_rx_Chan = DMA_rx_DmaInitialize(DMA_rx_BYTES_PER_BURST, DMA_rx_REQUEST_PER_BURST,
        HI16(DMA_rx_SRC_BASE), HI16(DMA_rx_DST_BASE));
    DMA_rx_TD[0] = CyDmaTdAllocate();
    CyDmaTdSetConfiguration(DMA_rx_TD[0], 32, DMA_rx_TD[0], CY_DMA_TD_INC_DST_ADR);//DMAのデータのカウントと送る設定
    CyDmaTdSetAddress(DMA_rx_TD[0], LO16((uint32)UART_1_RXDATA_PTR), LO16((uint32)gpsbuff));// 転送元と転送先のアドレス
    CyDmaChSetInitialTd(DMA_rx_Chan, DMA_rx_TD[0]);   
    CyDmaChEnable(DMA_rx_Chan, 1);//DMAの有効化
    UART_1_Start();//UARTの有効化

    for(;;)
    {
        vTaskDelay(250);
    }
}

転送テストを行った結果
tera tarmから文字で「123」と入力しました。
バッファの先頭から1(0x31)、2(0x32)、3(0x33)が入っています。

注意事項
PSoC5LPのDMAは最大で8chまでです。複数のDMAを使う場合はDMA同士の優先順位を決める必要があります。またDMAのカウンタは4095なのでそれを超えるデータの量を取り扱う場合はDMAの設定を組み替える必要があります。DMAと割り込みを組み合わせるケースもあります。DMAのコードジェネレータ(DMA Wizard)の使い方や詳細はアプリケーションマニュアルAN52705 - PSoC® 3 and PSoC 5LP - Getting Started with DMAを読んでください。

2020年1月19日日曜日

PSoC5LPでFreeRTOSを動かす。

今回はPSoC5LPでFreeRTOS V10を動かすことを行った。
以前はCypressのアプリケーションノートの中にFreeRTOSへ適用の仕方が書かれていたと記憶していた。今回調べたところ、アプリケーションノートがそのものがサイト等から消えてしまっていた。FreeRTOSのサイトにはPSoC5LPのサンプルコードがあるため、それをたたき台としてFreeRTOS V10をPSoC5LPへ適用することとした。
 サンプルコードは余計な内容が書かれていた。このままの状態では動作ができないので動作に必要となるコードを取り出して、適用することとした。必須となるスーパーバイザーコールとシスティックの部分はmain.c内に書かれていたので、新しい適用もこれに沿えば大丈夫だと思われる。使い方はスレッドスタートやタスクの登録以前に実行する。
下記はスーパーバイザーコールとシスティックのプログラム部分となる。
extern void xPortPendSVHandler( void );
extern void xPortSysTickHandler( void );
extern void vPortSVCHandler( void );
extern cyisraddress CyRamVectors[];

/* Install the OS Interrupt Handlers. */
CyRamVectors[ 11 ] = ( cyisraddress ) vPortSVCHandler;
CyRamVectors[ 14 ] = ( cyisraddress ) xPortPendSVHandler;
CyRamVectors[ 15 ] = ( cyisraddress ) xPortSysTickHandler;

あとはFreeRTOSでダウンロードしたソースファイルからCortexM3用のFreeRTOSデータをまとめれば、FreeRTOSに必要なデータがそろう。注意が必要な点はportableディレクトリ内のデータとなる。このディレクトリはCPUのコアとコンパイラ毎に異なったシスティックのプログラムとスーパーバイザーコールのプログラムが保存されている。さらにFreeRTOSが使うメモリー管理アルゴリズムのプログラムもここに格納されている。システィックのプログラムとスーパーバイザーコールのプログラムが書かれたファイルは、すべて同じファイル名となっている。つまり、ファイルの操作を間違えるとプログラムが変質することになる。
下記は今回参照したファイルのディレクトリ構造
FrerRTOSv10.2.1
┣FreeRTOS
┃┣Demo(MCUごとに作られたデモプログラムの一式)
┃┣License
┃┗Source(FreeRTOSの本体)
┃ ┣include
┃ ┗portable
┃  ┣MemMang(heap_1 heap_2 heap_3 heap_4 heap_5のいずれかが必要)
┃  ┣GCC
┃  ┃┣ARM_CM3(port.c portmacro.hがある。)
┃  ┃┗そのほかのCPU用ディレクトリ
┃  ┗そのほかのコンパイラ用ディレクトリ
┗FreeRTOS+Plus

下記はFreeRTOSのソースファイルから構成したファイル
freertos
┣inc
┃┗


┣src
┃┗

freeRTOSConfig.h

構成したソースファイルはエクステンディングアイテムを用いてPSoCCreatorに導入した。ビルドはFreeRTOSを入れたのでそれらを参照できるように設定を行った。

動作確認はLEDの点滅を行った。下記はそのプログラムとなる。
#include "project.h"

#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"

void vLEDtask();
xTaskHandle xLEDtask;
uint8_t ucParameterLED;

int main(void)
{
    CyGlobalIntEnable; /* Enable global interrupts. */
    /* Port layer functions that need to be copied into the vector table. */

    extern void xPortPendSVHandler( void );
    extern void xPortSysTickHandler( void );
    extern void vPortSVCHandler( void );
    extern cyisraddress CyRamVectors[];

/* Install the OS Interrupt Handlers. */
CyRamVectors[ 11 ] = ( cyisraddress ) vPortSVCHandler;
CyRamVectors[ 14 ] = ( cyisraddress ) xPortPendSVHandler;
CyRamVectors[ 15 ] = ( cyisraddress ) xPortSysTickHandler;
 
    xTaskCreate(vLEDtask,"ledtask",configMINIMAL_STACK_SIZE,&ucParameterLED,tskIDLE_PRIORITY + 1,&xLEDtask);
 
    /* Place your initialization/startup code here (e.g. MyInst_Start()) */
 
    vTaskStartScheduler();
    for(;;)
    {
        /* Place your application code here. */
    }
}

void vLEDtask()
{

    for(;;)
    {
        Pin_1_Write(1);
        vTaskDelay(250);
        Pin_1_Write(0);
        vTaskDelay(250);
    }
}

void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
{
/* The stack space has been execeeded for a task, considering allocating more. */
taskDISABLE_INTERRUPTS();
for( ;; );
}
/*---------------------------------------------------------------------------*/

void vApplicationMallocFailedHook( void )
{
/* The heap space has been execeeded. */
taskDISABLE_INTERRUPTS();
for( ;; );
}
/*---------------------------------------------------------------------------*/



PSoC5LPはPSoC6で使われているPDLが使われていない。PLDがあるとFreeRTOSの適用が楽なのだが、それらしいオプションも見当たらなかった。PSoC5LPでFreeRTOSの開発を進める場合はこれを参照に進めればよいと思われる。

2016年12月21日水曜日

感雨センサーをつくってみる。

今回はオペアンプとADCを組み合わせて、感雨センサーを作ってみました。
今回のは今までの記事を総合していけば難しい話ではない。

感雨センサーは割とお安く売っているのだけれど、
MEMS、つまりは専用ICになっているというわけじゃ無くて
むき出しの配線に水滴が当たると抵抗値が下がると言う仕組み。
ひずみゲージとかと同じで、
どう考えてもアナログフロントエンドが必要な類のセンサーです。

さて、分圧回路をするか差動増幅みたいな感じなるのかなと考えてチョロット
実験をしてみました。結果から言うと分圧してあげる方がよさそうという事がわかりました。しかし、感雨センサーに水滴を付けたりさせても200KΩ~1MΩぐらいの変化なので分圧回路に使う抵抗は変に小さくすると反応が出ないので「どうしたもんかね?」と言うのが出る訳ですな。

通常のMCUだと「どうしたもんかね…」でおしまいになるのですが、
PSoCなら分圧回路から出力される電圧値をオペアンプで増幅してあげれば
ADCにつなげた時にADCの分解能を最大限使える様になるはずです。
これは今回構成したPSoCの中身です。



分圧回路→オペアンプで1.5倍に増幅→ADCでデジタルに変換
デジタル値はI2CのLCDへ表示する。と言う感じ。
ただし、デジタル値は乾いているとき(抵抗値が大きいとき)は
電圧が大きくなる。なのでそこは気を付けないといけない。



MCUで同じことをするにはオペアンプを買ってきて、
電流制限を付けた電源を作ったりして流れる電流量を調整したり
(しないと配線むき出しのセンサーが熱を持つ可能性がある)
と非常に面倒臭い…。
ま、PSoCだとセンサーの性質を調べる方に時間がかかったけど
割と簡単にできちゃいます。

温度や湿度、気圧などは専用のICとして売られているけれど
今回みたいに物理的な現象を電圧値に変えてセンサーとして使う場合は
アナログフロントエンドを避けて通る事は中々難しい。
また、王道のアナログ回路をするのは部品や機材も多く必要になる。
けどPSoCであれば、途中から部品を買い足す事も少なくなるので
お財布にも優しく、多種多様構成が出来るのでうまく使って
高速に作りたいシステムや作品を作りましょう!!

2016年12月11日日曜日

コンパレータ―をつかってみる。(前回の続き)

前回の記事のつづき。

前回の記事で触れた通りで
コンパレータ―は電圧を比べる機能を持っている。
カンが良い人もいるかも知れないけど、
比べて上回れば出力されるという事は出力が0or1、つまりはONとOFFという事になる。
そう、じつはコンパレータの入力部はアナログだけど、出力されるのはデジタルなんだ。
つまり、コンパレータはアナログとデジタルの境界にある物なんだね。アナログフロントエンドの最後に使われるADCにも、コンパレータが入っている。ただ、コンパレータを沢山つかうと言うケースは中々ないのであまり登場しない。もちろん設計の仕方やリソースが減ってくると使う事もあるので知っていて損はないだろう。

さて、今回はADCを使ってみたときに使った温度センサー(LM61BIZ)と
コンパレータ―で温度の検出をしてみる。このセンサーは0℃の時に600mVを出力して
1℃あたり10mV増減する。
よってこのセンサーは600mA+XmAの電圧値が出力されるという事になる。
目標とする温度の電圧が用意出来れば、センサーの電圧を比較して
センサーの電圧値が上回ればその温度以上ある事が分かる。
つまり、目標の電圧とセンサーの電圧をコンパレータで比較してHIGH(ON)になれば
その温度以上ある事がわかる。

それではやってみよう。
今回は前回と比べてかなり単純。
温度センサーとコンパレータをつなげて、ある温度以上になったら
LEDが光ると言うのをやってみる。

アナログのコンポーネントの中から、コンパレータと
VDACをドラッグアンドドロップしてトップデザインへ入れる。



トップデザインに入れるとこんな感じ。

コンパレータ―のコンポーネントを開いたら、



Speedの項目のラジオボタンをFastに設定をして、Syncの項目のBypassを設定する。


出来たら、OKをクリックして閉じます。
今回はVDACの電圧設定がキーになる。
温度センサーに触れてしばらくしたら、LEDが光るようにしたいので
あまり高い電圧設定ではLEDが光ってくれない。かといって電圧が低くて光りっぱなしでは
テストにならない。と言うことで私の本業の知識から引っ張り出すと、
指の温度は個人差が多少なりともあるが28℃位を超えるかあれば
コンパレータのテストになるだろう。
なので、今回は600+28*10=880mAに設定をすれば良さそうだ。

設定が出来たらOKをクリックして設定を閉じよう。
ここまで出来たらコンポーネント同士を接続しよう。
記事の冒頭で書いた通り、コンパレータ―はアナログとデジタルの堺になる。
つまり、コンパレータは入力側のピンの種類がAnalogPin、
出力側のピンがDigitalPinを接続する事になる。
なので、今回はこのようにつなぐことになる。


これが出来たら使うピンの設定をしよう。
オペアンプの時と比べ、コンパレータ―は内部のリソースに余裕があるので
どのピンでも問題は特にない。しかし、デジタル専用のPort12は使えないので注意が要る。
光らせるLEDのピンは基板についているLEDを使いたいのでP2[1]にしておくと良いだろう。
わたしはこんな感じ。

ここまで出来たら、コンパイルをしよう。
コンパイルをしている間に、センサーとPSoCをつなげよう。

つなげられたらプログラミングをしよう。今回も単純。
コンパレータ―と比較対象のVDACのスタートを書いておしまい。
int main(void)
{
    CyGlobalIntEnable; /* Enable global interrupts. */

    WaveDAC8_1_Start();
    Opamp_1_Start();
    VDAC8_1_Start();

    Comp_1_Start();
    VDAC8_2_Start();

前回のプロジェクトを引き継いでいるのでWaveDAC云々があるが必要なのは2行だけ。
Comp_1_Start();
    VDAC8_2_Start();

ここが書けたら、もう一度コンパイルをしてPSoCへ書き込んでみよう。
書けたら、温度センサーに触れてみよう。
しばらくしたらLEDが光れば成功だ!!
(/・ω・)/

全2回をつかってアナログ回路の始めの方をしてみた。
実際のアナログフロントエンドでもアナログ回路の基本的な使い方を組わせてほしい機能を実現している。
PSoC3,PSoC5LPにはプログラム側から倍率の変更が出来るオペアンプや
電流値として出力されるセンサー等に対してADCが使えるように電流電圧変換アンプもある。
上手に使えば、ワンチップでアナログフロントエンドが出来てしまうでしょう。
また、オペアンプやコンパレーターを工夫して取り入れることで今回のように
CPUを使わないことで並列処理の様なシステムも組める。
なのでプログラミングに自信が無い人もアプローチを変える事も考えてみると良いでしょう。

2016年12月7日水曜日

PSoCでオペアンプとコンパレータを試す(コンパレータ―は別の記事で書くよ)

I2CやキャラクターLCDを含め、割とCPUのパワーを使う事が多かったので
今回は真反対のアナログ系について触れてみようと思う。

さて、以前の記事ではアナログをデジタルに変換をするADCのコンポーネントをつかって温度センサーの値を変換した。しかし、ADC以外にもPSoCには、アナログ回路を直接的に構成する事ができるコンポーネントがある。「高速、高分解能のADCがあればいいのでは?」っと思うかもしれない。けど、ADCへ接続する前に必要な電圧を取り出したり増幅する事が出来れば、ADCをより効果的に使う事ができる。これにはオペアンプを使ったり、コンパレータ―を使う事で取り出したり増幅することが出来る。ADCへつなぐ前の信号に、増幅や加工をすることをアナログフロントエンドとかシグナルコンディショニングと呼ぶ。
PSoC3,PSoC5LP,PSoC4に差はあるもの、オペアンプとコンパレータを内蔵している。
どのファミリーでも最大でオペアンプが4個、コンパレータ―が4個を内蔵している。
特にPSoC3とPSoC5LPにはスイッチキャパシタとオペアンプを合成したSC/CTブロックが4個ある。
これにより外部から抵抗を足すことなく特定のアナログ回路も構成することが出来る。
そのためPSoC3,PSoC5LPはPSoC4よりもアナログ系が得意と言って問題は無いだろう。
 通常のMCUばかりでオペアンプやコンパレータ―になじみが薄い人も多いので
少しオペアンプとコンパレータについて触れよう。
オペアンプとコンパレータは2つとも電圧の状態によって動いている部品になっている。
MCUではCPUがメモリー内にある数値を読みだす事で計算を出力する。
しかしオペアンプやコンパレータ―はメモリーではなく、
電圧同士の計算を行った結果を出力すると考えてもらえばいいだろう。

オペアンプは簡単に2つの機能がある。
 ①電圧を増幅する機能
 ②電圧同士を演算する機能(微積分もできたりする)

コンパレータの機能は1つで
 ①電圧同士を比較する機能

っと簡単にこんな機能がある。
オペアンプやコンパレータ―は単体ではほしい機能を得ることは中々少ない。それは入力部側(+と-の線)の関係性が出力側の結果へ反映される。そのため、抵抗やコンデンサを外付けする必要がある。オペアンプやコンパレータ―の全てを解説するのはなかなか難しいので、電子回路の本等でどういう使い方をするのかを調べて欲しい。
今回はPSoCをつかって簡単にオペアンプとコンパレータ―を使ってみようと思う。
今回はオペアンプを使って、増幅率2倍の反転増幅回路をしてみる。
反転増幅なので、オペアンプに入力した信号がプラスの電圧なら、出力は入力と比べて
マイナスの電圧が出力される。教科書でも出てくる標準的な使い方だ。
けど、PSoCが持っているオペアンプは方電源(+だけ)のため、教科書に出てくるような正負電源(プラスマイナス両方)をつかったオペアンプとは少し違う。
簡単に言うと増幅した信号が0Vより下回ると出力されない。
そのため出力電圧が0Vよりも下回る場合にはちょっとした工夫が要る。

それではやってみよう。
必要なものはPSoC5LP、もしくはPSoC3。100KΩ1個と200KΩ1個。
オシロスコープ(キットのオシロスコープでもかまわない)
今回は電源電圧を5Vで行う方が良い。

空のプロジェクトを用意したら。

アナログコンポーネントから

OpAmpとWaveDACとVDACをトップデザインへドラックアンドドロップする。



WaveDACは周波数発生器の代わりとして使って、
VDACは0Vより下に出力されてしまうのを解決させるのに使う。
トップデザインに並べるとこんな感じ。


先ずは、OpAmpのコンポーネントをダブルクリックして設定をしよう。

今回は実験なのでPowerのプルダウンメニューからHigh Powerを選択して


設定が出来たら、OKボタンをクリックして閉じよう。
その次はVDACをダブルクリックして設定をしよう。

Speedの項目にあるラジオボタンのHigh Speedに設定をして、
Valueの項目のmVの項目を668に設定をする。

出来たら、OKボタンをクリックして閉じよう。
その次はWaveDACをダブルクリックして設定する。

設定はほとんど触らないのですが
Range selectionのプルダウンメニューから
VDAC0 – 1.020V(Buffered)を選ぶ。


それが出来たらOKボタンをクリックして閉じる。
このままだと回路が動かないので、必要な所に結線とAnalog Pinを足して
抵抗をつなげるようにしていく。
WaveDACにはWSのピンにDigtal → LogicのLogic Lowのコンポーネントをつなげてあげて

WaveDACの先にはPort and Pins → Analog Pinのコンポーネントを追加する。

ピンやコンポーネントを反転させたいときはコンポーネントを選択した状態で、
メニューバー近くの反転ボタン(青い囲いの中)をクリックすると反転する。

繋ぎ終わるとWaveDACはこんな感じになる。

VDACはOpAmpの入力側のプラス側につなげる。

OpAmpは入力側のマイナス側にAnalog Pinをつなげる。

使うAnalog Pinは名前を変更しておいた方があとあと楽なので変えておく方が良いでしょう。
ここまで出来たら左側のツリーチェーンからPinをダブルクリックして
使うピンを設定しよう。
どこでもいいと言えばいいけれど、今回はOpAmpを使うのでプルダウンメニューから
OpAmp[*],***と表記されている物の方が内部リソースを無駄に消費しなくて済む。

例えば、オペアンプのマイナスに繋ぐピンにはOpAmp[*],vminusに設定をするような感じで設定してほしい。WaveDACの出力ピンはOpAmp[*],Voutに設定してほしい。
私はあまりギチギチにしなかったので、こんな感じにしました。

ここまで出来たら一度コンパイルしよう。
コンパイルをしている間にPSoCに抵抗を追加して反転増幅回路を構成しよう。
WaveDACとOpAmpのマイナスの間に100KΩをつないで、
OpAmpのマイナスと出力側の間に200KΩをつなぐ。
繋ぐとこんな感じ。

コンパイルが終わったら、プログラムを書いてOpAmpやDACが使えるようにしよう。
プログラムは単純。
int main(void)
{
    CyGlobalIntEnable; /* Enable global interrupts. */

    WaveDAC8_1_Start();
    Opamp_1_Start();
    VDAC8_1_Start();

  
だけ。For文の中身は空っぽでOK
それが終わったら、もう一度コンパイルをしてPSoCに書き込もう。
書き終わったら、WaveDACの出力ピンとオペアンプの出力ピンに
オシロスコープのプローブをつなげてみよう。
(1CHがWaveDAC,2CHがオペアンプの出力)

WaveDACからは0~1Vの電圧で1Khzの正弦波(sin波)が出ていて
OpAmpの出力側からは0~2Vの間でWaveDACとは電圧が反転した波形が2倍で出力されていれば成功!
(/・ω・)/

反転増幅回路は「マイナス」X倍で出力される。そのためどうしても0Vより下の電圧値が出てしまう。
オペアンプのバーチャルショートを利用して0Vより下回っている部分を0Vより上にする事が出来る。

記事が長くなり過ぎたので、ここで中断するよ。
別の記事にコンパレータ―の実験を試してみるよ~。