查看: 884|回复: 2

[分享] LPC55xx:ARM tx event触发ADC你了解吗?

[复制链接]

该用户从未签到

656

主题

6312

帖子

0

超级版主

Rank: 8Rank: 8

积分
19947
最后登录
2024-4-19
发表于 2023-6-1 14:44:30 | 显示全部楼层 |阅读模式
本帖最后由 小恩GG 于 2023-6-1 14:48 编辑

LPC55xx:ARM tx event触发ADC你了解吗?
一、简介
      本文讨论了基于LPC55S69-EVK板、mcxpresso IDE和SDK下的ARMtx event触发ADC的方法。ARM tx event是ADC的触发源之一,虽然是硬件触发,但是其机制与软件触发相同,经过ADC配置后,执行指令asm(“SEV”),将生成ARM tx event并触发ADC进行采样。
      LPC55xx的ADC支持硬件触发模式,每个硬件触发源对应一个触发寄存器,如表1所示,ARM tx event ADC触发源索引为11,因此必须初始化ADC触发控制寄存器TCTRL11。在TCTRL11寄存器中,可以分配命令ID,选择FIFO0或FIFO1去保存ADC结果,使能硬件触发。
    图片1.png
表1
二、"SEV "指令
      在执行指令asm(" SEV ")之后,ADC触发源11将产生事件触发ADC。"SEV "是一种提示指令,内核执行这条指令asm(“SEV”)后,会产生一个event给外设或其他内核(多内核处理器)以便触发外设或唤醒其他内核。手册user guide of ARM_Cortex_M33.pdf中" SEV "说明如图1所示:
图片2.png
图 1
三、ARM tx event触发ADC设置
          在基于LPC55S69-EVK板SDK包中的lpadc_interrupt项目,修改了项目程序中的两个位置,实现ARM tx event触发ADC。
       1)原始代码初始化了TCTRL0寄存器,因为它采用了软件触发方式,所以任何TCTRLx寄存器都可以使用。但是对于ARM tx event,必须使用TCTRL11寄存器并启用硬件触发模式。
         mLpadcTriggerConfigStruct.enableHardwareTrigger =true;
         LPADC_SetConvTriggerConfig(DEMO_LPADC_BASE,11U,&mLpadcTriggerConfigStruct);/*配置触发器* /
        2)每次采样执行asm(“SEV”)指令,指令完成后ADC进行转换,转换完成后执行ADC ISR(中断服务程序),g_lpadcconveroncompletedflag将会被设置
在例程中执行asm(“SEV”)指令代码如下:
while (1)
{
       GETCHAR();
        //LPADC_DoSoftwareTrigger(DEMO_LPADC_BASE, 1U);/* 1U is trigger0 mask. */
        asm("SEV");
       while (!g_LpadcConversionCompletedFlag)
       {
       }
       PRINTF("ADCvalue: %d\r\nADC interrupt count: %d\r\n",
       ((g_LpadcResultConfigStruct.convValue) >> g_LpadcResultShift), g_LpadcInterruptCounter);
       g_LpadcConversionCompletedFlag = false;
}
四、修改后的ADC代码
int main(void)
{
    lpadc_config_t mLpadcConfigStruct;
    lpadc_conv_trigger_config_t mLpadcTriggerConfigStruct;
    lpadc_conv_command_config_tmLpadcCommandConfigStruct;
   /* set BODVBAT level to 1.65V */
   POWER_SetBodVbatLevel(kPOWER_BodVbatLevel1650mv, kPOWER_BodHystLevel50mv, false);
    /* attach main clock divide toFLEXCOMM0 (debug console) */
   CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);
   BOARD_InitBootPins();
   BOARD_InitBootClocks();
   BOARD_InitDebugConsole();
    /* Set clock source for ADC0 */
   CLOCK_SetClkDiv(kCLOCK_DivAdcAsyncClk, 8U, true);
   CLOCK_AttachClk(kMAIN_CLK_to_ADC_CLK);
    /* Disable LDOGPADC power down */
   POWER_DisablePD(kPDRUNCFG_PD_LDOGPADC);
   ANACTRL_Init(ANACTRL);
   ANACTRL_EnableVref1V(ANACTRL, true);
   PRINTF("LPADCInterrupt Example\r\n");
   LPADC_GetDefaultConfig(&mLpadcConfigStruct);
   mLpadcConfigStruct.enableAnalogPreliminary = true;
#if defined(DEMO_LPADC_VREF_SOURCE)
   mLpadcConfigStruct.referenceVoltageSource = DEMO_LPADC_VREF_SOURCE;
#endif /* DEMO_LPADC_VREF_SOURCE */
#if defined(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 */
   LPADC_Init(DEMO_LPADC_BASE, &mLpadcConfigStruct);
#if defined(FSL_FEATURE_LPADC_HAS_CTRL_CALOFS)&& FSL_FEATURE_LPADC_HAS_CTRL_CALOFS
#if defined(FSL_FEATURE_LPADC_HAS_OFSTRIM)&& FSL_FEATURE_LPADC_HAS_OFSTRIM
/* Request offset calibration. */
#ifdefined(DEMO_LPADC_DO_OFFSET_CALIBRATION) && DEMO_LPADC_DO_OFFSET_CALIBRATION
    LPADC_DoOffsetCalibration(DEMO_LPADC_BASE);
#else
   LPADC_SetOffsetValue(DEMO_LPADC_BASE, DEMO_LPADC_OFFSET_VALUE_A,DEMO_LPADC_OFFSET_VALUE_B);
