查看: 1844|回复: 0

[原创] 使用LPC55xx ADC command chain 采样多个通道

[复制链接]

该用户从未签到

7

主题

15

帖子

0

注册会员

Rank: 2

积分
189
最后登录
2022-3-9
发表于 2021-3-4 15:57:36 | 显示全部楼层 |阅读模式
本帖最后由 rongxiangjun 于 2021-3-4 16:07 编辑


LPC55xx的ADC是一种全新的IP,它支持单端模拟信号采样,差分模拟信号采样,采样频率可以达到1MSPS。它支持软件触发和硬件触发,如外部GPIO 端口0 和端口1的引脚都可以触发ADC, 换句话说可以用外部信号触发ADC。 CTimer及SCT模块都可以产生触发信号触发ADC采样, 用这种方法可以保证ADC的等间隔采样。

这是ADC的模拟信号的引脚定义:

PinAssignment.png

ADC触发信号:

triggerSource.png

在SDK example中,我们有ADC采样的例子, 但这个例子是每次采样只能采样一个通道, 基于该例子做了功能扩展,扩展后单次软件触发可以采样多个模拟通道。
就硬件而言,每一个ADC触发源对应一个ADCTrigger Control Register, 总共有16 ADC Trigger ControlRegisters TCTRL[0:15]。 但是LPC55S69总共有13个硬件触发源,所以剩余的3个ADC TriggerControl Registers TCTRL[13:15]只可以用作软件触发。
TCMD.png


就每一个Trigger Control Register 都绑定一个ADC command buffer register, 且只能绑定一个 ADCcommand buffer register。
对于LPC55xx,总共有15个ADC command buffer registers: CMDH[1:15]/CMDL[1:15],其中CMDH[x]/CMDL[x]是一组,两个总共有64位。每一组ADC command buffer register定义了要采样的模拟通道,模拟通道的特性(单端,差分),分辨率,采样时间,采样的平均数,以及要链接的下一个ADC command buffer register。每一个ADC commandbuffer register只能定义了一个模拟通道,如果单次触发要采样多个通道,就要使用ADCcommand buffer register的链接功能,将多个ADC command bufferregister链接起来。

如下图所示,CMDH[1:15]的第24到27是Next Command Select, 用这几位就可以实现级联。
CommandLow.png

CommandH.png


这是一个列子,用户想用软件触发,采样3个通道:CH0A(ADC0_0), CH2A(ADC0_2), CH3A(ADC0_3).


  • ADC 初始化



lpadc_config_t mLpadcConfigStruct;

ADCPinAssignment();

    /* Set clock source for ADC0 */

    CLOCK_SetClkDiv(kCLOCK_DivAdcAsyncClk, 16U, true);

    CLOCK_AttachClk(kMAIN_CLK_to_ADC_CLK);

    /* Disable LDOGPADC power down */

    POWER_DisablePD(kPDRUNCFG_PD_LDOGPADC);

    LPADC_GetDefaultConfig(&mLpadcConfigStruct);

    mLpadcConfigStruct.enableAnalogPreliminary = true;

    #if defined(DEMO_LPADC_VREF_SOURCE)

    mLpadcConfigStruct.referenceVoltageSource = DEMO_LPADC_VREF_SOURCE;

#endif /* DEMO_LPADC_VREF_SOURCE */

#ifdefined(FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS) &&FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS

    mLpadcConfigStruct.conversionAverageMode = kLPADC_ConversionAverage128;

#endif /*FSL_FEATURE_LPADC_HAS_CTRL_CAL_AVGS */

    mLpadcConfigStruct.FIFO0Watermark=2;

    LPADC_Init(DEMO_LPADC_BASE, &mLpadcConfigStruct);



  • ADC 触发源配置



SDK为Trigger ControlRegister定义如下的结构:

typedef struct

