miércoles, 6 de julio de 2016

PDB_ADC_DAC UTILIZANDO FRDMK64 Y SDK 2.0

PDB_ADC_DAC

OBJETIVO

Elaborar un programa que convierta un valor de digital a analógico (DAC) y del analógico al digital (ADC).

DESCRIPCIÓN DEL PROGRAMA
El programa que pide un valor entrada al usuario de entre 0 y 4095 para hacer la conversión de digital a analógico (DAC), posteriormente tomará este valor y con el ADC volverá a regresar de analógico al digital, además se muestra un segundero de muestreo y un contador cada que ocurre una conversión por parte del ADC.

Se podrá observar pequeñas variaciones en el valor de una conversión a otra.


Diagrama:

Código:


#include "fsl_debug_console.h"
#include "board.h"
#include "fsl_pdb.h"
#include "fsl_adc16.h"

#include "fsl_dac.h"

#include "pin_mux.h"
#include "clock_config.h"
/*******************************************************************************
 * Definitions
 ******************************************************************************/
#define DEMO_PDB_BASE PDB0
#define DEMO_PDB_IRQ_ID PDB0_IRQn


#define DEMO_PDB_ADC_TRIGGER_CHANNEL 0U    /* For ADC0. */
#define DEMO_PDB_ADC_PRETRIGGER_CHANNEL 0U /* For ADC0_SC1[0]. */

#define DEMO_ADC_BASE ADC0
#define DEMO_ADC_CHANNEL_GROUP 0U
#define DEMO_ADC_USER_CHANNEL 0U
#define DEMO_ADC_IRQ_ID ADC0_IRQn
#define DEMO_ADC_IRQ_HANDLER ADC0_IRQHandler
#define DEMO_DAC_INSTANCE DAC0
/*******************************************************************************
 * Prototypes
 ******************************************************************************/
/*!
 * @brief Initialize the ADC16
 */
static void DEMO_InitPDB_ADC(void);

/*******************************************************************************
 * Variables
 ******************************************************************************/
//volatile uint32_t g_PdbDelayInterruptCounter;
//volatile bool g_PdbDelayInterruptFlag;
volatile uint32_t g_AdcInterruptCounter;
volatile bool g_AdcInterruptFlag;
volatile uint32_t g_AdcConvValue;
uint32_t Bus_Clk;
uint32_t Modulo_PDB;
uint32_t  Sec_Fm;

/*******************************************************************************
 * Code
 ******************************************************************************/

