MSP432 DAC8555

4チャンネルの16bitDACのDAC8555をMSPから制御 



特徴はバッファを2つもっていて、同時に4つチャンネルを変更することもできる点。

https://www.tij.co.jp/jp/lit/ds/symlink/dac8555.pdf?ts=1623402965967&ref_url=https%253A%252F%252Fwww.tij.co.jp%252Fproduct%252Fjp%252FDAC8555

データシートを見ながら、電源回りにパスコン等をつけて回路を形成。Vrefには、

ISL21080CIH315Z-TK(基準電圧1.5V)を利用し動作確認をしている。

各ピンの機能を簡単に。データシートの要約。すべての動きを試した訳ではない。
IOVDD:ロジック回路の電圧。MSP432の場合は、3.3Vだが、5.0Vのロジックと混在する時には、ここに与える電圧で変更する
RST:LOWの時リセットされて、ゼロかまたは、Vrefの中間の値の出力にする。リセット時にゼロか、中間の値にするのかを選択するのがRSTSEL。中間にしたい場合はHIGHに接続、ゼロにしたい場合はGNDに接続。
ENABLE:読んで字のごとく。動作時にはLOWにする。HIGHだとSPIのコマンドを受け付けない。
LDAC:ソフト的にバッファーの値をアップデートし出力を変更できるが、このピンを使ってハード的にもできる。

【動作】
よくあるDACと同じで最初の8ビットがコントロールビットを送りこんで、続いて16ビットの設定したい値のデータを送信する。

LD1,LD0の組み合わせで、チャンネル1~4までまずはデータを送ってから、同時に電圧出力を変化させる事もできるし、各チャンネルを個別に次々に電圧を変更していく事もできる。このあたりは、データシートに任せて、後者で実装する。この時、LD0=0,LD=1にすることになる。DACSelect1,0は進数でチャンネルを設定するところ。PD0は、パワーモードの選択。DACなので特段苦労することはないかと。

 /* Transmitting data to slave */

 MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P3, GPIO_PIN0);

 MAP_SPI_transmitData(EUSCI_B0_BASE, Datatemp0);

 MAP_SPI_transmitData(EUSCI_B0_BASE, Datatemp1);

 MAP_SPI_transmitData(EUSCI_B0_BASE, Datatemp2);

 MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P3, GPIO_PIN0);

といったようにCSを下げてあげて、順番に送りこむ。


以下テストのソース

