从原理图看到有6路模拟输入,分别对应
P10.0~P10.5, VREF为模拟参考电压。
使用的是MAX4466的MIC,接到ADC0,如下图所示
(资料图片仅供参考)
配置模拟采集引脚代码Adc.c
#include "cy_pdl.h"#include "cyhal.h"#include "cybsp.h"#include "cy_retarget_io.h"#define VPLUS_CHANNEL_0 (P10_0)/* Conversion factor */#define MICRO_TO_MILLI_CONV_RATIO (1000u)/* Acquistion time in nanosecond */#define ACQUISITION_TIME_NS (116680u)/* ADC Scandelay in millisecond */#define ADC_SCAN_DELAY_MS (200u)/******************************************************************************** Enumerated Types*******************************************************************************//* ADC Channel constants*/enum ADC_CHANNELS{ CHANNEL_0 = 0, NUM_CHANNELS} adc_channel;/******************************************************************************** Global Variables*******************************************************************************//* ADC Object */cyhal_adc_t adc_obj;/* ADC Channel 0 Object */cyhal_adc_channel_t adc_chan_0_obj;/* Default ADC configuration */const cyhal_adc_config_t adc_config = { .continuous_scanning=false, // Continuous Scanning is disabled .average_count=1, // Average count disabled .vref=CYHAL_ADC_REF_VDDA, // VREF forSingle ended channel set to VDDA .vneg=CYHAL_ADC_VNEG_VSSA, // VNEG for Single ended channel set to VSSA .resolution = 12u, // 12-bit resolution .ext_vref = NC, // No connection .bypass_pin = NC }; // No connection/* Asynchronous read complete flag, used in Event Handler */staticbool async_read_complete = true;#define NUM_SCAN (1000)#define NUM_CHANNELS (1)/* Variable to store results from multiple channels during asynchronous read*/int32_t result_arr[NUM_CHANNELS * NUM_SCAN] = {0};static void adc_event_handler(void* arg, cyhal_adc_event_t event){ if(0u != (event & CYHAL_ADC_ASYNC_READ_COMPLETE)) { /* Set async read complete flag to true */ async_read_complete = true; }}int adc_init(void){ /* Variable to capture return value of functions */ cy_rslt_t result; /* Initialize ADC. The ADC block which can connect to the channel 0 input pin is selected */ result = cyhal_adc_init(&adc_obj, VPLUS_CHANNEL_0, NULL); if(result != CY_RSLT_SUCCESS) { printf("ADC initialization failed. Error: %ld\\n", (long unsigned int)result); CY_ASSERT(0); } /* ADC channel configuration */ const cyhal_adc_channel_config_t channel_config = { .enable_averaging = false, // Disable averaging for channel .min_acquisition_ns = ACQUISITION_TIME_NS, // Minimum acquisition time set to 1us .enabled = true }; // Sample this channel when ADC performs a scan /* Initialize a channel 0 and configure it to scan the channel 0 input pin in single ended mode. */ result = cyhal_adc_channel_init_diff(&adc_chan_0_obj, &adc_obj, VPLUS_CHANNEL_0, CYHAL_ADC_VNEG, &channel_config); if(result != CY_RSLT_SUCCESS) { printf("ADC first channel initialization failed. Error: %ld\\n", (long unsigned int)result); CY_ASSERT(0); } /* Register a callback to handle asynchronous read completion */ cyhal_adc_register_callback(&adc_obj, &adc_event_handler, result_arr); /* Subscribe to the async read complete event to process the results */ cyhal_adc_enable_event(&adc_obj, CYHAL_ADC_ASYNC_READ_COMPLETE, CYHAL_ISR_PRIORITY_DEFAULT, true); printf("ADC is configured in multichannel configuration.\\r\\n\\n"); printf("Channel 0 is configured in single ended mode, connected to the \\r\\n"); printf("channel 0 input pin. Provide input voltage at the channel 0 input pin \\r\\n"); return 0;}int adc_samp(void){ /* Variable to capture return value of functions */ cy_rslt_t result; /* Variable to store ADC conversion result from channel 0 */ int32_t adc_result_0 = 0; /* Clear async read complete flag */ async_read_complete = false; /* Initiate an asynchronous read operation. The event handler will be called * when it is complete. */ memset(result_arr,0,sizeof(result_arr)); cyhal_gpio_write_internal(CYBSP_USER_LED,true); result = cyhal_adc_read_async_uv(&adc_obj, NUM_SCAN, result_arr); if(result != CY_RSLT_SUCCESS) { printf("ADC async read failed. Error: %ld\\n", (long unsigned int)result); CY_ASSERT(0); } while(async_read_complete == false); cyhal_gpio_write_internal(CYBSP_USER_LED,false); /* * Read data from result list, input voltage in the result list is in * microvolts. Convert it millivolts and print input voltage * */ for(int i=0; i< NUM_SCAN; i++) { adc_result_0 = result_arr[i] / MICRO_TO_MILLI_CONV_RATIO; printf("/*%4ld*/\\r\\n", (long int)adc_result_0); } return 0;}
Adc.h
#ifndef ADC_H#define ADC_Hint adc_init(void);int adc_samp(void);#endif
Main.c调用
adc_init();
adc_samp();
时钟源时钟源是100Mhz,12分频=8.33M,满足1.8MHz~18MHz之间的要求
默认是按照8M配置
采样时间采样前后翻转LED用示波器测量时间
int adc_samp(void){ /* Variable to capture return value of functions */ cy_rslt_t result; /* Variable to store ADC conversion result from channel 0 */ int32_t adc_result_0 = 0; /* Clear async read complete flag */ async_read_complete = false; /* Initiate an asynchronous read operation. The event handler will be called * when it is complete. */ memset(result_arr,0,sizeof(result_arr)); cyhal_gpio_write_internal(CYBSP_USER_LED,true); result = cyhal_adc_read_async_uv(&adc_obj, NUM_SCAN, result_arr); if(result != CY_RSLT_SUCCESS) { printf("ADC async read failed. Error: %ld\\n", (long unsigned int)result); CY_ASSERT(0); } while(async_read_complete == false); cyhal_gpio_write_internal(CYBSP_USER_LED,false); /* * Read data from result list, input voltage in the result list is in * microvolts. Convert it millivolts and print input voltage * */ for(int i=0; i< NUM_SCAN; i++) { adc_result_0 = result_arr[i] / MICRO_TO_MILLI_CONV_RATIO; printf("/*%4ld*/\\r\\n", (long int)adc_result_0); } return 0;}
采样1000次,分别设置采样时间为2uS和1uS对比。
#define ACQUISITION_TIME_NS (2000u)
10.28mS
#define ACQUISITION_TIME_NS (1000u)
9.32mS
10.28-9.32=0.96mS 1000次约1mS,1次刚好是1uS。
而1000次除去采样时间其他时间为8.32mS,即一次8.32uS。
因为前面设置了时钟为8.33MHz, 从前面时序一节可以看到,除去采样时间,其他转换时间等需要14个CLK,所以需要14/8.33uS=1.7uS. 剩余的8.32-1.7为数据搬运,软件处理等时间。
采样值正确性1.545V和示波器采集为1.54V差不多是正确的,这里没有高精度的万用表就不对测试精度了,只测试了正确性。
音频采集一次采集1000次然后串口打印,使用SerialStudio可视化显示
int adc_samp(void){ /* Variable to capture return value of functions */ cy_rslt_t result; /* Variable to store ADC conversion result from channel 0 */ int32_t adc_result_0 = 0; /* Clear async read complete flag */ async_read_complete = false; /* Initiate an asynchronous read operation. The event handler will be called * when it is complete. */ memset(result_arr,0,sizeof(result_arr)); cyhal_gpio_write_internal(CYBSP_USER_LED,true); result = cyhal_adc_read_async_uv(&adc_obj, NUM_SCAN, result_arr); if(result != CY_RSLT_SUCCESS) { printf("ADC async read failed. Error: %ld\\n", (long unsigned int)result); CY_ASSERT(0); } while(async_read_complete == false); cyhal_gpio_write_internal(CYBSP_USER_LED,false); /* * Read data from result list, input voltage in the result list is in * microvolts. Convert it millivolts and print input voltage * */ for(int i=0; i< NUM_SCAN; i++) { adc_result_0 = result_arr[i] / MICRO_TO_MILLI_CONV_RATIO; printf("/*%4ld*/\\r\\n", (long int)adc_result_0); } return 0;}
串口打印到PC,可视化显示如下
审核编辑:汤梓红