查看: 6560|回复: 4

[S32] s32k144 ADC 多通道采样问题

[复制链接]

该用户从未签到

1

主题

4

帖子

0

新手上路

Rank: 1

积分
19
最后登录
2019-3-20
发表于 2019-2-26 16:31:47 | 显示全部楼层 |阅读模式
void adc_irqHandler(void)
{
ADC_DRV_GetChanResult(ADC_INSTANCE, 0U, (uint16_t *)&adcRawValue);
adcConvDone = true;
}

void drv_adc_init(void)
{
uint16_t delayValue = 0;
adConv1_ChnConfig0.channel = ADC_CHN;
ADC_DRV_ConfigConverter(ADC_INSTANCE, &adConv1_ConvConfig0);
ADC_DRV_ConfigChan(ADC_INSTANCE, 0UL, &adConv1_ChnConfig0);
INT_SYS_InstallHandler(ADC0_IRQn, &adc_irqHandler, (isr_t*) 0);
if(!calculateIntValue(&pdly1_InitConfig0, PDLY_TIMEOUT, &delayValue))
{
  while(1);
}
PDB_DRV_Init(PDB_INSTANCE, &pdly1_InitConfig0);
PDB_DRV_ConfigAdcPreTrigger(PDB_INSTANCE, 0UL, &pdly1_AdcTrigInitConfig0);
PDB_DRV_SetTimerModulusValue(PDB_INSTANCE, (uint32_t)delayValue);
PDB_DRV_SetAdcPreTriggerDelayValue(PDB_INSTANCE, 0UL, 0UL, (uint32_t) delayValue);
PDB_DRV_LoadValuesCmd(PDB_INSTANCE);
PDB_DRV_SoftTriggerCmd(PDB_INSTANCE);
INT_SYS_EnableIRQ(ADC0_IRQn);
}

void drv_adc_main(void)
{
float adcValue;
if(adcConvDone == true)
{
  adcValue = ((float)adcRawValue / ((uint16_t)(1 << 12))) * (ADC_VREFH - ADC_VREFL);
  adcConvDone = false;
  PDB_DRV_SoftTriggerCmd(PDB_INSTANCE);
}
}
这是参考官方示例写的单通道采样,在这个基础上如何添加多通道,望指教,谢谢。
我知道答案 目前已有4人回答
回复

使用道具 举报

该用户从未签到

712

主题

6371

帖子

0

超级版主

Rank: 8Rank: 8

积分
24917
最后登录
2025-7-23
发表于 2019-2-27 13:28:01 | 显示全部楼层
adConv1_ChnConfig0.channel = ADC_CHN;
还有对应的引脚要配置为ADC功能,另外在中断里面,通道也要改成对应的添加的通道。
回复 支持 反对

使用道具 举报

该用户从未签到

1

主题

4

帖子

0

新手上路

Rank: 1

积分
19
最后登录
2019-3-20
 楼主| 发表于 2019-3-1 11:41:17 | 显示全部楼层
小恩GG 发表于 2019-2-27 13:28
adConv1_ChnConfig0.channel = ADC_CHN;
还有对应的引脚要配置为ADC功能,另外在中断里面,通道也要改成对 ...

有这样一个问题,就是一次PDB触发一个AD通道转换,我在中断后切换其它通道,在软件开启PDB,这样的方式可以实现多通道吗?
回复 支持 反对

使用道具 举报

该用户从未签到

1

主题

4

帖子

0

新手上路

Rank: 1

积分
19
最后登录
2019-3-20
 楼主| 发表于 2019-3-1 11:46:03 | 显示全部楼层
void adc_irqHandler(void)
{
        uint16_t convData;
        ADC_DRV_GetChanResult(ADC_INSTANCE, 0U, (uint16_t *)&convData);

        adcConvDone = 1;

        switch(AdcScan)
        {
                case ADC_CH1_CUSHION_LOCK:
                {
                        AdcData_a[ADC_CH1_CUSHION_LOCK] = convData;
                }break;
                case ADC_CH2_5V_BATT_1:
                {
                        AdcData_a[ADC_CH2_5V_BATT_1] = convData;
                }break;
//                case ADC_CH3_5V_BATT:
//                {
//                        AdcData_a[ADC_CH3_5V_BATT] = convData;
//                }break;
//                case ADC_CH6_VBAT_IA:
//                {
//                        AdcData_a[ADC_CH6_VBAT_IA] = convData;
//                }break;
//                case ADC_CH7_60VIN_IA:
//                {
//                        AdcData_a[ADC_CH7_60VIN_IA] = convData;
//                }break;
//                case ADC_CH8_TL_OUT_12V:
//                {
//                        AdcData_a[ADC_CH8_TL_OUT_12V] = convData;
//                }break;
//                case ADC_CH9_TR_OUT_12V:
//                {
//                        AdcData_a[ADC_CH9_TR_OUT_12V] = convData;
//                }break;
//                case ADC_CH12_Y_KEY_LED:
//                {
//                        AdcData_a[ADC_CH12_Y_KEY_LED] = convData;
//                }break;
//                case ADC_CH13_ACC:
//                {
//                        AdcData_a[ADC_CH13_ACC] = convData;
//                }break;
//                case ADC_CH14_ACC1:
//                {
//                        AdcData_a[ADC_CH14_ACC1] = convData;
//                }break;
//                case ADC_CH15_B_60V:
//                {
//                        AdcData_a[ADC_CH15_B_60V] = convData;
//                }break;
                default:
                {
                        Log_Debug(MODEN_ADC, "unkown channel, %d.\r\n", AdcScan);
                }break;
        }

        AdcScan++;
        if(AdcScan == ADC_CHANNEL_MAX)
        {
                AdcScanFinsh = 1;
        }

        return;
}

