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