{

    uint32_t targetCommandId; /*!< Select the command from commandbuffer to execute upon detect of the associated

                                   triggerevent. */

    uint32_t delayPower;      /*!< Select the trigger delay duration to wait at thestart of servicing a trigger event.

                                   When thisfield is clear, then no delay is incurred. When this field is set to a non-zero

                                   value, theduration for the delay is 2^delayPower ADCK cycles. The available value range

                                   is 4-bit. */

    uint32_t priority; /*!< Sets the priority of the associatedtrigger source. If two or more triggers have the same

                            priority levelsetting, the lower order trigger event has the higher priority. The lower

                            value for thisfield is for the higher priority, the available value range is 1-bit. */

#if(defined(FSL_FEATURE_LPADC_FIFO_COUNT) && (FSL_FEATURE_LPADC_FIFO_COUNT== 2))

    uint8_t channelAFIFOSelect; /* SAR Result Destination For Channel A. */

    uint8_t channelBFIFOSelect; /* SAR Result Destination For Channel B. */

#endif                          /* FSL_FEATURE_LPADC_FIFO_COUNT */

    bool enableHardwareTrigger; /*!< Enable hardware trigger source toinitiate conversion on the rising edge of the

                                     inputtrigger source or not. THe software trigger is always available. */

} lpadc_conv_trigger_config_t;


用户可以声明一个以此结构的变量,然后初始化此变量,且用下列代码初始化相应的TriggerControl Register。

lpadc_conv_trigger_config_t mLpadcTriggerConfigStruct;


/*Set trigger configuration. */

   LPADC_GetDefaultConvTriggerConfig(&mLpadcTriggerConfigStruct);

    mLpadcTriggerConfigStruct.targetCommandId       = DEMO_LPADC_USER_CMDID1; /* CMD15 is executed. */

    mLpadcTriggerConfigStruct.enableHardwareTrigger = false;

   LPADC_SetConvTriggerConfig(DEMO_LPADC_BASE,0U, &mLpadcTriggerConfigStruct);/* Configuratethe trigger0. */


在以上的代码中, 初始化了ADC Trigger Control Registers0寄存器

  • ADCcommand buffer 配置


下面的代码就是介绍基于SDK的函数,如何使用Command buffer的链接功能。首先定义一个结构和基于此结构的3个变量。

typedef struct

{

#ifdefined(FSL_FEATURE_LPADC_HAS_CMDL_CSCALE) &&FSL_FEATURE_LPADC_HAS_CMDL_CSCALE

    lpadc_sample_scale_mode_tsampleScaleMode;     /*!<Sample scale mode. */

#endif                                             /*FSL_FEATURE_LPADC_HAS_CMDL_CSCALE */

    lpadc_sample_channel_mode_t sampleChannelMode; /*!< Channel samplemode. */

    uint32_t channelNumber;                        /*!< Channel number, select the channelor channel pair. */

    uint32_t chainedNextCommandNumber; /*!< Selects the next command to beexecuted after this command completes.

                                            1-15 is available, 0 is to terminatethe chain after this command. */

    bool enableAutoChannelIncrement;  /*!< Loopwith increment: when disabled, the "loopCount" field selects thenumber

                                            oftimes the selected channel is converted consecutively; when enabled, the

                                           "loopCount" field defines how many consecutive channels areconverted as part

                                            of the commandexecution. */

    uint32_t loopCount; /*!< Selects how many times this commandexecutes before finish and transition to the next

                             command or Idlestate. Command executes LOOP+1 times. 0-15 is available. */

    lpadc_hardware_average_mode_t hardwareAverageMode; /*!< Hardware average selection. */

    lpadc_sample_time_mode_t sampleTimeMode;           /*!< Sample time selection. */


    lpadc_hardware_compare_mode_t hardwareCompareMode; /*!< Hardware compare selection. */

    uint32_t hardwareCompareValueHigh; /*!< Compare Value High. The availablevalue range is in 16-bit. */

    uint32_t hardwareCompareValueLow; /*!<Compare Value Low. The available value range is in 16-bit. */

#if defined(FSL_FEATURE_LPADC_HAS_CMDL_MODE)&& FSL_FEATURE_LPADC_HAS_CMDL_MODE

    lpadc_conversion_resolution_mode_t conversionResolutionMode; /*!< Conversion resolution mode. */

#endif                                                          /* FSL_FEATURE_LPADC_HAS_CMDL_MODE*/

#ifdefined(FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG) &&FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG

    bool enableWaitTrigger; /*!< Wait for trigger assertion before execution: whendisabled, this command will be

                                 automatically executed; whenenabled, the active trigger must be asserted again before

                                 executing thiscommand. */

#endif                      /* FSL_FEATURE_LPADC_HAS_CMDH_WAIT_TRIG */

} lpadc_conv_command_config_t;



