注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
Justice_Gao的个人空间 https://home.eeworld.com.cn/space-uid-784175.html [收藏] [复制] [分享] [RSS]
日志

MAX32630FTHR设计笔记(10):MAX32630本身存在问题:AD通道切换引起的干扰

已有 631 次阅读2017-9-12 22:30 |个人分类:MAX32630学习笔记

MAX32630的10位AD有多个通道,每个通道共用一个寄存器,如图

我在调试的时候使用1个通道AIN0的时候,用示波器查看波形并没有问题,但是在使用AIN0和AIN1时就出现问题,代码程序如下:
[C] 纯文本查看 复制代码
void TMR0_IRQHandler(void)
{
        static uint8_t ADC_GET_Time=0;
       
                ADC_GET_Time++;
                if(ADC_GET_Time % 10==0)
                {
                        adc_Channel=2;
                        //ADC0_StartConvert(ADC_CH_0, 0, 1,4);                //¿aê¼ADC0×a»»
                        //ADC_StartConvert(ADC_CH_0_DIV_5, 0, 0);
                        ADC_StartConvert(ADC_CH_0, 0, 0);
                        ADC_GET_Time = 1;
                }
                else if((ADC_GET_Time % 2==0)&&(adc_Channel==0))
                {
                        adc_Channel=1;
                        //ADC0_StartConvert(ADC_CH_1, 0, 1,5);                //¿aê¼ADC0×a»»
                        ADC_StartConvert(ADC_CH_1, 0, 0);
                        //ADC_StartConvert(ADC_CH_1_DIV_5, 0, 0);
                }
                TMR32_ClearFlag(MXC_TMR0);
}

程序的功能是用定时器计时切换AD通道,切换周期为10ms,其他程序如下:
[C] 纯文本查看 复制代码
#define USE_INTERRUPTS 1
//#undef USE_INTERRUPTS
/***** Globals *****/
//#ifdef USE_INTERRUPTS
volatile unsigned int adc_Channel = 0;

//#endif

/***** Functions *****/

#ifdef USE_INTERRUPTS
void AFE_IRQHandler(void)
{
    uint16_t ADC_Value_Temp=0;
    ADC_GetData(&ADC_Value_Temp);
    /* Signal bottom half that data is ready */
                if(adc_Channel == 1)
    {
                        //LED1_OFF;
                        Get_ADC1_Data(ADC_Value_Temp);
                       
                }
                else if(adc_Channel == 2)
    {
                        Get_ADC2_Data(ADC_Value_Temp);
                }
                adc_Channel = 0;
//                LED0_TURN;
                ADC_ClearFlags(MXC_F_ADC_INTR_ADC_DONE_IF);
    return;
}
#endif

void ADC0_Init()
{
    /* Initialize ADC */
    ADC_Init();
    #ifdef USE_INTERRUPTS
                //        NVIC_EnableIRQ(AFE_IRQn);
                        NVIC_ClearPendingIRQ(AFE_IRQn);
                        NVIC_DisableIRQ(AFE_IRQn);
                        NVIC_SetPriority(AFE_IRQn, 1);
                        NVIC_EnableIRQ(AFE_IRQn);
                #endif
}
/* ************************************************************************* */
void ADC0_StartConvert(mxc_adc_chsel_t channel, unsigned int adc_scale, unsigned int bypass, uint32_t mode)
{
  uint32_t ctrl_tmp;

  /* Clear the ADC done flag */
  ADC_ClearFlags(MXC_F_ADC_INTR_ADC_DONE_IF);
  /* Enable done interrupt */
  MXC_ADC->intr = MXC_F_ADC_INTR_ADC_DONE_IE;
  /* Insert channel selection */
  ctrl_tmp = MXC_ADC->ctrl;
  ctrl_tmp &= ~(MXC_F_ADC_CTRL_ADC_CHSEL);
  ctrl_tmp |= ((channel << MXC_F_ADC_CTRL_ADC_CHSEL_POS) | (mode<<MXC_F_ADC_CTRL_ADC_CHSEL_POS));
        //ctrl_tmp |= ((channel << MXC_F_ADC_CTRL_ADC_CHSEL_POS) & MXC_F_ADC_CTRL_ADC_CHSEL);
  
  /* Clear channel configuration */
  ctrl_tmp &= ~(MXC_F_ADC_CTRL_ADC_REFSCL | MXC_F_ADC_CTRL_ADC_SCALE | MXC_F_ADC_CTRL_BUF_BYPASS);

  /* ADC reference scaling must be set for all channels but two*/
  if ((channel != ADC_CH_VDD18) && (channel != ADC_CH_VDD12)) {
    ctrl_tmp |= MXC_F_ADC_CTRL_ADC_REFSCL;
  }

  /* Finalize user-requested channel configuration */
  if (adc_scale || channel > ADC_CH_3) {
    ctrl_tmp |= MXC_F_ADC_CTRL_ADC_SCALE;
  }
  if (bypass) {
    ctrl_tmp |= MXC_F_ADC_CTRL_BUF_BYPASS;
  }
  
  /* Write this configuration */
  MXC_ADC->ctrl = ctrl_tmp;
  
  /* Start conversion */
  MXC_ADC->ctrl |= MXC_F_ADC_CTRL_CPU_ADC_START;
       
}


这个问题美信技术支持也没有解决,这个问题无法避免,但是还是可以解决的,先来看现象

图1


图2


图3

从图2和图3可以看出,杂波出现的周期刚好是10ms一次,所以我们可以这样处理,(1)降采样;(2)延时10ms以上采样(具体看你切换的时间周期)

本文来自论坛,点击查看完整帖子内容。

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章