[开发工具]

【PIC-IoT WA开发板】+ADC采集光亮

[复制链接]
822|1
手机看帖
扫描二维码
随时随地手机跟帖
qjp1988113|  楼主 | 2020-11-2 10:31 | 显示全部楼层 |阅读模式
本帖最后由 qjp1988113 于 2020-11-2 10:38 编辑

今天有空,试一下PIC-IoT WA开发板上PIC24FJ128的ADC功能,我们测试板上的光敏传感器在不同亮度下的分压。
电路如下:
C1.png
PIC24FJ128的ADC支持10BIt/12BIT的采样模式。我们这里用12BIT,软件触发非扫描的形式采样,毕竟就用了一个通道么。
采样速度最高200K/S,普通也够用了。
C2.png
下面进行代码的配置:
C3.png
C4.png
生成的ADC的程序:
C文件:
/**
  Section: Included Files
*/
#include "adc1.h"

/**
  Section: File Specific Functions
*/

// ADC1 Default Interrupt Handler
static void (*ADC1_DefaultInterruptHandler)(void) = NULL;

/**
  Section: Driver Interface
*/

void ADC1_Initialize (void)
{
    // ASAM enabled; DMABM disabled; ADSIDL disabled; DONE disabled; DMAEN disabled; FORM Absolute decimal result, unsigned, right-justified; SAMP disabled; SSRC Internal counter ends sampling and starts conversion; MODE12 12-bit; ADON enabled;
    AD1CON1 = 0x8474;
    // CSCNA disabled; NVCFG0 AVSS; PVCFG AVDD; ALTS disabled; BUFM disabled; SMPI Generates interrupt after completion of every sample/conversion operation; BUFREGEN disabled;
    AD1CON2 = 0x00;
    // SAMC 31; EXTSAM disabled; PUMPEN disabled; ADRC RC clock; ADCS 0;
    AD1CON3 = 0x9F00;
    // CH0SA AN0; CH0SB AN0; CH0NB AVSS; CH0NA AVSS;
    AD1CHS = 0x00;
    // CSS30 disabled; CSS29 disabled; CSS28 disabled;
    AD1CSSH = 0x00;
    // CSS9 disabled; CSS8 disabled; CSS7 disabled; CSS6 disabled; CSS5 disabled; CSS4 disabled; CSS3 disabled; CSS2 disabled; CSS15 disabled; CSS1 disabled; CSS14 disabled; CSS0 disabled; CSS13 disabled; CSS12 disabled; CSS11 disabled; CSS10 disabled;
    AD1CSSL = 0x00;
    // DMABL Allocates 1 word of buffer to each analog input;
    AD1CON4 = 0x00;
    // ASEN disabled; WM Legacy operation; ASINT No interrupt; CM Less Than mode; BGREQ disabled; CTMREQ disabled; LPEN disabled;
    AD1CON5 = 0x00;
    // CHH9 disabled; CHH8 disabled; CHH7 disabled; CHH6 disabled; CHH5 disabled; CHH4 disabled; CHH3 disabled; CHH2 disabled; CHH1 disabled; CHH0 disabled; CHH11 disabled; CHH10 disabled; CHH13 disabled; CHH12 disabled;
    AD1CHITL = 0x00;
    // CTMEN30 disabled; CTMEN29 disabled; CTMEN28 disabled;
    AD1CTMENH = 0x00;
    // CTMEN5 disabled; CTMEN6 disabled; CTMEN7 disabled; CTMEN8 disabled; CTMEN9 disabled; CTMEN12 disabled; CTMEN13 disabled; CTMEN10 disabled; CTMEN0 disabled; CTMEN11 disabled; CTMEN1 disabled; CTMEN2 disabled; CTMEN3 disabled; CTMEN4 disabled; CTMEN14 disabled; CTMEN15 disabled;
    AD1CTMENL = 0x00;
    // AD1RESDMA 0;
    AD1RESDMA = 0x00;
    // VBGEN3 disabled; VBGEN2 disabled; VBGEN1 disabled;
    ANCFG = 0x00;
   
    //Assign Default Callbacks
    ADC1_SetInterruptHandler(&ADC1_CallBack);
   

}

void __attribute__ ((weak)) ADC1_CallBack(void)
{

}

void ADC1_SetInterruptHandler(void* handler)
{
    ADC1_DefaultInterruptHandler = handler;
}

