跳转至内容
  • 版块
  • 最新
  • 标签
  • 热门
折叠
品牌标识

YunTu Forum

YTMicro.com
  1. 主页
  2. Discussion & Question
  3. YT MCAL
  4. mcal ADC硬件触发和软件触发混用DEMO

mcal ADC硬件触发和软件触发混用DEMO

已定时 已固定 已锁定 已移动 已解决 YT MCAL
demopwm
14 帖子 4 发布者 3.9k 浏览
  • 从旧到新
  • 从新到旧
  • 最多赞同
登录后回复
此主题已被删除。只有拥有主题管理权限的用户可以查看。
  • qinzhaoQ 离线
    qinzhaoQ 离线
    qinzhao YunTu
    写于 最后由 编辑
    #1

    1.背景
    在PWM的下降沿触发ADC采集
    2.需求

    • PWM(eTMR0_CH0)的每个周期中,上升沿触发ADC转换10次后,切换到3个软件触发的group的采集。
    • MCAL: 2.2.0 , gcc
    • YTM32B1ME0X
      3.解决方案描述:
      由于PWM模块没有提供MID值的设置API,采用手写代码设置MID值:
      eTMR0->SYNC |= eTMR_SYNC_CLDOK_MASK;
      eTMR0->MID = eTMR0->CH[0].VAL1;
      eTMR0->SYNC |= eTMR_SYNC_LDOK(1);
    

    1d4fd905-ae3c-47d3-888c-f4ee53cb1bf2-image.png
    测试波形:
    bd8b3693-ae79-4952-81dd-89a6bb2aa4b6-image.png
    示例工程:12694718-26d0-4c88-a824-16035e3174d3-Adc_HwTrig_Demo.zip

    EkkoE 1 条回复 最后回复
    0
    • SSEZKXS 离线
      SSEZKXS 离线
      SSEZKX YunTu
      写于 最后由 SSEZKX 编辑
      #4

      尝试在切换ADC触发方式的间插入Init和DeInit的操作;
      在采样完成后,DeInit ADC,Disable ADC HW触发信号输出,后Init ADC,
      确定ADC寄存器STS_ADRDY位 置一后,再Enable ADC HW触发信号输出;
      为了保证代码执行效率,这部分操作建议直接操作寄存器;

      EkkoE 1 条回复 最后回复
      0
      • EkkoE 离线
        EkkoE 离线
        Ekko
        在 回复了 qinzhao 最后由 编辑
        #2

        qinzhao 你好 我们有客户的应用场景需要频繁的软硬件触发切换,具体为每隔1ms触发sw adc采样,会先关闭adc hw触发,完成sw后,再打开adc hw触发,有概率出现hw触发不成功,后续排查是关闭hw触发之后,必须延迟800us左右,才能正常打开adc hw触发,请问一下这个延迟时间是因为什么,之前无延迟操作,函数也不报DET错误,看起来像是生效的。

        1 条回复 最后回复
        0
        • xianghanX 离线
          xianghanX 离线
          xianghan YunTu
          写于 最后由 编辑
          #3

          使用的什么方式进行硬件触发ADC?

          EkkoE 1 条回复 最后回复
          0
          • SSEZKXS 离线
            SSEZKXS 离线
            SSEZKX YunTu
            写于 最后由 SSEZKX 编辑
            #4

            尝试在切换ADC触发方式的间插入Init和DeInit的操作;
            在采样完成后,DeInit ADC,Disable ADC HW触发信号输出,后Init ADC,
            确定ADC寄存器STS_ADRDY位 置一后,再Enable ADC HW触发信号输出;
            为了保证代码执行效率,这部分操作建议直接操作寄存器;

            EkkoE 1 条回复 最后回复
            0
            • EkkoE 离线
              EkkoE 离线
              Ekko
              在 回复了 xianghan 最后由 编辑
              #5

              xianghan etmr触发

              1 条回复 最后回复
              0
              • EkkoE 离线
                EkkoE 离线
                Ekko
                在 回复了 SSEZKX 最后由 编辑
                #6

                SSEZKX 这样时间会不会太久,客户的意思就是现在的延时时间太久,影响正常功能

                1 条回复 最后回复
                0
                • SSEZKXS 离线
                  SSEZKXS 离线
                  SSEZKX YunTu
                  写于 最后由 编辑
                  #7

                  不会,这样操作时间很短,可以参考这个电机demo代码
                  71654c09-93fd-404e-86b1-9d8316a0c3f8.zip

                  1 条回复 最后回复
                  0
                  • SSEZKXS 离线
                    SSEZKXS 离线
                    SSEZKX YunTu
                    写于 最后由 编辑
                    #8

                    不需要额外增加延时,只需要等待ADC自身采集和转换以及代码执行的时间

                    EkkoE 1 条回复 最后回复
                    0
                    • EkkoE 离线
                      EkkoE 离线
                      Ekko
                      在 回复了 SSEZKX 最后由 编辑
                      #9

                      SSEZKX 好的 我让客户试一下

                      1 条回复 最后回复
                      0
                      • SSEZKXS 离线
                        SSEZKXS 离线
                        SSEZKX YunTu
                        写于 最后由 编辑
                        #10

                        可以参考OneShunt Demo中这两个API

                        1. HW_SetupAdcSeqMode
                        2. Motor_AdcFOCISR
                        EkkoE 1 条回复 最后回复
                        0
                        • EkkoE 离线
                          EkkoE 离线
                          Ekko
                          在 回复了 SSEZKX 最后由 编辑
                          #11

                          SSEZKX 如果我Disable ADC HW触发信号输出 然后判断确定ADC寄存器STS_ADRDY位 置一后,再Enable ADC HW触发信号输出,这个步骤可以吗,省去Init和DeInit操作

                          1 条回复 最后回复
                          0
                          • SSEZKXS 离线
                            SSEZKXS 离线
                            SSEZKX YunTu
                            写于 最后由 编辑
                            #12

                            image.png
                            我这里弄错了,ADC重新初始化才需要Disable,不进行重新初始化不需要Disable ADC HW触发信号输出,只需要在采样完成进入中断后按用户需求重新配置ADC就行,配置完后执行以下流程重装载回调函数和开启ADC,等待标志位

                                base->INTE = ADC_INTE_EOSEQIE(1U);                                   /* Enable end of sequence interrupt */
                                INT_SYS_InstallHandler(ADC0_IRQn, adcISR, NULL);
                                INT_SYS_EnableIRQ(ADC0_IRQn);
                                base->CTRL = ADC_CTRL_TSEN(1U) |                                     /* Enable temperature sensor */
                                             ADC_CTRL_ADEN(1U);                                      /* Enable ADC */
                                base->CTRL |= ADC_CTRL_ADSTART(1U);                                  /* Start ADC */
                                while(!(base->STS & ADC_STS_ADRDY_MASK));                           /* Wait for ADC ready */
                            
                            EkkoE 1 条回复 最后回复
                            0
                            • EkkoE 离线
                              EkkoE 离线
                              Ekko
                              在 回复了 SSEZKX 最后由 编辑
                              #13

                              SSEZKX 可能我描述也有点不清楚,客户需要在ADC HW触发中 穿插一次SW触发,所以肯定先得Disable ADC HW 触发,再打开SW 触发,所以这样的话,是不是直接再判断STS_ADRDY位就行了呢

                              1 条回复 最后回复
                              0
                              • SSEZKXS 离线
                                SSEZKXS 离线
                                SSEZKX YunTu
                                写于 最后由 SSEZKX 编辑
                                #14

                                不是的,我们的单电阻电机demo就是这样操作的,ADCHW触发,step采样完成后,切换成ADCSW触发,continue采样,完成后切换回ADCHW触发,是这个意思吧,ME0是这样做的,别的芯片也一样,寄存器操作有细微区别

                                void HW_SetupAdcSeq1Mode(const uint8_t *channels, uint8_t channel_cnt, const isr_t adcISR)
                                {    
                                    ADC_Type *base = ADC0;
                                
                                    /* Setup adc configuration */
                                    base->CFG0 = ((channel_cnt - 1) & 0xFU) << ADC_CFG0_SEQLEN_SHIFT |   /* Sequence length */
                                                 ADC_CFG0_DISCEN(1U) |                                                                    
                                                 ADC_CFG0_CONT(0U) |
                                                 ADC_CFG0_TRIGMD(1U);                                  
                                
                                    base->CFG1 = ADC_CFG1_STCNT(32U) | ADC_CFG1_PRS(0);                   /* Start time count */
                                    base->SMP = ADC_SMP_SMP(1U);                                         /* Sample time */
                                
                                        /* Configure sequence 0 channels for current sensing */
                                    ADC0->CHSEL[0] = ADC_CHSEL_CHSEL(ADC_V_PHASE_CHANNEL);
                                    ADC0->CHSEL[1] = ADC_CHSEL_CHSEL(ADC_V_PHASE_CHANNEL);
                                
                                    base->INTE = ADC_INTE_EOSEQIE(1U);                                     /* Enable end of sequence interrupt */
                                    INT_SYS_InstallHandler(ADC0_IRQn, adcISR, NULL);
                                    INT_SYS_EnableIRQ(ADC0_IRQn);
                                    base->CTRL = ADC_CTRL_ADEN(1U);                                      /* Enable ADC */
                                    base->CTRL |= ADC_CTRL_ADSTART(1U);                                  /* Start ADC */
                                    while(!(base->STS & ADC_STS_ADRDY_MASK));                            /* Wait for ADC ready */
                                }
                                
                                void HW_SetupAdcSeq2Mode(const uint8_t *channels, uint8_t channel_cnt, const isr_t adcISR)
                                {    
                                    ADC_Type *base = ADC0;
                                
                                    /* Setup adc configuration */
                                    base->CFG0 = ((channel_cnt - 1) & 0xFU) << ADC_CFG0_SEQLEN_SHIFT |   /* Sequence length */
                                                 ADC_CFG0_CONT(0U) |
                                                 ADC_CFG0_DISCEN(0U) |
                                                 ADC_CFG0_TRIGMD(0U);                                    
                                
                                    base->CFG1 = ADC_CFG1_STCNT(32U) | ADC_CFG1_PRS(0);                 /* Start time count */
                                    base->SMP = ADC_SMP_SMP(16U);                                         /* Sample time */
                                    for (int i = 0; i < channel_cnt; i++)
                                    {
                                        base->CHSEL[i] = ADC_CHSEL_CHSEL(channels[i]);                   /* Setup channel */
                                    }
                                    base->INTE = ADC_INTE_EOSEQIE(1U);                                   /* Enable end of sequence interrupt */
                                    INT_SYS_InstallHandler(ADC0_IRQn, adcISR, NULL);
                                    INT_SYS_EnableIRQ(ADC0_IRQn);
                                    base->CTRL = ADC_CTRL_TSEN(1U) |                                     /* Enable temperature sensor */
                                                 ADC_CTRL_ADEN(1U);                                      /* Enable ADC */
                                    base->CTRL |= ADC_CTRL_ADSTART(1U);                                  /* Start ADC */
                                    while(!(base->STS & ADC_STS_ADRDY_MASK));                           /* Wait for ADC ready */
                                }
                                
                                
                                uint8_t ADCTrgCnt = 0U;
                                void Motor_AdcFOCISR(void)
                                {
                                    // GPIOE->PSOR = 1 << 10;
                                    /* Clear the interrupt flag */
                                    MC_ADC->STS = ADC_STS_EOSEQ_MASK;
                                    if(ADCTrgCnt  == 0U)
                                    {
                                        CIM->SWTRIG = CIM_SWTRIG_SWT(1U) | CIM_SWTRIG_SWTCNT(0U);
                                
                                        /* User code */
                                
                                        ADCTrgCnt = 1;
                                
                                        HW_SetupAdcSeq2Mode(motorAdcFocUserSample2, 2, Motor_AdcFOCISR);
                                    }
                                    else
                                    {
                                        /* User code */
                                
                                        HW_SetupAdcSeq1Mode(motorAdcFocUserSample1, 2, Motor_AdcFOCISR);
                                        ADCTrgCnt = 0U;
                                    }
                                    // GPIOE->PCOR = 1 << 10;
                                }
                                
                                
                                
                                
                                1 条回复 最后回复
                                0
                                • ,FrankieF Frankie 将这个主题转为问答主题
                                • ,FrankieF Frankie 将这个主题标记为已解决

                              • 云途开发生态介绍

                                快速上手云途开发生态

                              • 云途论坛规则/Yuntu Forum Rules

                                发帖前请查看

                              • YT CONFIG TOOL调查问卷

                                帮助改进和优化YT CONFIG TOOL,有机会抽取YTM32B1ME0 EVB哦...

                              • can
                                25
                                demo
                                23
                                lin stack
                                13
                                uds
                                13
                                md14
                                6
                                yt-link
                                6
                                fbl
                                5
                                adc模块
                                4
                                Online Users
                                • 登录

                                • 登录或注册以进行搜索。
                                • 第一个帖子
                                  最后一个帖子
                                0
                                • 版块
                                • 最新
                                • 标签
                                • 热门