本帖最后由 qjp1988113 于 2020-11-2 10:38 编辑
今天有空,试一下PIC-IoT WA开发板上PIC24FJ128的ADC功能,我们测试板上的光敏传感器在不同亮度下的分压。
电路如下:
PIC24FJ128的ADC支持10BIt/12BIT的采样模式。我们这里用12BIT,软件触发非扫描的形式采样,毕竟就用了一个通道么。
采样速度最高200K/S,普通也够用了。
下面进行代码的配置:
生成的ADC的程序:
C文件:
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);
编译下载,查看串口输出:
有±20个最小单位的跳到,效果还是不错的。
本次实验比较简单,但ADC配置那块还得注意些,ADC就到这。
|