void __attribute__ ((weak)) ADC1_Tasks ( void )
{
    if(IFS0bits.AD1IF)
    {
        if(ADC1_DefaultInterruptHandler)
        {
            ADC1_DefaultInterruptHandler();
        }

        // clear the ADC interrupt flag
        IFS0bits.AD1IF = false;
    }
}

/*******************************************************************************

  !!! Deprecated Definitions and APIs !!!
  !!! These functions will not be supported in future releases !!!

*******************************************************************************/
void ADC1_Start(void)
{
   AD1CON1bits.SAMP = 1;
}

void ADC1_Stop(void)
{
   AD1CON1bits.SAMP = 0;
}

uint16_t ADC1_ConversionResultBufferGet(uint16_t *buffer)
{
    int count;
    uint16_t *ADC16Ptr;
    uint16_t sampleCount = AD1CON2bits.SMPI;

    ADC16Ptr = (uint16_t *)&(ADC1BUF0);

    for(count=0;count<=sampleCount;count++)
    {
        buffer[count] = (uint16_t)*ADC16Ptr;
        ADC16Ptr++;
    }
    return count;
}


/**
  End of File
*/
h文件:
#ifndef _ADC1_H
#define _ADC1_H

/**
  Section: Included Files
*/

#include <xc.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

#ifdef __cplusplus  // Provide C++ Compatibility

    extern "C" {

#endif

/**
  Section: Data Types
*/

/** Scan Selected Macro Definition

[url=home.php?mod=space&uid=267864]@summary[/url]
   Defines the scan option selection done for the shared channels.

@Description
   This macro defines the scan option selection done for the shared channels.

Remarks:
   None
*/
#define ADC1_SCAN_MODE_SELECTED false

/** ADC1 Channel Definition

[url=home.php?mod=space&uid=267864]@summary[/url]
   Defines the channels selected.

@Description
   This routine defines the channels that are available for the module to use.

Remarks:
   None
*/
typedef enum
{
    Light_In,//Channel Name:AN8   Assigned to:Shared Channel
    CHANNEL_CTMU_temperature_sensor_input,//Channel Name:CTMU temperature sensor input   Assigned to:Shared Channel
    CHANNEL_CTMU,//Channel Name:CTMU   Assigned to:Shared Channel
    CHANNEL_VBG,//Channel Name:VBG   Assigned to:Shared Channel
    CHANNEL_AVSS,//Channel Name:AVSS   Assigned to:Shared Channel
    CHANNEL_AVDD,//Channel Name:AVDD   Assigned to:Shared Channel
} ADC1_CHANNEL;

/**
  Section: Interface Routines
*/

/**
  @Summary
    Initializes ADC1 module.

  @Description
    This routine initializes ADC1 module, using the given initialization data.
    This routine must be called before any other ADC routine is called.

  @Preconditions
    None.

  @Param
    None.

  @Returns
    None

  @Example
    <code>
        int conversion,i=0;
        ADC1_Initialize();

        ADC1_Enable();
        ADC1_ChannelSelect(channel);
        ADC1_SoftwareTriggerEnable();
        //Provide Delay
        for(i=0;i <1000;i++)
        {
        }
        ADC1_SoftwareTriggerDisable();
        while(!ADC1_IsConversionComplete(channel));
        conversion = ADC1_ConversionResultGet(channel);
        ADC1_Disable();
    </code>
*/
void ADC1_Initialize (void);

/**
  @Summary
    Enables the ADC1 module.

  @Description
    This routine is used to enable the ADC1 module.

  @Preconditions
    ADC1_Initialize function should have been called
    before calling this function.

  @Param
    None.

  @Returns
    None.

  @Example
    <code>
        int conversion,i=0;
        ADC1_Initialize();

        ADC1_Enable();
        ADC1_ChannelSelect(channel);
        ADC1_SoftwareTriggerEnable();
        //Provide Delay
        for(i=0;i <1000;i++)
        {
        }
        ADC1_SoftwareTriggerDisable();
        while(!ADC1_IsConversionComplete(channel));
        conversion = ADC1_ConversionResultGet(channel);
        ADC1_Disable();
    </code>
*/
inline static void ADC1_Enable(void)
{
   AD1CON1bits.ADON = 1;
}

/**
  @Summary
    Disables the ADC1 module.

  @Description
    This routine is used to disable the ADC1 module.

  @Preconditions
    ADC1_Initialize function should have been called
    before calling this function.

  @Param
    None.

  @Returns
    None.

  @Example
    <code>
        int conversion,i=0;
        ADC1_Initialize();

        ADC1_Enable();
        ADC1_ChannelSelect(channel);
        ADC1_SoftwareTriggerEnable();
        //Provide Delay
        for(i=0;i <1000;i++)
        {
        }
        ADC1_SoftwareTriggerDisable();
        while(!ADC1_IsConversionComplete(channel));
        conversion = ADC1_ConversionResultGet(channel);
        ADC1_Disable();
    </code>
*/
inline static void ADC1_Disable(void)
{
   AD1CON1bits.ADON = 0;
}

/**
  @Summary
    Starts sampling manually.

  @Description
    This routine is used to start sampling manually.

  @Preconditions
    ADC1_Initialize function should have been called
    before calling this function.

  @Param
    None.

  @Returns
    None.

  @Example
    <code>
        int conversion,i=0;
        ADC1_Initialize();

        ADC1_Enable();
        ADC1_ChannelSelect(channel);
        ADC1_SoftwareTriggerEnable();
        //Provide Delay
        for(i=0;i <1000;i++)
        {
        }
        ADC1_SoftwareTriggerDisable();
        while(!ADC1_IsConversionComplete(channel));
        conversion = ADC1_ConversionResultGet(channel);
        ADC1_Disable();
    </code>
*/

inline static void ADC1_SoftwareTriggerEnable(void)
{
   AD1CON1bits.SAMP = 1;
}

/**
  @Summary
    Stops sampling manually.

  @Description
    This routine is used to stop the sampling manually.

  @Preconditions
    ADC1_Initialize() function should have been
    called before calling this function.

  @Param
    None.

  @Returns
    None.

  @Example
    <code>
        int conversion,i=0;
        ADC1_Initialize();

        ADC1_Enable();
        ADC1_ChannelSelect(channel);
        ADC1_SoftwareTriggerEnable();
        //Provide Delay
        for(i=0;i <1000;i++)
        {
        }
        ADC1_SoftwareTriggerDisable();
        while(!ADC1_IsConversionComplete(channel));
        conversion = ADC1_ConversionResultGet(channel);
        ADC1_Disable();
    </code>
*/
inline static void ADC1_SoftwareTriggerDisable(void)
{
   AD1CON1bits.SAMP = 0;
}

/**
  @Summary
    Allows selection of a channel for conversion.

  @Description
    This routine is used to select desired channel for conversion.
  
  @Preconditions
    ADC1_Initialize() function should have been
    called before calling this function.

  @Param
    channel - Channel for conversion

  @Returns
    None
  
  @Example
    <code>
        int conversion,i=0;
        ADC1_Initialize();

        ADC1_Enable();
        ADC1_ChannelSelect(channel);
        ADC1_SoftwareTriggerEnable();
        //Provide Delay
        for(i=0;i <1000;i++)
        {
        }
        ADC1_SoftwareTriggerDisable();
        while(!ADC1_IsConversionComplete(channel));
        conversion = ADC1_ConversionResultGet(channel);
        ADC1_Disable();
    </code>
*/
inline static void ADC1_ChannelSelect( ADC1_CHANNEL channel )
{
    switch(channel)
    {
        case Light_In:
                AD1CHSbits.CH0SA= 0x8;
                break;
        case CHANNEL_CTMU_temperature_sensor_input:
                AD1CHSbits.CH0SA= 0xE;
                break;
        case CHANNEL_CTMU:
                AD1CHSbits.CH0SA= 0xF;
                break;
        case CHANNEL_VBG:
                AD1CHSbits.CH0SA= 0x1C;
                break;
        case CHANNEL_AVSS:
                AD1CHSbits.CH0SA= 0x1D;
                break;
        case CHANNEL_AVDD:
                AD1CHSbits.CH0SA= 0x1E;
                break;
        default:
                break;
    }
}

/**
  @Summary
    Returns the conversion value for the channel selected.

  @Description
    This routine is used to get the analog to digital converted value for a
    specific channel.

  @Preconditions
    This routine returns the conversion value only after the conversion is complete.
    Conversion completion status can be checked using ADC1_IsConversionComplete(channel)
    routine.

  @Param
    channel - Selected channel
   
  @Returns
   Returns the analog to digital converted value
  
  @Example
    <code>
        int conversion,i=0;
        ADC1_Initialize();

        ADC1_Enable();
        ADC1_ChannelSelect(channel);
        ADC1_SoftwareTriggerEnable();
        //Provide Delay
        for(i=0;i <1000;i++)
        {
        }
        ADC1_SoftwareTriggerDisable();
        while(!ADC1_IsConversionComplete(channel));
        conversion = ADC1_ConversionResultGet(channel);
        ADC1_Disable();
    </code>
*/
inline static uint16_t ADC1_ConversionResultGet( ADC1_CHANNEL channel )
{
    uint16_t result;

    result = ADC1BUF0;

    return result;
}

/**
  @Summary
    Returns the status of conversion.

  @Description
    This routine is used to determine if conversion is completed. When conversion
    is complete the routine returns true otherwise false.

  @Preconditions
    ADC1_Initialize() function should have been
    called before calling this function.

  @Param
    channel - Selected channel

  @Returns
    true - Conversion is complete.
    false - Conversion is not complete.
  
  @Example
    <code>
        int conversion,i=0;
        ADC1_Initialize();

        ADC1_Enable();
        ADC1_ChannelSelect(channel);
        ADC1_SoftwareTriggerEnable();
        //Provide Delay
        for(i=0;i <1000;i++)
        {
        }
        ADC1_SoftwareTriggerDisable();
        while(!ADC1_IsConversionComplete(channel));
        conversion = ADC1_ConversionResultGet(channel);
        ADC1_Disable();
    </code>
*/
inline static bool ADC1_IsConversionComplete(ADC1_CHANNEL channel)
{
    bool status;

    status = AD1CON1bits.DONE;

    return status;
}

/**
  @Summary
    Enables interrupts.

  @Description
    This routine is used to enable the ADC1 interrupt.

  @Preconditions
    None.

  @Param
    None.

  @Returns
    None.

  @Example
    <code>
        ADC1_InterruptEnable();
    </code>
*/
inline static void ADC1_InterruptEnable(void)
{
    IEC0bits.AD1IE = 1;
}

/**
  @Summary
    Disables interrupts.

  @Description
    This routine is used to disable the ADC1 interrupt.

  @Preconditions
    None.

  @Param
    None.

  @Returns
    None.

  @Example
    <code>
        ADC1_InterruptDisable();
    </code>
*/
inline static void ADC1_InterruptDisable(void)
{
    IEC0bits.AD1IE = 0;
}

/**
  @Summary
    Clears interrupt flag

  @Description
    This routine is used to clear the interrupt flag manually.

  @Preconditions
    None.

  @Param
    None.

  @Returns
    None.

  @Example
    <code>
        ADC1_InterruptFlagClear();
    </code>
*/
inline static void ADC1_InterruptFlagClear(void)
{
    IFS0bits.AD1IF = 0;
}

/**
  @Summary
    Allows selection of priority for interrupt.

  @Description
    This routine is used to select desired priority for interrupt.
  
  @Preconditions
    None.

  @Param
    None.

  @Returns
    None.

  @Example
    <code>
        uint16_t priorityValue;
        priorityValue = 0x002;

        ADC1_InterruptPrioritySet(priorityValue);
    </code>
*/
inline static void ADC1_InterruptPrioritySet( uint16_t priorityValue )
{
    IPC3bits.AD1IP = 0x7 & priorityValue;
}

/**
  @Summary
    Callback for ADC1.

  @Description
    This routine is callback for ADC1
  
  @Preconditions
    None.

  @Param
    None.

  @Returns
    None

  [url=home.php?mod=space&uid=389923]@example[/url]
    <code>   
        ADC1_CallBack();
    </code>
*/
void ADC1_CallBack(void);

/**
  @Summary
    Assigns a function pointer with a callback address.

  @Description
    This routine assigns a function pointer with a callback address.

  @Preconditions
    None.

  @Param
    Address of the callback routine.

  @Returns
    None

  [url=home.php?mod=space&uid=389923]@example[/url]
    <code>
        ADC1_SetInterruptHandler(&ADC1_CallBack);
    </code>
*/
void ADC1_SetInterruptHandler(void* handler);


/**
  [url=home.php?mod=space&uid=267864]@summary[/url]               
    Polled implementation

  @Description
    This routine is used to implement the tasks for polled implementations.
  
  @Preconditions
    ADC1_Initialize() function should have been
    called before calling this function.

  @Param
    None

  @Returns
    None

  @Example
    <code>   
        ADC1_Tasks();
    </code>
*/
void ADC1_Tasks(void);

/*******************************************************************************

  !!! Deprecated Definitions and APIs !!!
  !!! These functions will not be supported in future releases !!!

*******************************************************************************/
/**
  @Summary
    Starts sampling manually.

  @Description
    This routine is used to start the sampling manually.

  @Preconditions
    ADC1_Initialize function should have been called
    before calling this function.

  @Param
    None.

  @Returns
    None.

  @Example
    None.
*/
void __attribute__((deprecated("\nThis will be removed in future MCC releases. \nUse ADC1_SoftwareTriggerEnable instead."))) ADC1_Start(void);

/**
  @Summary
    Stops sampling manually.

  @Description
    This routine is used to stop the sampling manually before conversion
    is triggered.

  @Preconditions
    ADC1_Initialize() function should have been
    called before calling this function.

  @Param
    None.

  @Returns
    None.

  @Example
    None.
*/
void __attribute__((deprecated("\nThis will be removed in future MCC releases. \nUse ADC1_SoftwareTriggerDisable instead."))) ADC1_Stop(void);

/**
  @Summary
    Gets the buffer loaded with conversion results.

  @Description
    This routine is used to get the analog to digital converted values in a
    buffer. This routine gets converted values from multiple channels.

  @Preconditions
    This routine returns the buffer containing the conversion values only after
    the conversion is complete. Completion status conversion can be checked using
    ADC1_IsConversionComplete() routine.

  @Param
    None.

  @Returns
    Returns the count of the buffer containing the conversion values.

  @Example
    None.
*/
uint16_t __attribute__((deprecated("\nThis will be removed in future MCC releases. \nUse ADC1_ConversionResultGet instead."))) ADC1_ConversionResultBufferGet(uint16_t *buffer);

#ifdef __cplusplus  // Provide C++ Compatibility

    }

