查看: 4103|回复: 7

[MQX] 关于 MK64 MQX BSP(板级支持包)ADC USART等最最底层的驱动的疑问

[复制链接]
  • TA的每日心情
    郁闷
    2021-9-6 10:31
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    8

    主题

    57

    帖子

    0

    注册会员

    Rank: 2

    积分
    128
    最后登录
    2021-10-9
    发表于 2016-8-30 09:58:55 | 显示全部楼层 |阅读模式
    本帖最后由 gdgn526345 于 2016-8-30 10:01 编辑

    关于 MK64 MQX  BSP(板级支持包)ADC USART等最最底层的驱动的疑问

    最近,新的项目接触飞思卡尔的K64 和 MQX,在ADC\USART等硬件驱动,存在迷惑!

    最最底层的硬件初始化(比如I/O口功能的选择、跟据AD通道配置相应的IO功能)我找不到在哪里配置的?

    比如,以下为BSP的 initBSP.c(硬件初始化文件),以ADC0为例:

    如果我使能ADC0模块  #define BSPCFG_ENABLE_ADC0       1

    initbsp就会执行以下的ADC0初始化函数:_io_adc_install("adc0:", (void *) &_bsp_adc0_init);

    #if BSPCFG_ENABLE_ADC0
        _io_adc_install("adc0:", (void *) &_bsp_adc0_init);
    #endif

    分析ADC0的 初始化函数_io_adc_install主要是依据 &_bsp_adc0_init的内容:
    内容包括给ADC0S模块分配时钟源、设置时间分频、AD采样速率、中断向量、中断优先级以及ADC0的触发方式等。

    typedef struct kadc_install_struct
    {
        /* The number of ADC peripheral, use adc_t enum from PSP */
        uint8_t ADC_NUMBER;

        /* The clock source */
        ADC_CLOCK_SOURCE CLOCK_SOURCE;

        /* The clock divisor for ADC */
        ADC_CLOCK_DIV CLOCK_DIV;

        /* ADC high speed control, see ADC_HSC enum */
        ADC_HSC SPEED;

        /* ADC low power control, see ADC_LPC enum */
        ADC_LPC POWER;

        /* The calibration data pointer */
        uint8_t *CALIBRATION_DATA_PTR;

        /* ADC interrupt vector */
        uint32_t ADC_VECTOR;

        /* ADC interrupt vector */
        uint32_t ADC_PRIORITY;

        /* KPDB init structure */
        const KPDB_INIT_STRUCT * PDB_INIT;

    } KADC_INIT_STRUCT, * KADC_INIT_STRUCT_PTR;
    /////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////
    const KADC_INIT_STRUCT _bsp_adc0_init = {
        /* The number of ADC peripheral, use adc_t enum from PSP */
        0,
        /* The clock source, selects the best from BUSCLK and BUSCLK/2 */
        ADC_CLK_BUSCLK_ANY,
        /* The clock divisor for ADC. use the fastest one */
        ADC_DIV_ANY,
        /* ADC high speed control, see ADC_HSC enum */
        ADC_HSC_NORMAL,
        /* ADC low power control, see ADC_LPC enum */
        ADC_LPC_NORMAL,
        /* The calibration data pointer */
        NULL,
        /* ADC interrupt vector */
        INT_ADC0,
        /* ADC interrupt vector */
        BSP_ADC0_VECTOR_PRIORITY,
        /* PDB init structure */
        &_bsp_pdb_init
    };

    但是,但是 这个硬件的初始化都没有涉及到最最底层的,I/O口的功能和AD通道的选择和配置????


    再返回来分析一下ADC0的 任务,ADC0任务流使用的通道是:ADC_CHANNEL_DP3_DIFF:
    大致的流程:

    定义ADC通道和工作方式:
    #define     ADC_VALUE_MASK      ((uint32_t)(0xff))
    #define     ADC_SAMPLE_FREQ     ((uint32_t)(256))
    #define     ADC0_TABLE          {ADC_CHANNEL_DP3_DIFF}////选择ADC通道是ADC_CHANNEL_DP3_DIFF
    #define     ADC0_TABLE_LEN      (1)

    //define if testing DIFF channel
    #define TEST_DIFF_CH

    以下为ADC0的初始化(初始化也没有看到有IO和通道选择的部分)??????????
    typedef struct
    {
        ADC_CLOCK               xAdcClock;              //时钟
        ADC_CLOCK_DIVSION       xAdcClockDivsion;       //时钟分频
        ADC_ADACK               xAdcAck;                //异步时钟输出
        ADC_DIFF                xAdcDiff;               //差分使能
        ADC_LOWPOWER            xAdcLowpower;           //低功耗模式
        ADC_MODE                xAdcMode;               //采样精度
        ADC_LONG_SAMPLE         xAdcLongSample;         //长采样
        ADC_LONG_SAMPLE_TIME    xAdcLongSampleTime;     //长采样时间
        ADC_SPEED               xAdcSpeed;              //转换速度
        ADC_TRIGGER             xAdcTrigger;            //触发方式
        ADC_REFSEL              xAdcRefsel;             //参考电压
        ADC_AVERAGE             xAdcAverage;            //硬件均值
        ADC_AVERAGE_SELECT      xAdcAverageSelect;      //硬件均值采样数量
        ADC_AVERAGE_CONTINUOUS  xAdcAverageContinuous;  //硬件均值连续转换次数
        void                    (*old_isr)(pointer);    //中断服务程序入口
        pointer                 old_isr_data;           //中断服务程序参数
    }ADC_PARAMETER;

    ADC_PARAMETER   ux_Adc_Parameter;

    ADC_StructInit(&ux_Adc_Parameter);//初始化ADC0,ADC0工作模式的初始化

    再往下的机制大概就是利用PDB和2个DMA通道配合,分别片选ADC通道和读取ADC的采样结果,
    并通过printfK串口打印(其中,这里用到的只有一个ADC通道,但从原理上做了多通道的考虑)

        //配置DMA通道1,利用PDB和DMA原理机制是片选触发不同的ADC通道
        ADC_DMACmd(ADC0, ENABLE);
            
        DMA_PARAMETER   ux_Dma_Parameter;

        DMA_StructInit(&ux_Dma_Parameter);
        ux_Dma_Parameter.xDmaSrcChannel = DMAMUX_SRC_CHANNEL_PDB;
        ux_Dma_Parameter.u32SourceAddress = (uint32_t)&(u32_p_adc0_channel_table[0]);//跟AD通道有关的
        ux_Dma_Parameter.u32DestinationAddress = (uint32_t)&(ADC0_SC1A);
        ux_Dma_Parameter.u16SourceNextValueOffset = sizeof(uint32_t);
        ux_Dma_Parameter.u16DestinationNextValueOffset = 0;
        ux_Dma_Parameter.u8SourceAddressModulo = 0;
        ux_Dma_Parameter.u8DestinationAddressModulo = 0;
        ux_Dma_Parameter.xSourceDataSize = DMA_TRANSFER_SIZE_32_BIT;
        ux_Dma_Parameter.xDestinationDataSize = DMA_TRANSFER_SIZE_32_BIT;
        ux_Dma_Parameter.u32ByteTransferCount = sizeof(uint32_t);
        ux_Dma_Parameter.u32LastSourceAddressAdjustment = -(ADC0_TABLE_LEN * ux_Dma_Parameter.u16SourceNextValueOffset);
        ux_Dma_Parameter.u32LastDestinationAddressAdjustment = 0;
        ux_Dma_Parameter.u16BufferSize = ADC0_TABLE_LEN;
        DMA_Init(DMA_CHANNEL_0, DMAMUX, &ux_Dma_Parameter);
        DMA_Cmd(DMA_CHANNEL_0, DMAMUX, ENABLE);

    这里在配置DMA的的源地址的时候出现了跟ADC通道有关的    ux_Dma_Parameter.u32SourceAddress = (uint32_t)&(u32_p_adc0_channel_table[0]);
    也就是ADC_CHANNEL_DP3_DIFF
    但是也看不到有跟ADC通道的真正的最最底层的配置(ADCIO初始化和真正的ADC通道的选择的部分)
    ???????????????????????????????????????????????

    /////////////////////////////////////////////////////////
    //以下是配置DMA通道1 通过DMA读取ADC的打样结果
       ux_Dma_Parameter.xDmaSrcChannel = DMAMUX_SRC_CHANNEL_ADC0;
        ux_Dma_Parameter.u32SourceAddress = (uint32_t)&(ADC0_RA);
        ux_Dma_Parameter.u32DestinationAddress = (uint32_t)&(ux_adc0_value.u16_p_all_value[0]);
        ux_Dma_Parameter.u16SourceNextValueOffset = 0;
        ux_Dma_Parameter.u16DestinationNextValueOffset = sizeof(uint16_t);
        ux_Dma_Parameter.u8SourceAddressModulo = 0;
        ux_Dma_Parameter.u8DestinationAddressModulo = 0;
        ux_Dma_Parameter.xSourceDataSize = DMA_TRANSFER_SIZE_16_BIT;
        ux_Dma_Parameter.xDestinationDataSize = DMA_TRANSFER_SIZE_16_BIT;
        ux_Dma_Parameter.u32ByteTransferCount = sizeof(uint16_t);
        ux_Dma_Parameter.u32LastSourceAddressAdjustment = 0;
        ux_Dma_Parameter.u32LastDestinationAddressAdjustment = -((ADC0_TABLE_LEN*(ADC_VALUE_MASK + 1)) * ux_Dma_Parameter.u16DestinationNextValueOffset);
        ux_Dma_Parameter.u16BufferSize = ADC0_TABLE_LEN*(ADC_VALUE_MASK + 1);
        DMA_Init(DMA_CHANNEL_1, DMAMUX, &ux_Dma_Parameter);
        DMA_Cmd(DMA_CHANNEL_1, DMAMUX, ENABLE);
       
    ///////////////到最后面就是取数据串口打印................

    到整个过程下来,我都没有找到,也是让我迷惑的地方。。。。。。。最最底层的IO和 ADC通道的选择和配置的那部分硬件的初始化。



    以下是 ADC0任务的DEMO代码:

    谢谢大家!

    #include <mqx.h>
    #include <bsp.h>
    #include "adc16.h"
    #include "dma.h"
    #include "app_dma.h"

    #define     ADC_VALUE_MASK      ((uint32_t)(0xff))
    #define     ADC_SAMPLE_FREQ     ((uint32_t)(256))
    #define     ADC0_TABLE          {ADC_CHANNEL_DP3_DIFF}
    #define     ADC0_TABLE_LEN      (1)

    //define if testing DIFF channel
    #define TEST_DIFF_CH

    typedef union
    {
        struct
        {
            uint16_t  u16_channel[ADC0_TABLE_LEN];
        }ux_p_each_value[ADC_VALUE_MASK + 1];
        uint16_t  u16_p_all_value[ADC0_TABLE_LEN*(ADC_VALUE_MASK + 1)];
    } ADC0_VALUE;

    uint32_t          u32_p_adc0_channel_table[ADC0_TABLE_LEN] = ADC0_TABLE;
    ADC0_VALUE      ux_adc0_value;

    uint32_t cnt = 0;

    /* Task IDs */
    #define MAIN_TASK 5

    /* Function prototypes */
    extern void main_task(uint32_t);

    const TASK_TEMPLATE_STRUCT MQX_template_list[] =
    {
        /* Task Index,  Function,  Stack,  Priority,    Name,       Attributes,             Param,  Time Slice */
        {MAIN_TASK,     main_task, 2048,      8,        "Main",     MQX_AUTO_START_TASK,    0,      0           },
        {0}
    };

    /*TASK*-----------------------------------------------------
    **
    ** Task Name    : main_task
    ** Comments     :
    **
    *END*-----------------------------------------------------*/
    void main_task
       (
          uint32_t initial_data
       )
    {
    #ifdef TEST_DIFF_CH
        short buf[ADC0_TABLE_LEN*(ADC_VALUE_MASK + 1)];
    #endif
       
        ADC_PARAMETER   ux_Adc_Parameter;
       
        ADC_StructInit(&ux_Adc_Parameter);
        /* Before calibration, set hardware average to maximum and set ADC clock to be less than or equal to 4MHz,
        using external reference VREFH = VDDA */
        //ux_Adc_Parameter.xAdcAck               = ADC_ADACK_ENABLE;
        ux_Adc_Parameter.xAdcClock              = ADC_CLOCK_BUSCLK;
        ux_Adc_Parameter.xAdcClockDivsion       = ADC_CLOCK_DIVSION_8;
        ux_Adc_Parameter.xAdcMode               = ADC_MODE_16_BIT;
        ux_Adc_Parameter.xAdcLongSample         = ADC_LONG_SAMPLE_ENABLE;
        ux_Adc_Parameter.xAdcLongSampleTime     = ADC_LONG_SAMPLE_TIME_6ADCK;
        /* Select internal reference */
        ux_Adc_Parameter.xAdcRefsel             = ADC_REFSEL_INTERNAL;
        /* Set ADC speed and low power mode to select ADACK value */
        ux_Adc_Parameter.xAdcSpeed              = ADC_SPEED_HIGH;

        /* hardware average enable */
        ux_Adc_Parameter.xAdcAverage            = ADC_AVERAGE_ENABLE;
        ux_Adc_Parameter.xAdcAverageContinuous  = ADC_AVERAGE_CONTINUOUS_1;
        ux_Adc_Parameter.xAdcAverageSelect      = ADC_AVERAGE_SELECT_32;

        ADC_Init(ADC0, &ux_Adc_Parameter);
        ADC_Cal(ADC0);

        /* hardware average enable */
        //ux_Adc_Parameter.xAdcAverage            = ADC_AVERAGE_DISABLE;
        ux_Adc_Parameter.xAdcAverageSelect      = ADC_AVERAGE_SELECT_4;
        ADC_Init(ADC0, &ux_Adc_Parameter);
       
        ADC_DMACmd(ADC0, ENABLE);
            
        DMA_PARAMETER   ux_Dma_Parameter;

        DMA_StructInit(&ux_Dma_Parameter);
        ux_Dma_Parameter.xDmaSrcChannel = DMAMUX_SRC_CHANNEL_PDB;
        ux_Dma_Parameter.u32SourceAddress = (uint32_t)&(u32_p_adc0_channel_table[0]);
        ux_Dma_Parameter.u32DestinationAddress = (uint32_t)&(ADC0_SC1A);
        ux_Dma_Parameter.u16SourceNextValueOffset = sizeof(uint32_t);
        ux_Dma_Parameter.u16DestinationNextValueOffset = 0;
        ux_Dma_Parameter.u8SourceAddressModulo = 0;
        ux_Dma_Parameter.u8DestinationAddressModulo = 0;
        ux_Dma_Parameter.xSourceDataSize = DMA_TRANSFER_SIZE_32_BIT;
        ux_Dma_Parameter.xDestinationDataSize = DMA_TRANSFER_SIZE_32_BIT;
        ux_Dma_Parameter.u32ByteTransferCount = sizeof(uint32_t);
        ux_Dma_Parameter.u32LastSourceAddressAdjustment = -(ADC0_TABLE_LEN * ux_Dma_Parameter.u16SourceNextValueOffset);
        ux_Dma_Parameter.u32LastDestinationAddressAdjustment = 0;
        ux_Dma_Parameter.u16BufferSize = ADC0_TABLE_LEN;
        DMA_Init(DMA_CHANNEL_0, DMAMUX, &ux_Dma_Parameter);
        DMA_Cmd(DMA_CHANNEL_0, DMAMUX, ENABLE);
       
        ux_Dma_Parameter.xDmaSrcChannel = DMAMUX_SRC_CHANNEL_ADC0;
        ux_Dma_Parameter.u32SourceAddress = (uint32_t)&(ADC0_RA);
        ux_Dma_Parameter.u32DestinationAddress = (uint32_t)&(ux_adc0_value.u16_p_all_value[0]);
        ux_Dma_Parameter.u16SourceNextValueOffset = 0;
        ux_Dma_Parameter.u16DestinationNextValueOffset = sizeof(uint16_t);
        ux_Dma_Parameter.u8SourceAddressModulo = 0;
        ux_Dma_Parameter.u8DestinationAddressModulo = 0;
        ux_Dma_Parameter.xSourceDataSize = DMA_TRANSFER_SIZE_16_BIT;
        ux_Dma_Parameter.xDestinationDataSize = DMA_TRANSFER_SIZE_16_BIT;
        ux_Dma_Parameter.u32ByteTransferCount = sizeof(uint16_t);
        ux_Dma_Parameter.u32LastSourceAddressAdjustment = 0;
        ux_Dma_Parameter.u32LastDestinationAddressAdjustment = -((ADC0_TABLE_LEN*(ADC_VALUE_MASK + 1)) * ux_Dma_Parameter.u16DestinationNextValueOffset);
        ux_Dma_Parameter.u16BufferSize = ADC0_TABLE_LEN*(ADC_VALUE_MASK + 1);
        DMA_Init(DMA_CHANNEL_1, DMAMUX, &ux_Dma_Parameter);
        DMA_Cmd(DMA_CHANNEL_1, DMAMUX, ENABLE);
       
        DMA_EnableRequest(DMAMUX, DMA_CHANNEL_0);
        DMA_EnableRequest(DMAMUX, DMA_CHANNEL_1);
       
       
        SIM_SCGC6 |= SIM_SCGC6_PDB_MASK;

        PDB_SC_REG(PDB0_BASE_PTR) |= PDB_SC_PDBEN_MASK ;
        PDB_SC_REG(PDB0_BASE_PTR) |= PDB_SC_TRGSEL(0xf) | PDB_SC_CONT_MASK;
        PDB_MOD_REG(PDB0_BASE_PTR) = BSP_BUS_CLOCK / 50 / ADC_SAMPLE_FREQ;
        PDB_IDLY_REG(PDB0_BASE_PTR) = 0;
        PDB_SC_REG(PDB0_BASE_PTR) |= PDB_SC_LDOK_MASK;
        PDB_SC_REG(PDB0_BASE_PTR) |= PDB_SC_DMAEN_MASK;
        PDB_SC_REG(PDB0_BASE_PTR) |= PDB_SC_SWTRIG_MASK;
       
       
        while(1)
        {
            for(long int i = 0; i < 8000000; i ++);
            ADC_DMACmd(ADC0, DISABLE);
            
            for(cnt = 0; cnt < ADC0_TABLE_LEN*(ADC_VALUE_MASK + 1); cnt++)
            {
    #ifdef TEST_DIFF_CH
                //when ADC operate in differential mode, converted 16bit value is in 2's complement value
                if((ux_adc0_value.u16_p_all_value[cnt])&0x8000)
                    buf[cnt] = -(~(ux_adc0_value.u16_p_all_value[cnt])+1);
                else
                    buf[cnt] = ux_adc0_value.u16_p_all_value[cnt];
                printf("%d\n", buf[cnt]);
    #else
                printf("%d\n", ux_adc0_value.u16_p_all_value[cnt]);
    #endif
            }
            ADC_DMACmd(ADC0, ENABLE);
            
            _time_delay(100);
        }   
        //_task_block();
    }  

    /* EOF */










    我知道答案 目前已有7人回答
    郁闷的一个上午
    回复

    使用道具 举报

  • TA的每日心情
    郁闷
    2021-9-6 10:31
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    8

    主题

    57

    帖子

    0

    注册会员

    Rank: 2

    积分
    128
    最后登录
    2021-10-9
     楼主| 发表于 2016-8-30 10:11:06 | 显示全部楼层
    有经验的老师,帮忙指点一下 方向和思路! 谢谢!
    郁闷的一个上午
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    712

    主题

    6371

    帖子

    0

    超级版主

    Rank: 8Rank: 8

    积分
    24873
    最后登录
    2025-7-18
    发表于 2016-8-31 10:42:28 | 显示全部楼层
    MQX 中有2个ADC 驱动  一个 是 source/io/adc,  另一个source/io/lwadc.      我们一般推荐客户使用lwadc
    楼主问的channel 初始化, 楼主可以参考  source/io/adc/kadc/adt_kpdb.c 中  _adt_hw_channel_int函数
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    2021-9-6 10:31
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    8

    主题

    57

    帖子

    0

    注册会员

    Rank: 2

    积分
    128
    最后登录
    2021-10-9
     楼主| 发表于 2016-9-4 09:42:17 | 显示全部楼层
    嗯 嗯   谢谢!
    郁闷的一个上午
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    2021-9-6 10:31
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    8

    主题

    57

    帖子

    0

    注册会员

    Rank: 2

    积分
    128
    最后登录
    2021-10-9
     楼主| 发表于 2016-9-6 10:00:09 | 显示全部楼层
    小恩GG 发表于 2016-8-31 10:42
    MQX 中有2个ADC 驱动  一个 是 source/io/adc,  另一个source/io/lwadc.      我们一般推荐客户使用lwadc
    ...

    小恩GG 版主:
    我现在 在用lwadc的时候,用的是MQX的 example的 程序test.c,程序开始运行 串口就提示:
    ADC Test for FTU_EVK
    Monitoring potentiometer
    LWADC_RESOLUTION               not supported
    LWADC_REFERENCE                not supported
    LWADC_FREQUENCY                not supported
    LWADC_DIVIDER                  not supported
    LWADC_DIFFERENTIAL             not supported
    LWADC_POWER_DOWN               not supported
    LWADC_NUMERATOR                not supported
    LWADC_DENOMINATOR              not supported
    LWADC_FORMAT                   not supported
    LWADC_INPUT_CONVERSION_ENABLE  not supported
    Error, unable to set attribute.
    Monitoring all inputs
    Failed to initialize ADC input Potentiometer
    Monitoring ADC Inputs

    是不是 有哪个地方 还需要配置?
    LWADC_RESOLUTION               not supported
    LWADC_REFERENCE                not supported
    LWADC_FREQUENCY                not supported
    LWADC_DIVIDER                  not supported
    LWADC_DIFFERENTIAL             not supported
    LWADC_POWER_DOWN               not supported
    LWADC_NUMERATOR                not supported
    LWADC_DENOMINATOR              not supported
    LWADC_FORMAT                   not supported

    谢谢!
    郁闷的一个上午
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    2021-9-6 10:31
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    8

    主题

    57

    帖子

    0

    注册会员

    Rank: 2

    积分
    128
    最后登录
    2021-10-9
     楼主| 发表于 2016-9-6 10:16:29 | 显示全部楼层

    这个是例程的源码,用的是LWADC的驱动

    本帖最后由 gdgn526345 于 2016-9-6 10:17 编辑

    /*HEADER**********************************************************************
    *
    * Copyright 2008 Freescale Semiconductor, Inc.
    * Copyright 2011 Embedded Access Inc.
    *
    * This software is owned or controlled by Freescale Semiconductor.
    * Use of this software is governed by the Freescale MQX RTOS License
    * distributed with this Material.
    * See the MQX_RTOS_LICENSE file distributed for more details.
    *
    * Brief License Summary:
    * This software is provided in source form for you to use free of charge,
    * but it is not open source software. You are allowed to use this software
    * but you cannot redistribute it or derivative works of it in source form.
    * The software may be used only in connection with a product containing
    * a Freescale microprocessor, microcontroller, or digital signal processor.
    * See license agreement file for full license terms including other
    * restrictions.
    *****************************************************************************
    *
    * Comments:
    *
    *   This file contains the source for the hello example program.
    *
    *
    *END************************************************************************/

    #include <mqx.h>
    #include <bsp.h>
    #include <fio.h>


    #if ! BSPCFG_ENABLE_IO_SUBSYSTEM
    #error This application requires BSPCFG_ENABLE_IO_SUBSYSTEM defined non-zero in user_config.h. Please recompile BSP with this option.
    #endif


    #ifndef BSP_DEFAULT_IO_CHANNEL_DEFINED
    #error This application requires BSP_DEFAULT_IO_CHANNEL to be not NULL. Please set corresponding BSPCFG_ENABLE_TTYx to non-zero in user_config.h and recompile BSP with this option.
    #endif

    #ifndef BSP_DEFAULT_LWADC_MODULE
    #error This application requires BSP_DEFAULT_LWADC_MODULE to be not defined in the BSP. Please recompile BSP with this option.
    #endif

    #ifndef BSP_ADC_POTENTIOMETER
    #error This application requires BSP_ADC_POTENTIOMETER to be defined in the BSP. Please recompile BSP with this option.
    #endif


    extern void test_task(uint32_t);

    extern const LWADC_INIT_STRUCT BSP_DEFAULT_LWADC_MODULE;

    const TASK_TEMPLATE_STRUCT  MQX_template_list[] =
    {
    /* Task Index,   Function,   Stack,  Priority, Name,     Attributes,    Param,            Time Slice */
        { 1,   test_task, 2000,   8,        "test_task",  MQX_AUTO_START_TASK, 0, 0 },
        { 0 }
    };


    typedef struct adc_demo_struct {
        const char *    name;
        uint32_t         input;
    } ADC_DEMO_STRUCT;

    /* This structure defines the generic ADCs available on this board. The structure will be populated based on
    ** what generic ADCs are defined in the BSP. The generic ADCs currently supported are:
    **  Potentiometer:                  BSP_ADC_POTENTIOMETER
    **  Up to 8 generic ADC inputs:     BSP_ADC_INPUT_0..BSP_ADC_INPUT_7
    **  One TWRPI ADC interface:        BSP_ADC_TWRPI_PINx
    **  Tower primary elevator          BSP_ADC_TWR_AN0..BSP_ADC_TWR_AN7
    **  Tower secondary elevator        BSP_ADC_TWR_AN8..BSP_ADC_TWR_AN13
    **  Core voltage:                   BSP_ADC_VDD_CORE
    **  Temperature:                    BSP_ADC_TEMPERATURE */

    const ADC_DEMO_STRUCT adc_inputs[] = {
            
    #ifdef BSP_ADC_POTENTIOMETER
       {"Potentiometer", BSP_ADC_POTENTIOMETER },
    #endif   
       
    #ifdef BSP_ADC_INPUT_0
       {"Generic input #0", BSP_ADC_INPUT_0 },
    #endif
       
    #ifdef BSP_ADC_INPUT_1
       {"Generic input #1", BSP_ADC_INPUT_1 },
    #endif
       
    #ifdef BSP_ADC_INPUT_2
       {"Generic input #2", BSP_ADC_INPUT_2 },
    #endif
       
    #ifdef BSP_ADC_INPUT_3
       {"Generic input #3", BSP_ADC_INPUT_3 },
    #endif
       
    #ifdef BSP_ADC_INPUT_4
       {"Generic input #4", BSP_ADC_INPUT_4 },
    #endif
       
    #ifdef BSP_ADC_INPUT_5
       {"Generic input #5", BSP_ADC_INPUT_5 },
    #endif
       
    #ifdef BSP_ADC_INPUT_6
       {"Generic input #6", BSP_ADC_INPUT_6 },
    #endif
       
    #ifdef BSP_ADC_INPUT_7
       {"Generic input #7", BSP_ADC_INPUT_7 },
    #endif
       
    #ifdef BSP_ADC_TWRPI_PIN8
       {"TWRPI Pin#8", BSP_ADC_TWRPI_PIN8 },
    #endif               
    #ifdef BSP_ADC_TWRPI_PIN9
       {"TWRPI Pin#9", BSP_ADC_TWRPI_PIN9 },
    #endif               
    #ifdef BSP_ADC_TWRPI_PIN12
       {"TWRPI Pin#12", BSP_ADC_TWRPI_PIN12 },
    #endif               
    #ifdef BSP_ADC_TWRPI_PIN17
       {"TWRPI Pin#17", BSP_ADC_TWRPI_PIN17 },
    #endif               
    #ifdef BSP_ADC_TWRPI_PIN18
       {"TWRPI Pin#18", BSP_ADC_TWRPI_PIN18 },
    #endif               

    #ifdef BSP_ADC_TWR_AN0
       {"Primary Elevator AN0", BSP_ADC_TWR_AN0 },
    #endif               
    #ifdef BSP_ADC_TWR_AN1
       {"Primary Elevator AN1", BSP_ADC_TWR_AN1 },
    #endif               
    #ifdef BSP_ADC_TWR_AN2
       {"Primary Elevator AN2", BSP_ADC_TWR_AN2 },
    #endif               
    #ifdef BSP_ADC_TWR_AN3
       {"Primary Elevator AN3", BSP_ADC_TWR_AN3 },
    #endif               
    #ifdef BSP_ADC_TWR_AN4
       {"Primary Elevator AN4", BSP_ADC_TWR_AN4 },
    #endif               
    #ifdef BSP_ADC_TWR_AN5
       {"Primary Elevator AN5", BSP_ADC_TWR_AN5 },
    #endif               
    #ifdef BSP_ADC_TWR_AN6
       {"Primary Elevator AN6", BSP_ADC_TWR_AN6 },
    #endif               
    #ifdef BSP_ADC_TWR_AN7
       {"Primary Elevator AN7", BSP_ADC_TWR_AN7 },
    #endif               
          
    #ifdef BSP_ADC_TWR_AN8
       {"Secondary Elevator AN8", BSP_ADC_TWR_AN8 },
    #endif               
    #ifdef BSP_ADC_TWR_AN9
       {"Secondary Elevator AN9", BSP_ADC_TWR_AN9 },
    #endif               
    #ifdef BSP_ADC_TWR_AN10
       {"Secondary Elevator AN10", BSP_ADC_TWR_AN10 },
    #endif               

    #ifdef BSP_ADC_TWR_AN11
       {"Secondary Elevator AN11", BSP_ADC_TWR_AN11 },
    #endif               
    #ifdef BSP_ADC_TWR_AN12
       {"Secondary Elevator AN12", BSP_ADC_TWR_AN12 },
    #endif               
    #ifdef BSP_ADC_TWR_AN13
       {"Secondary Elevator AN13", BSP_ADC_TWR_AN13 },
    #endif               

    #ifdef BSP_ADC_VDD_CORE
       {"Core VDD", BSP_ADC_VDD_CORE },
    #endif               
    #ifdef BSP_ADC_TEMPERATURE
       {"Temperature", BSP_ADC_TEMPERATURE },
    #endif               

    };



    static void print_lwadc_attribute( LWADC_STRUCT_PTR lwadc_ptr, LWADC_ATTRIBUTE attribute, const char * name)
    {
        uint32_t value;
       
        if (_lwadc_get_attribute(lwadc_ptr,attribute,&value)) {
            printf("%-30s = 0x%08x (%d)\n", name,value,value);
        } else {
            printf("%-30s not supported\n", name);
        }
    }

    #define PRINT_LWADC_ATTRIBUTE(p,x) print_lwadc_attribute(p,x,#x)

    static void print_all_lwadc_attributes( LWADC_STRUCT_PTR lwadc_ptr)
    {
        PRINT_LWADC_ATTRIBUTE(lwadc_ptr, LWADC_RESOLUTION);
        PRINT_LWADC_ATTRIBUTE(lwadc_ptr, LWADC_REFERENCE);
        PRINT_LWADC_ATTRIBUTE(lwadc_ptr, LWADC_FREQUENCY);
        PRINT_LWADC_ATTRIBUTE(lwadc_ptr, LWADC_DIVIDER);
        PRINT_LWADC_ATTRIBUTE(lwadc_ptr, LWADC_DIFFERENTIAL);
        PRINT_LWADC_ATTRIBUTE(lwadc_ptr, LWADC_POWER_DOWN);
        PRINT_LWADC_ATTRIBUTE(lwadc_ptr, LWADC_NUMERATOR);
        PRINT_LWADC_ATTRIBUTE(lwadc_ptr, LWADC_DENOMINATOR);
        PRINT_LWADC_ATTRIBUTE(lwadc_ptr, LWADC_FORMAT);
        PRINT_LWADC_ATTRIBUTE(lwadc_ptr, LWADC_INPUT_CONVERSION_ENABLE);
    }


    static void monitor_potentiometer(uint32_t input, uint32_t max_range)
    {
        LWADC_STRUCT    potentiometer;
        LWADC_VALUE     percent, last = MAX_UINT_32, min_percent = 100, max_percent = 0;
        uint32_t         resolution, reference;
       
        printf("Monitoring potentiometer\n");

        /* Initialize an LWADC_STRUCT for the potentiometer  */
        _lwadc_init_input(&potentiometer,input);
       
        /* Print out all the attributes associated with it. Some will be device-wide attributes */
        print_all_lwadc_attributes(&potentiometer);
       
        /* We want to change the default scaling of the potentiometer to return a percent instead of milli-volts.
        ** We change the numerator to reflect the range, and the denominator to reflect the max potentiometer value. */
        if (!_lwadc_set_attribute(&potentiometer,LWADC_NUMERATOR,100)) {
            printf("Error, unable to set attribute.\n");
            return;
        }
        if (!_lwadc_get_attribute(&potentiometer,LWADC_RESOLUTION,&resolution)) {
            printf("Error, unable to get attribute.\n");
            return;
        }
        if (!_lwadc_get_attribute(&potentiometer,LWADC_REFERENCE,&reference)) {
            printf("Error, unable to get attribute.\n");
            return;
        }
        if (!_lwadc_set_attribute(&potentiometer,LWADC_DENOMINATOR,resolution*max_range/reference)) {
            printf("Error, unable to set attribute.\n");
            return;
        }

        /* Print out what we changed.*/
        PRINT_LWADC_ATTRIBUTE(&potentiometer, LWADC_NUMERATOR);
        PRINT_LWADC_ATTRIBUTE(&potentiometer, LWADC_DENOMINATOR);

        printf("Rotate potentiometer. Test will run until readings range from  10%% to 90%% \n");
       
        while ((min_percent>10) || (max_percent<90)) {
            /* Request 10 consecutive readings, averaged and scaled. */
            _lwadc_read_average(&potentiometer, 10, &percent);
            
            /* If it is different, print it. */
            if (percent != last) {
                printf("potentiometer = %3d\r",percent);
                last=percent;
                if (percent<min_percent) min_percent=percent;
                if (percent>max_percent) max_percent=percent;
            }
        }
        printf("\n");
    }

    static void monitor_all_inputs(void)
    {
        LWADC_STRUCT_PTR    lwadc_inputs;
        LWADC_VALUE_PTR     last;
        LWADC_VALUE         i,scaled, raw, delta, max_delta = 160;

        printf("Monitoring all inputs\n");

        lwadc_inputs = (LWADC_STRUCT_PTR) _mem_alloc_zero(ELEMENTS_OF(adc_inputs)*sizeof(LWADC_STRUCT));
        last         = (LWADC_VALUE_PTR)  _mem_alloc_zero(ELEMENTS_OF(adc_inputs)*sizeof(LWADC_VALUE));
       
        if ((lwadc_inputs == NULL) || (last==NULL)) {
            printf("Error, Insufficient memory to run full test\n.");
            _task_block();
        }
       
        for (i=0;i<ELEMENTS_OF(adc_inputs);i++) {
            /* Set last value to a value out of range of the ADC. */
            last = MAX_UINT_32;
            if ( !_lwadc_init_input(&lwadc_inputs,adc_inputs.input) ) {
                /* Failed to initialize this input. We will end up failing the reads below as well. */
                printf("Failed to initialize ADC input %s\n",adc_inputs.name);
            }
        }
       
        printf("Monitoring ADC Inputs\n");
        while (1) {
            for (i=0;i<ELEMENTS_OF(adc_inputs);i++) {
                /* This waits until a new conversion is read on the channel */
                if (_lwadc_wait_next(&lwadc_inputs)) {
                    if (_lwadc_read(&lwadc_inputs, &scaled) &&
                        _lwadc_read_raw(&lwadc_inputs, &raw)) {
                        
                        /* Obtained data, is the change significant enough to display? */
                        delta = (raw>last)?raw-last:last-raw;
                        if (delta > max_delta) {
                            printf("%-30s = %04x (%d mv)\n",adc_inputs.name, raw,scaled);
                            last=raw;
                        }
                    }
                }
            }
        }
    }

    void test_task(uint32_t initial_data)
    {
        printf("\n\n\nADC Test for %s\n",BSP_NAME);

        _lwadc_init(&BSP_DEFAULT_LWADC_MODULE);

        #ifdef BSP_ADC_POTENTIOMETER
            monitor_potentiometer(BSP_ADC_POTENTIOMETER,BSP_ADC_POTENTIOMETER_MAX);
        #endif
        monitor_all_inputs();
    }

    /* EOF */
    郁闷的一个上午
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    郁闷
    2021-9-6 10:31
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    8

    主题

    57

    帖子

    0

    注册会员

    Rank: 2

    积分
    128
    最后登录
    2021-10-9
     楼主| 发表于 2016-9-6 11:57:57 | 显示全部楼层
    问题找到了:BSP_ADC_POTENTIOMETER定义的问题,这个是ADC通道
    Monitoring potentiometer
    LWADC_RESOLUTION               = 0x00010000 (65536)
    LWADC_REFERENCE                = 0x00000ce4 (3300)
    LWADC_FREQUENCY                = 0x007a1200 (8000000)
    LWADC_DIVIDER                  = 0x00000001 (1)
    LWADC_DIFFERENTIAL             = 0x00000000 (0)
    LWADC_POWER_DOWN               = 0x00000001 (1)
    LWADC_NUMERATOR                = 0x00000ce4 (3300)
    LWADC_DENOMINATOR              = 0x00010000 (65536)
    LWADC_FORMAT                   = 0x00000000 (0)
    LWADC_INPUT_CONVERSION_ENABLE  = 0x00000000 (0)
    LWADC_NUMERATOR                = 0x00000064 (100)
    LWADC_DENOMINATOR              = 0x00010000 (65536)
    Rotate potentiometer. Test will run until readings range from  10% to 90%
    potentiometer = 100


    郁闷的一个上午
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2019-9-17 13:22
  • 签到天数: 238 天

    连续签到: 1 天

    [LV.7]常住居民III

    30

    主题

    905

    帖子

    6

    金牌会员

    Rank: 6Rank: 6

    积分
    2251
    最后登录
    2024-10-8
    发表于 2017-3-6 16:48:18 | 显示全部楼层
    gdgn526345 发表于 2016-9-6 11:57
    问题找到了:BSP_ADC_POTENTIOMETER定义的问题,这个是ADC通道
    Monitoring potentiometer
    LWADC_RESOLUTION ...

    最近也在研究MQX的片内adc,我也有和你一样的疑惑,这个ADC通道该则呢配置呢?
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

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

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

    GMT+8, 2025-7-20 01:43 , Processed in 0.103225 second(s), 28 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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