#endif /* DEMO_LPADC_DO_OFFSET_CALIBRATION */
#endif /* FSL_FEATURE_LPADC_HAS_OFSTRIM */
    /* Request gain calibration. */
   LPADC_DoAutoCalibration(DEMO_LPADC_BASE);
#endif /* FSL_FEATURE_LPADC_HAS_CTRL_CALOFS */
#if(defined(FSL_FEATURE_LPADC_HAS_CFG_CALOFS) &&FSL_FEATURE_LPADC_HAS_CFG_CALOFS)
    /* Do auto calibration. */
    LPADC_DoAutoCalibration(DEMO_LPADC_BASE);
#endif /*FSL_FEATURE_LPADC_HAS_CFG_CALOFS */
    /* Set conversion CMDconfiguration. */
   LPADC_GetDefaultConvCommandConfig(&mLpadcCommandConfigStruct);
   mLpadcCommandConfigStruct.channelNumber =DEMO_LPADC_USER_CHANNEL;
#ifdefined(DEMO_LPADC_USE_HIGH_RESOLUTION) &&DEMO_LPADC_USE_HIGH_RESOLUTION
   mLpadcCommandConfigStruct.conversionResolutionMode =kLPADC_ConversionResolutionHigh;
#endif /*DEMO_LPADC_USE_HIGH_RESOLUTION */
   LPADC_SetConvCommandConfig(DEMO_LPADC_BASE, DEMO_LPADC_USER_CMDID,&mLpadcCommandConfigStruct);
    /* Set trigger configuration. */
   LPADC_GetDefaultConvTriggerConfig(&mLpadcTriggerConfigStruct);
   mLpadcTriggerConfigStruct.targetCommandId       = DEMO_LPADC_USER_CMDID; /* CMD15 is executed. */
    mLpadcTriggerConfigStruct.enableHardwareTrigger= true;
   LPADC_SetConvTriggerConfig(DEMO_LPADC_BASE, 11U,&mLpadcTriggerConfigStruct); /* Configurate the trigger0. */
/* Enable the watermark interrupt.*/
#if (defined(FSL_FEATURE_LPADC_FIFO_COUNT)&& (FSL_FEATURE_LPADC_FIFO_COUNT == 2U))
   LPADC_EnableInterrupts(DEMO_LPADC_BASE, kLPADC_FIFO0WatermarkInterruptEnable);
#else
    LPADC_EnableInterrupts(DEMO_LPADC_BASE,kLPADC_FIFOWatermarkInterruptEnable);
#endif /*FSL_FEATURE_LPADC_FIFO_COUNT */
   EnableIRQ(DEMO_LPADC_IRQn);
   PRINTF("ADCFull Range: %d\r\n", g_LpadcFullRange);
#ifdefined(FSL_FEATURE_LPADC_HAS_CMDL_CSCALE) &&FSL_FEATURE_LPADC_HAS_CMDL_CSCALE
    if(kLPADC_SampleFullScale == mLpadcCommandConfigStruct.sampleScaleMode)
    {
        PRINTF("Full channel scale(Factor of 1).\r\n");
    }
    else if(kLPADC_SamplePartScale == mLpadcCommandConfigStruct.sampleScaleMode)
    {
        PRINTF("Divided inputvoltage signal. (Factor of 30/64).\r\n");
    }
#endif
    /* When the number of datawordsstored in the ADC Result FIFO is greater
    * than watermark value(0U), LPADC watermark interruptwould be triggered.
    */
   PRINTF("Pleasepress any key to get user channel's ADC value.\r\n");
    while (1)
    {
       GETCHAR();
       //LPADC_DoSoftwareTrigger(DEMO_LPADC_BASE,1U); /* 1U is trigger0 mask. */
        asm("SEV");
       while (!g_LpadcConversionCompletedFlag)
       {
       }
       PRINTF("ADCvalue: %d\r\nADC interrupt count: %d\r\n",
               ((g_LpadcResultConfigStruct.convValue) >> g_LpadcResultShift),g_LpadcInterruptCounter);
       g_LpadcConversionCompletedFlag = false;
    }

}
五、ARM txevent 触发ADC程序测试结果
        5.1 找到开发板ADC通道引脚
图片3.png
图片4.png
          lpadc_interrupt例程中选择了ADC0_0通道,PORT0 PIN23引脚设置为了ADC0_0通道引脚。
      5.2 通过串口输出ADC采样结果
         每次单击PC上的任何按钮,ADC将经行一转换。

         当PORT0 PIN23引脚接地时,单击PC上的任何按钮,串口输出ADC值ADC value=1。
         当PORT0PIN23引脚接3.3V时,单击PC上的任何按钮,串口输出ADC值ADC value=4095。
图片5.png


回复

使用道具 举报

  • TA的每日心情
    慵懒
    2024-2-21 10:06
  • 签到天数: 310 天

    [LV.8]以坛为家I

    2

    主题

    5670

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    11646
    最后登录
    2024-2-21
    发表于 2023-9-30 07:54:04 | 显示全部楼层
    0930活动打卡
    0930.png
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    昨天 11:26
  • 签到天数: 1274 天

    [LV.10]以坛为家III

    21

    主题

    1万

    帖子

    1

    金牌会员

    Rank: 6Rank: 6

    积分
    13214
    最后登录
    2024-4-19
    发表于 2023-10-14 09:49:58 | 显示全部楼层
    打卡学习签到



    微信图片_20231014094932.png
    跟着日天混 ,三天饱九顿!
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

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

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

    GMT+8, 2024-4-20 21:17 , Processed in 0.112622 second(s), 22 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

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