void static DEMO_InitPDB_ADC(void)
{
    adc16_config_t adc16ConfigStruct;
    adc16_channel_config_t adc16ChannelConfigStruct;
    /*
     * adc16ConfigStruct.referenceVoltageSource = kADC16_ReferenceVoltageSourceVref;
     * adc16ConfigStruct.clockSource = kADC16_ClockSourceAsynchronousClock;
     * adc16ConfigStruct.enableAsynchronousClock = true;
     * adc16ConfigStruct.clockDivider = kADC16_ClockDivider8;
     * adc16ConfigStruct.resolution = kADC16_ResolutionSE12Bit;
     * adc16ConfigStruct.longSampleMode = kADC16_LongSampleDisabled;
     * adc16ConfigStruct.enableHighSpeed = false;
     * adc16ConfigStruct.enableLowPower = false;
     * adc16ConfigStruct.enableContinuousConversion = false;
     */
    ADC16_GetDefaultConfig(&adc16ConfigStruct);
    ADC16_Init(DEMO_ADC_BASE, &adc16ConfigStruct);
#if defined(FSL_FEATURE_ADC16_HAS_CALIBRATION) && FSL_FEATURE_ADC16_HAS_CALIBRATION
    ADC16_EnableHardwareTrigger(DEMO_ADC_BASE, false);
    ADC16_DoAutoCalibration(DEMO_ADC_BASE);
#endif /* FSL_FEATURE_ADC16_HAS_CALIBRATION */
    ADC16_EnableHardwareTrigger(DEMO_ADC_BASE, true);

    adc16ChannelConfigStruct.channelNumber = DEMO_ADC_USER_CHANNEL;
    adc16ChannelConfigStruct.enableInterruptOnConversionCompleted = true; /* Enable the interrupt. */
#if defined(FSL_FEATURE_ADC16_HAS_DIFF_MODE) && FSL_FEATURE_ADC16_HAS_DIFF_MODE
    adc16ChannelConfigStruct.enableDifferentialConversion = false;
#endif /* FSL_FEATURE_ADC16_HAS_DIFF_MODE */
    ADC16_SetChannelConfig(DEMO_ADC_BASE, DEMO_ADC_CHANNEL_GROUP, &adc16ChannelConfigStruct);

}
void Init_DAC(void)
{
dac_config_t dacConfigStruct;

       DAC_GetDefaultConfig(&dacConfigStruct);
       DAC_Init(DEMO_DAC_INSTANCE, &dacConfigStruct);
       DAC_SetBufferReadPointer(DEMO_DAC_INSTANCE, 0U);
}
void Init_PDB(void)
{
pdb_config_t pdbConfigStruct;
   pdb_adc_pretrigger_config_t pdbAdcPreTriggerConfigStruct;

/* Configure the PDB counter. */
   /*
    * pdbConfigStruct.loadValueMode = kPDB_LoadValueImmediately;
    * pdbConfigStruct.prescalerDivider = kPDB_PrescalerDivider1;
    * pdbConfigStruct.dividerMultiplicationFactor = kPDB_DividerMultiplicationFactor1;
    * pdbConfigStruct.triggerInputSource = kPDB_TriggerSoftware;
    * pdbConfigStruct.enableContinuousMode = false;
    */
   PDB_GetDefaultConfig(&pdbConfigStruct);
   pdbConfigStruct.prescalerDivider = kPDB_PrescalerDivider128;
   pdbConfigStruct.dividerMultiplicationFactor = kPDB_DividerMultiplicationFactor40;
   pdbConfigStruct.enableContinuousMode=true;
   PDB_Init(DEMO_PDB_BASE, &pdbConfigStruct);

   Bus_Clk = CLOCK_GetFreq(kCLOCK_BusClk);
     Modulo_PDB = 1*(1969<<pdbConfigStruct.prescalerDivider)*40;
     Modulo_PDB = Bus_Clk/Modulo_PDB;

   /* Configure the delay interrupt. */
   PDB_SetModulusValue(DEMO_PDB_BASE, Modulo_PDB);

   /* The available delay value is less than or equal to the modulus value. */
   PDB_SetCounterDelayValue(DEMO_PDB_BASE, Modulo_PDB/2);
   //PDB_EnableInterrupts(DEMO_PDB_BASE, kPDB_DelayInterruptEnable);

   /* Configure the ADC Pre-Trigger. */
   pdbAdcPreTriggerConfigStruct.enablePreTriggerMask = 1U << DEMO_PDB_ADC_PRETRIGGER_CHANNEL;
   pdbAdcPreTriggerConfigStruct.enableOutputMask = 1U << DEMO_PDB_ADC_PRETRIGGER_CHANNEL;
   pdbAdcPreTriggerConfigStruct.enableBackToBackOperationMask = 0U;
   PDB_SetADCPreTriggerConfig(DEMO_PDB_BASE, DEMO_PDB_ADC_TRIGGER_CHANNEL, &pdbAdcPreTriggerConfigStruct);
   PDB_SetADCPreTriggerDelayValue(DEMO_PDB_BASE, DEMO_PDB_ADC_TRIGGER_CHANNEL, DEMO_PDB_ADC_PRETRIGGER_CHANNEL, Modulo_PDB/2); //200U
   /* The available Pre-Trigger delay value is less than or equal to the modulus value. */

   PDB_DoLoadValues(DEMO_PDB_BASE);
}
/*!

 * @brief ISR for ADC16 interrupt function
 */
void DEMO_ADC_IRQ_HANDLER(void)
{
    /* Read to clear COCO flag. */
static  int i=0;
    g_AdcConvValue = ADC16_GetChannelConversionValue(DEMO_ADC_BASE, DEMO_ADC_CHANNEL_GROUP);
    g_AdcInterruptCounter++;
    g_AdcInterruptFlag = true;
    i++;
    i%=1920;
    if(i==0)
    {
    Sec_Fm++;
    }
    }


/*!
 * @brief Main function
 */
int main(void)
{
uint32_t dacValue;
    BOARD_InitPins();
    BOARD_BootClockRUN();
    BOARD_InitDebugConsole();
    EnableIRQ(DEMO_PDB_IRQ_ID);
    EnableIRQ(DEMO_ADC_IRQ_ID);

    PRINTF("\r\nPDB ADC16 Pre-Trigger Example.\r\n") ;
    Init_PDB();

        /* Configure the ADC. */
    DEMO_InitPDB_ADC();
    Init_DAC();

    g_AdcInterruptCounter = 0U;

    PRINTF("\r\nType any key into terminal to trigger the PDB and then trigger the ADC's conversion ...\r\n");
    PDB_DoSoftwareTrigger(DEMO_PDB_BASE);
    while (1)
    {

    PRINTF("\r\nPlease input a value (0 - 4095) to output with DAC: ");
           SCANF("%d", &dacValue);
           PRINTF("\r\nInput value is %d\r\n", dacValue);
           if (dacValue > 0xFFFU)
           {
               PRINTF("Your value is output of range.\r\n");
               continue;
           }
           DAC_SetBufferValue(DEMO_DAC_INSTANCE, 0U, dacValue);
           PRINTF("DAC out: %d\r\n", dacValue);
           /*
           * The value in the first item would be converted. User can measure the output voltage from DAC_OUTx pin.
           */

        g_AdcInterruptFlag = false;

        while (!g_AdcInterruptFlag)
        {
        }
        PRINTF("\r\n");
        PRINTF("Sec_Fm: %d\r\n", Sec_Fm);
        PRINTF("ADC Conversion Interrupt Counter: %d\r\n", g_AdcInterruptCounter);
        PRINTF("ADC Conversion Value: %d\r\n", g_AdcConvValue);
    }
}

A continuación se muestra operación del programa.



No hay comentarios:

Publicar un comentario