(利用するには、OLEDを使うための準備は必要→ここ

動作としては、MSP432LaunchPadの横のスイッチを押すと、設定したい電圧を高くしたり、弱くしたりできて、出力されてくる電圧をADCで読み取ってOLEDに表示するというった内容。ADCは拡張性をもって5チャンネル程読めるようにしているが、コメントアウトして1つしか使っていない。


/* --COPYRIGHT--,BSD

 * Copyright (c) 2017, Texas Instruments Incorporated

 * All rights reserved.

 *

 * Redistribution and use in source and binary forms, with or without

 * modification, are permitted provided that the following conditions

 * are met:

 *

 * *  Redistributions of source code must retain the above copyright

 *    notice, this list of conditions and the following disclaimer.

 *

 * *  Redistributions in binary form must reproduce the above copyright

 *    notice, this list of conditions and the following disclaimer in the

 *    documentation and/or other materials provided with the distribution.

 *

 * *  Neither the name of Texas Instruments Incorporated nor the names of

 *    its contributors may be used to endorse or promote products derived

 *    from this software without specific prior written permission.

 *

 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"

 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,

 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR

 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR

 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,

 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,

 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;

 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,

 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR

 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,

 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

 * --/COPYRIGHT--*/

/******************************************************************************

 * MSP432 Empty Project

 *

 * Description: An empty project that uses DriverLib

 *

 *                MSP432P401

 *             ------------------

 *         /|\|                  |

 *          | |                  |

 *          --|RST

 *            |        SW1 /P1.1 |

*             |        SW2 /P1.4 |

 *             ******SPI*******

 *            |       MOSI P/1.6 |------->

 *            |             P1.7 |MISO

 *      <---  |P1.5 CLK          |

 *            |           CS/P3.0|------->

 *            ******I2C*******

 *            |          SDA/P6.4|------->SSD1306*

 *            |          SCK/P6.5|------->

 *            |                  |

 *            ******ADC14*******

 *            |ch1 P5.5          |

 *

 *              DAC 8555

 *             ------------------

 *            |1 VoutA    LDAC 16|connected to GND.when asynchronous DAC updates is used, triggered timing signal is given.

 *            |2 VoutB  ENABLE 15|Active LOW.

 *            |3 Vref+  RSTSEL 14|Low zero, 1 half of Vref

 *            |4 Vcc       RST 13|Active HIGH. RST is low, all DAC channels reset either to zero-scale (RSTSEL = 0) or midscale (RSTSEL = 1).

 *            |5 Vref-   IOVdd 12|single-supply operation, it can be tied to AVDD.

 *            |6 GND       DIN 11|

 *            |7 VoutC    SCLK 10|

 *            |8 VoutD      CS  9|

 *             ------------------

 * Author: 

*******************************************************************************/

/* DriverLib Includes */

#include <ti/devices/msp432p4xx/driverlib/driverlib.h>

/* Standard Includes */


#include <stdio.h>

#include <stdint.h>

#include <stdlib.h>

#include "ssd1306_lib.h"

char OLED_buffer[32];


static uint16_t resultsBuffer[5];

void DACVset(uint8_t chan, float Vsetadc);


/* SPI Master Configuration Parameter */

const eUSCI_SPI_MasterConfig spiMasterConfig =

{

        EUSCI_B_SPI_CLOCKSOURCE_SMCLK,             // SMCLK Clock Source

        12000000,                                  // SMCLK = DCO = 12000000

        12000000,                                  // SPICLK = 12000000

        EUSCI_B_SPI_MSB_FIRST,                     // MSB First

        EUSCI_B_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT,

        //EUSCI_B_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT,

        //EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_HIGH, // High polarity

        EUSCI_B_SPI_CLOCKPOLARITY_INACTIVITY_LOW, // Low polarity

        EUSCI_SPI_3PIN

        //EUSCI_SPI_4PIN_UCxSTE_ACTIVE_LOW                          // 3Wire SPI Mode

};


//DAC variables

static float Vset=1.0;

void DACVset(uint8_t chan, float Vsetadc);


uint16_t j;

int main(void)

 {

    /* Stop Watchdog  */

    MAP_WDT_A_holdTimer();

    /**************************************************************************/

    /*Switch*/

    /**************************************************************************/

    MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1);

    MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN4);


    /**************************************************************************/

    /*OLED SSD1306 via I2C*/

    /**************************************************************************/

    /* Initialization of SSD1306 OLED*/

    ssd1306Init();

    fillDisplay (0x00);

    //draw6x8Str(0, 3, "Hello", 1,0);

    /**************************************************************************/

    /*ADC*/

    /**************************************************************************/

    /* for digital filter*/

    //static float old_Vadc=0.000;


    /* Setting reference voltage to 2.5  and enabling reference */

       MAP_REF_A_setReferenceVoltage(REF_A_VREF2_5V);

       MAP_REF_A_enableReferenceVoltage();

       /* Initializing ADC (MCLK/1/1) */

       MAP_ADC14_enableModule();

       MAP_ADC14_initModule(ADC_CLOCKSOURCE_MCLK, ADC_PREDIVIDER_1, ADC_DIVIDER_1,0);


       /* Configuring GPIOs for Analog In */

       MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5,

       GPIO_PIN5 | GPIO_PIN4 | GPIO_PIN2 | GPIO_PIN1 | GPIO_PIN0,

       GPIO_TERTIARY_MODULE_FUNCTION);


       /* Configuring ADC Memory (ADC_MEM0 - ADC_MEM7 (A0 - A7)  with no repeat)

         * with internal 2.5v reference */

        MAP_ADC14_configureMultiSequenceMode(ADC_MEM0, ADC_MEM7, false);

        MAP_ADC14_configureConversionMemory(ADC_MEM0,

                ADC_VREFPOS_INTBUF_VREFNEG_VSS,

                ADC_INPUT_A0, false);//5.5