/* @brief: Calculate the values to be used by pdb to generate
*        a interrupt at a specific timeout.
* @param pdbConfig: pointer to the PDB configuration struct
* @param type:      pdb_timer_config_t *
* @param uSec:      interval for pdb interrupt in microseconds
* @param type:      uint32_t
* @param intVal:    pointer to the storage element where to set the calculated value
* @param type:      uint16_t
* @return:          Returns true if the interrupt period can be achieved, false if not
* @return type:     bool
*/
bool calculateIntValue(const pdb_timer_config_t *pdbConfig, uint32_t uSec, uint16_t * intVal)
{
    /* Local variables used to store different parameters
     * such as frequency and prescalers
     */
    uint32_t    intVal_l            = 0;
    uint8_t     pdbPrescaler        = (1 << pdbConfig->clkPreDiv);
    uint8_t     pdbPrescalerMult    = 0;
    uint32_t    pdbFrequency;

    bool resultValid = false;

    /* Get the Prescaler Multiplier from the configuration structure */
    switch (pdbConfig->clkPreMultFactor)
    {
        case PDB_CLK_PREMULT_FACT_AS_1:
            pdbPrescalerMult    =   1U;
            break;
        case PDB_CLK_PREMULT_FACT_AS_10:
            pdbPrescalerMult    =   10U;
            break;
        case PDB_CLK_PREMULT_FACT_AS_20:
            pdbPrescalerMult    =   20U;
            break;
        case PDB_CLK_PREMULT_FACT_AS_40:
            pdbPrescalerMult    =   40U;
            break;
        default:
            /* Defaulting the multiplier to 1 to avoid dividing by 0*/
            pdbPrescalerMult    =   1U;
            break;
    }

    /* Get the frequency of the PDB clock source and scale it
     * so that the result will be in microseconds.
     */
    CLOCK_SYS_GetFreq(BUS_CLOCK, &pdbFrequency);
    pdbFrequency /= 1000000;

    /* Calculate the interrupt value for the prescaler, multiplier, frequency
     * configured and time needed.
     */
    intVal_l = (pdbFrequency * uSec) / (pdbPrescaler * pdbPrescalerMult);

    /* Check if the value belongs to the interval */
    if((intVal_l == 0) || (intVal_l >= (1 << 16)))
    {
        resultValid = false;
        (*intVal) = 0U;
    }
    else
    {
        resultValid = true;
        (*intVal) = (uint16_t)intVal_l;
    }

    return resultValid;
}

/**
  * @brief  match adc channel and callback function
  * @param  scanCh: valid adc channel
  * @param  fAdcFinsh: adc finish callback function
  * @retval
  */
uint32_t drv_adc_add(SCAN_ADC_CH_E scanCh, DrvAdcCallBack fAdcFinsh)
{
        if(scanCh < ADC_CHANNEL_MAX)
        {
                AdcCallBack_a[scanCh] = fAdcFinsh;
        }else
        {
                Log_Debug(MODEN_ADC, "err channel,scanCh(%d).\r\n", scanCh);
        }

        return 1;
}

/**
  * @brief
  * @param
  * @retval
  */