lpadc_conv_command_config_tmLpadcCommandConfigStruct0,mLpadcCommandConfigStruct1,mLpadcCommandConfigStruct2;


LPADC_GetDefaultConvCommandConfig(&mLpadcCommandConfigStruct0);

   mLpadcCommandConfigStruct0.channelNumber = DEMO_LPADC_USER_CHANNEL; //adc channel0

   mLpadcCommandConfigStruct0.chainedNextCommandNumber=DEMO_LPADC_USER_CMDID2;

   LPADC_SetConvCommandConfig(DEMO_LPADC_BASE, DEMO_LPADC_USER_CMDID1,&mLpadcCommandConfigStruct0);


    ///////////////Rong addedanother adc channel

   LPADC_GetDefaultConvCommandConfig(&mLpadcCommandConfigStruct1);

    mLpadcCommandConfigStruct1.channelNumber = DEMO_LPADC_USER_CHANNEL+1;  //DEMO_LPADC_USER_CHANNEL+1=1, adc channel1

    mLpadcCommandConfigStruct1.chainedNextCommandNumber=DEMO_LPADC_USER_CMDID3;

    LPADC_SetConvCommandConfig(DEMO_LPADC_BASE,DEMO_LPADC_USER_CMDID2, &mLpadcCommandConfigStruct1);


   LPADC_GetDefaultConvCommandConfig(&mLpadcCommandConfigStruct2);

    mLpadcCommandConfigStruct2.channelNumber = DEMO_LPADC_USER_CHANNEL+2;  //DEMO_LPADC_USER_CHANNEL+1=1, adc channel1

    mLpadcCommandConfigStruct2.chainedNextCommandNumber=0;

    LPADC_SetConvCommandConfig(DEMO_LPADC_BASE,DEMO_LPADC_USER_CMDID3, &mLpadcCommandConfigStruct2);


注意最后一个Command Buffer的链接 Command Buffer必须手机0, 0被认为是一个无效的Command Buffer.

mLpadcCommandConfigStruct2.chainedNextCommandNumber=0;


  • 软件触发ADC


LPADC_DoSoftwareTrigger(DEMO_LPADC_BASE, 1U); /* 1U is trigger0 mask.*/


在初始化的代码中使用了ADC Trigger Control Registers0 寄存器,故用以上代码触发 ADC Trigger Control Registers0 寄存器来启动ADC转换。


  • 用中断模式读取多通道ADC采样值


void DEMO_LPADC_IRQ_HANDLER_FUNC(void)

{

   static uint32_t index=0;

g_LpadcInterruptCounter++;

   {

        g_LpadcConversionCompletedFlag = true;

        LPADC_GetConvResult(DEMO_LPADC_BASE,&g_LpadcResultConfigStruct, 0U);

       resultArray[index][0]=g_LpadcResultConfigStruct;

        LPADC_GetConvResult(DEMO_LPADC_BASE,&g_LpadcResultConfigStruct, 0U);

        resultArray[index][1]=g_LpadcResultConfigStruct;

        LPADC_GetConvResult(DEMO_LPADC_BASE,&g_LpadcResultConfigStruct, 0U);

       resultArray[index][2]=g_LpadcResultConfigStruct;

        index++;

        if(index>=NUMBEROFSAMPLE)

        {

         __asm("nop"); //set breakpoint here

         index=0;

        }

   }

  • 采样结果

sampleResult.png

conclusion.png


回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /4 下一条

Archiver|手机版|小黑屋|恩智浦技术社区

GMT+8, 2024-4-24 21:05 , Processed in 0.110726 second(s), 20 queries , MemCache On.

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

快速回复 返回顶部 返回列表