/*        MAP_ADC14_configureConversionMemory(ADC_MEM1,

                ADC_VREFPOS_INTBUF_VREFNEG_VSS,

                ADC_INPUT_A1, false);//5.4

        MAP_ADC14_configureConversionMemory(ADC_MEM3,

                ADC_VREFPOS_INTBUF_VREFNEG_VSS,

                ADC_INPUT_A3, false);//5.2

        MAP_ADC14_configureConversionMemory(ADC_MEM4,

                ADC_VREFPOS_INTBUF_VREFNEG_VSS,

                ADC_INPUT_A4, false);//5.1

        MAP_ADC14_configureConversionMemory(ADC_MEM5,

                ADC_VREFPOS_INTBUF_VREFNEG_VSS,

                ADC_INPUT_A5, false);//5.0*/


        /* Enabling the interrupt when a conversion on channel 7 (end of sequence)

          *  is complete and enabling conversions */

         MAP_ADC14_enableInterrupt(ADC_INT0);


         /* Enabling Interrupts */

         MAP_Interrupt_enableInterrupt(INT_ADC14);

         MAP_Interrupt_enableMaster();


         /* Setting up the sample timer to automatically step through the sequence

          * convert.

          */

         MAP_ADC14_enableSampleTimer(ADC_AUTOMATIC_ITERATION);


         /* the start of the sample */

         MAP_ADC14_enableConversion();



      /**************************************************************************/

      /* SPI setting*/

      /**************************************************************************/

     /* Setting DCO to 12MHz */

    CS_setDCOCenteredFrequency(CS_DCO_FREQUENCY_12);


    /* Selecting P1.5 P1.6 and P1.7 in SPI mode */

    MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,

    GPIO_PIN5 | GPIO_PIN6 | GPIO_PIN7, GPIO_PRIMARY_MODULE_FUNCTION);

    /* Configuring SPI in 3wire master mode */

    MAP_SPI_initMaster(EUSCI_B0_BASE, &spiMasterConfig);


    /* Selecting P3.0 as SPI CS pin */

    MAP_GPIO_setAsOutputPin(GPIO_PORT_P3, GPIO_PIN0);

    MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P3, GPIO_PIN0);


    /* Enable SPI module */

    MAP_SPI_enableModule(EUSCI_B0_BASE);

    /**************************************************************************/

    /* DAC8555 setting*/

    /**************************************************************************/

    DACVset(0, Vset);

    DACVset(1, 0.1);

    DACVset(2, 0.2);

    DACVset(3, 0.3);

    /**************************************************************************/

    /*While Loop*/

    /**************************************************************************/


    float Vadc[5];

    uint16_t i;

    while(1){

        while(MAP_GPIO_getInputPinValue(GPIO_PORT_P1, GPIO_PIN1)==GPIO_INPUT_PIN_LOW){

           if ((Vset >= 0) && (Vset <= 1.4999)) {

                       Vset=Vset+0.0001;

                       sprintf (OLED_buffer, "%6.4f",  Vset);

                       draw6x8Str(0, 1, OLED_buffer, 1,0);

                       DACVset(0, Vset);

                    }

        }

       while(MAP_GPIO_getInputPinValue(GPIO_PORT_P1, GPIO_PIN4)==GPIO_INPUT_PIN_LOW){

           if ((Vset >= 0.0001) && (Vset <= 1.500)) {

                Vset=Vset-0.0001;

                      sprintf (OLED_buffer, "%6.4f",  Vset);

                      draw6x8Str(0, 1, OLED_buffer, 1,0);

                      DACVset(0, Vset);

                      }

       }

        //if (Vset>=1.5){Vset=0.0;}

        DACVset(0, Vset);

        //Vset=Vset+0.01;


         MAP_ADC14_toggleConversionTrigger();

         for (i=0;i<1;++i){

             Vadc[i]=2.5*resultsBuffer[i]/ 16384;

               }

         //digital filtering

         //Vadc[0]=0.8*old_Vadc+0.2*Vadc[0];

         //old_Vadc=Vadc[0];

         sprintf (OLED_buffer, "%6.4f",  Vadc[0]);

         draw6x8Str(0, 0, OLED_buffer, 1,0);

         sprintf (OLED_buffer, "%6.4f",  Vset);

         draw6x8Str(0, 1, OLED_buffer, 1,0);

    }

}


void ADC14_IRQHandler(void){

    uint64_t status;


    status = MAP_ADC14_getEnabledInterruptStatus();

    MAP_ADC14_clearInterruptFlag(status);


    if(status & ADC_INT0)

    {

        MAP_ADC14_getMultiSequenceResult(resultsBuffer);

    }


}


void DACVset(uint8_t chan, float Vsetadc){


 static uint16_t DataInt=0;

 static uint8_t Datatemp0=0;

 static uint8_t Datatemp1=0;

 static uint8_t Datatemp2=0;

 const float Vdacref=1.500;


//Send data to DAC8555 via SPI


  DataInt=(uint16_t)(Vsetadc/Vdacref*65536);

  switch(chan) {

                  case 0: //Channel A

                      Datatemp0 = 0b00010000;

                      break;

                  case 1: //Channel B

                      Datatemp0 = 0b00010010;

                      break;

                  case 2: //Channel C

                      Datatemp0 = 0b00010100;

                      break;

                  case 3: //Channel D

                      Datatemp0 = 0b00010110;

                      break;

                  default:

                      Datatemp0 = 0b00010000;

              }

  //Datatemp0=0b00010000;// control bits

  Datatemp1=DataInt >> 8; //MSB

  Datatemp2=DataInt & 0xFF; //LSB

 /* Transmitting data to slave */

 MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P3, GPIO_PIN0);

 MAP_SPI_transmitData(EUSCI_B0_BASE, Datatemp0);

 MAP_SPI_transmitData(EUSCI_B0_BASE, Datatemp1);

 MAP_SPI_transmitData(EUSCI_B0_BASE, Datatemp2);

 MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P3, GPIO_PIN0);

 sprintf (OLED_buffer, "%x %x %x",  Datatemp0,Datatemp1,Datatemp2);

 draw6x8Str(0, 2, OLED_buffer, 1,0);


}




コメント

このブログの人気の投稿

Attiny85とAQM0802A(LCD)のI2C接続

Attiny85 FuseRest

HS101 STM32の自作お手軽オシロスコープ