static void drv_adc_work(void)
{
        uint32_t i;

        if(AdcScanFinsh == 1)
        {
                AdcScanFinsh = 0;

                for(i=0; i<(uint32_t)ADC_CHANNEL_MAX; i++)
                {
                        if(AdcCallBack_a[i] != NULL)
                        {
                                (AdcCallBack_a[i])(AdcData_a[i]);   //call back
                                //Log_Debug(MODEN_ADC, "AdcData_a[%d]=%d.\r\n", i, AdcData_a[i]);
                        }
                }
        }

        if(adcConvDone == 1)
        {
                adcConvDone = 0;

                switch(AdcScan)
                {
                        case ADC_CH1_CUSHION_LOCK:
                        {
        //                        adConv1_ChnConfig0.channel = 2;
        //                        ADC_DRV_ConfigChan(ADC_INSTANCE, 0UL, &adConv1_ChnConfig0);
        //                        PDB_DRV_SoftTriggerCmd(PDB_INSTANCE);
                        }break;
                        case ADC_CH2_5V_BATT_1:
                        {
                                adConv1_ChnConfig0.channel = 2;
                                ADC_DRV_ConfigChan(ADC_INSTANCE, 0UL, &adConv1_ChnConfig1);
                                PDB_DRV_SoftTriggerCmd(PDB_INSTANCE);
                        }break;
        //                case ADC_CH3_5V_BATT:
        //                {
        //                        AdcData_a[ADC_CH3_5V_BATT] = convData;
        //                }break;
        //                case ADC_CH6_VBAT_IA:
        //                {
        //                        AdcData_a[ADC_CH6_VBAT_IA] = convData;
        //                }break;
        //                case ADC_CH7_60VIN_IA:
        //                {
        //                        AdcData_a[ADC_CH7_60VIN_IA] = convData;
        //                }break;
        //                case ADC_CH8_TL_OUT_12V:
        //                {
        //                        AdcData_a[ADC_CH8_TL_OUT_12V] = convData;
        //                }break;
        //                case ADC_CH9_TR_OUT_12V:
        //                {
        //                        AdcData_a[ADC_CH9_TR_OUT_12V] = convData;
        //                }break;
        //                case ADC_CH12_Y_KEY_LED:
        //                {
        //                        AdcData_a[ADC_CH12_Y_KEY_LED] = convData;
        //                }break;
        //                case ADC_CH13_ACC:
        //                {
        //                        AdcData_a[ADC_CH13_ACC] = convData;
        //                }break;
        //                case ADC_CH14_ACC1:
        //                {
        //                        AdcData_a[ADC_CH14_ACC1] = convData;
        //                }break;
        //                case ADC_CH15_B_60V:
        //                {
        //                        AdcData_a[ADC_CH15_B_60V] = convData;
        //                }break;
                        case ADC_CHANNEL_MAX:
                        {
                                AdcScan = ADC_CH1_CUSHION_LOCK;

                                adConv1_ChnConfig0.channel = 1;
                                ADC_DRV_ConfigChan(ADC_INSTANCE, 0UL, &adConv1_ChnConfig0);
                                PDB_DRV_SoftTriggerCmd(PDB_INSTANCE);
                        }break;
                        default:
                        {
                                Log_Debug(MODEN_ADC, "unkown channel, %d.\r\n", AdcScan);
                        }break;
                }
        }
}

uint32_t test_callback_func(uint32_t val)
{
        Log_Debug(MODEN_ADC, "val1=%d\r\n", val);

        return 0;
}

uint32_t test_callback_func1(uint32_t val)
{
        Log_Debug(MODEN_ADC, "val2=%d\r\n", val);

        return 0;
}

/**
  * @brief
  * @param
  * @retval
  */
void drv_adc_init(void)
{
        uint16_t delayValue = 0;

        adConv1_ChnConfig0.channel = 1;
        ADC_DRV_ConfigConverter(ADC_INSTANCE, &adConv1_ConvConfig0);
        ADC_DRV_ConfigChan(ADC_INSTANCE, 0UL, &adConv1_ChnConfig0);

        INT_SYS_InstallHandler(ADC0_IRQn, &adc_irqHandler, (isr_t*) 0);

        if(!calculateIntValue(&pdly1_InitConfig0, PDLY_TIMEOUT, &delayValue))
        {
                while(1);
        }

        Log_Debug(MODEN_ADC, "delayValue=0x%x\r\n", delayValue);  //delayValue = 18750

        PDB_DRV_Init(PDB_INSTANCE, &pdly1_InitConfig0);
        PDB_DRV_ConfigAdcPreTrigger(PDB_INSTANCE, 0UL, &pdly1_AdcTrigInitConfig0);
        PDB_DRV_SetTimerModulusValue(PDB_INSTANCE, (uint32_t)delayValue);
        PDB_DRV_SetAdcPreTriggerDelayValue(PDB_INSTANCE, 0UL, 0UL, (uint32_t) delayValue);
        PDB_DRV_LoadValuesCmd(PDB_INSTANCE);
        PDB_DRV_SoftTriggerCmd(PDB_INSTANCE);

        INT_SYS_EnableIRQ(ADC0_IRQn);

        drv_adc_add(ADC_CH1_CUSHION_LOCK, test_callback_func);
        drv_adc_add(ADC_CH2_5V_BATT_1, test_callback_func1);
}

/**
  * @brief
  * @param
  * @retval
  */
void drv_adc_main(void)
{
        drv_adc_work();

        return;
}
暂时用这样的方式写的ADC多通道采集,还未试有没有用,也不知道可不可以实现
回复 支持 反对

使用道具 举报

该用户从未签到

0

主题

1

帖子

0

新手上路

Rank: 1

积分
39
最后登录
2020-3-4
发表于 2020-2-25 21:01:46 | 显示全部楼层
我也遇到S32K144多通道的使用问题,这样写OK吗?
回复 支持 反对

使用道具 举报

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

本版积分规则

关闭

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

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

GMT+8, 2025-7-24 00:31 , Processed in 0.092816 second(s), 25 queries , MemCache On.

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

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