#endif

#endif //_ADC1_H
   
/**
End of File
*/
h文件里老是插入一些函数的写法,又不要define,起码看起来归类好些。但是用肯定是正常的。
新建light_in.c和light_in.h
light_in.c:
#include "light_in.h"


//NEW ADD
uint16_t ADC1_GetConversion(ADC1_CHANNEL channel)
{
    int conversion,i=0;

    ADC1_Initialize();
   
    //ADC1_Enable();
    ADC1_ChannelSelect(channel);
    ADC1_SoftwareTriggerEnable();
   
    //Provide Delay
    for(i=0;i <1000;i++)
    {
    }
    ADC1_SoftwareTriggerDisable();
    while (!ADC1_IsConversionComplete(channel))
    {
    }
    conversion = ADC1_ConversionResultGet(channel);
    //ADC1_Disable();
    return conversion;   
}

uint16_t SENSORS_getLightValue(void)
{
    return ADC1_GetConversion(LIGHT_SENSOR_ADC_CHANNEL);
}
light_in.h:
/* 
* File:   light_in.h
* Author: Administrator
*
* Created on November 2, 2020, 8:50 AM
*/

#ifndef LIGHT_IN_H
#define        LIGHT_IN_H

#ifdef        __cplusplus
extern "C" {
#endif

#include "../mcc_generated_files/adc1.h"

#define LIGHT_SENSOR_ADC_CHANNEL        Light_In

uint16_t ADC1_GetConversion(ADC1_CHANNEL channel);
uint16_t SENSORS_getLightValue(void);

#ifdef        __cplusplus
}
#endif

#endif        /* LIGHT_IN_H */

在mian函数while循环里调用:
int nowLight=0;
nowLight= SENSORS_getLightValue();
printf("the light is : %d\r\n",nowLight);
编译下载,查看串口输出:
C5.png
有±20个最小单位的跳到,效果还是不错的。
本次实验比较简单,但ADC配置那块还得注意些,ADC就到这。



  

使用特权

评论回复
FYLZLXD| | 2020-11-2 19:24 | 显示全部楼层
测试数据又交叉, 不能分开, 楼主解决了吗? 什么问题导致的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

111

主题

627

帖子

2

粉丝