本帖最后由 LIZARD925 于 2025-7-20 17:39 编辑
#技术资源#
APM32E030系列使用记录--ADC的使用
目标:实现阻塞式读取ADC数值
程序中使用ADC1的通道2进行ADC的读取,初始化程序如下- void AD_Init(void)
- {
- RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_ADC1);
- RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOA);
-
- GPIO_Config_T GPIO_InitStructure;
- GPIO_InitStructure.mode = GPIO_MODE_AN;
- GPIO_InitStructure.pupd = GPIO_PUPD_NO;
- GPIO_InitStructure.pin = GPIO_PIN_2;
- GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
- GPIO_Config(GPIOA, &GPIO_InitStructure);
-
- ADC_Reset();
-
- ADC_Config_T ADC_InitStructure;
- ADC_InitStructure.resolution = ADC_RESOLUTION_12B; //ADC数据分辨率
- ADC_InitStructure.scanDir = ADC_SCAN_DIR_UPWARD; //ADC扫描序列方向
- ADC_InitStructure.convMode = ADC_CONVERSION_CONTINUOUS; //连续扫描
- ADC_InitStructure.dataAlign = ADC_DATA_ALIGN_RIGHT; //右对齐
- ADC_InitStructure.extTrigEdge = ADC_EXT_TRIG_EDGE_NONE; //禁用外部触发转换模式
- ADC_InitStructure.extTrigConv = ADC_EXT_TRIG_CONV_TRG0; //ADC外部触发转换定时器1 TRG0
- ADC_Config(&ADC_InitStructure);
-
- ADC_ConfigChannel(ADC_CHANNEL_2, ADC_SAMPLE_TIME_239_5);
-
- ADC_ReadCalibrationFactor(); //ADC 读取校准系数
-
- ADC_Enable();
-
- ADC_StartConversion(); //开始转换
- }
- uint16_t AD_getvalue(void)
- {
- while(ADC_ReadStatusFlag(ADC_FLAG_CC)==RESET); //转换结束标志
- return ADC_ReadConversionValue();
- }
此方式的ADC数值读取使用阻塞的方式,可能会阻塞主循环的其它函数,使用滑动电阻求连接ADC引脚,通过串口将采集的数据打印出来,查看是否正确- uint16_t ADvalue;
- float v;
- int main (void)
- {
- LED_init();
- AD_Init();
- Serial_Init(115200);
- printf("APM32E030\r\n");
-
- while(1)
- {
- ADvalue=AD_getvalue();
- v=(float)ADvalue/4095*3.3;
- printf("ADC:%f\n",v);
-
- LED1_turn();
- Delay_ms(1000);
-
- rx_test(); //串口接收
- }
- }
目标:实现中断读取ADC数值
程序中使用ADC1的通道2进行ADC的读取,初始化程序如下
- void AD_Init(void)
- {
- RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_ADC1);
- RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOA);
- RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_SYSCFG);
-
- GPIO_Config_T GPIO_InitStructure;
- GPIO_InitStructure.mode = GPIO_MODE_AN;
- GPIO_InitStructure.pupd = GPIO_PUPD_NO;
- GPIO_InitStructure.pin = GPIO_PIN_2;
- GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
- GPIO_Config(GPIOA, &GPIO_InitStructure);
-
- ADC_Reset();
-
- ADC_Config_T ADC_InitStructure;
- ADC_InitStructure.resolution = ADC_RESOLUTION_12B; //ADC数据分辨率
- ADC_InitStructure.scanDir = ADC_SCAN_DIR_UPWARD; //ADC扫描序列方向
- ADC_InitStructure.convMode = ADC_CONVERSION_CONTINUOUS; //连续扫描
- ADC_InitStructure.dataAlign = ADC_DATA_ALIGN_RIGHT; //右对齐
- ADC_InitStructure.extTrigEdge = ADC_EXT_TRIG_EDGE_NONE; //禁用外部触发转换模式
- ADC_InitStructure.extTrigConv = ADC_EXT_TRIG_CONV_TRG0; //ADC外部触发转换定时器1 TRG0
- ADC_Config(&ADC_InitStructure);
-
- ADC_ConfigChannel(ADC_CHANNEL_2, ADC_SAMPLE_TIME_239_5);
-
- /* Enable Interrupt*/
- ADC_EnableInterrupt(ADC_INT_CS);
- NVIC_EnableIRQRequest(ADC1_IRQn, 2);
-
- ADC_ReadCalibrationFactor(); //ADC 读取校准系数
- ADC_Enable();
- /* Wait until ADC is ready */
- while (!ADC_ReadStatusFlag(ADC_FLAG_ADRDY));
- ADC_StartConversion(); //开始转换
- }
只有ADC采集结束才会进入中断,将数据进行保存,此方式不阻塞主循环的其它函数,主循环通过串口将采集的数据进行打印,查看是否正确采集
- uint16_t ADvalue;
- float v;
- int main (void)
- {
- LED_init();
- Serial_Init(115200);
- AD_Init();
- printf("APM32E030\r\n");
- while(1)
- {
- v=(float)ADvalue/4095*3.3;
- printf("ADC:%f\n",v);
-
- LED1_turn();
- Delay_ms(1000);
-
- rx_test(); //串口接收
- }
- }
- void ADC1_IRQHandler(void)
- {
- if (ADC_ReadIntFlag(ADC_INT_FLAG_CS) == SET)
- {
- ADC_ClearIntFlag(ADC_INT_FLAG_CS);
- ADvalue = ADC_ReadConversionValue();
- }
- }
目标:实现DMA读取ADC数值
程序中使用ADC1的通道0、1、2、3进行ADC的读取,初始化程序如下- #define ADC_CH_SIZE 4
- uint16_t adcData[ADC_CH_SIZE];
- void DMA_Init(void)
- {
- DMA_Config_T dmaConfig;
- RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_DMA1);
- dmaConfig.peripheralAddress = ((uint32_t)ADC_BASE + 0x40);
- dmaConfig.memoryAddress = (uint32_t)&adcData;
- dmaConfig.direction = DMA_DIR_PERIPHERAL;
- dmaConfig.bufferSize = ADC_CH_SIZE;
- dmaConfig.peripheralInc = DMA_PERIPHERAL_INC_DISABLE;
- dmaConfig.memoryInc = DMA_MEMORY_INC_ENABLE;
- dmaConfig.peripheralDataSize = DMA_PERIPHERAL_DATASIZE_HALFWORD;
- dmaConfig.memoryDataSize = DMA_MEMORY_DATASIZE_HALFWORD;
- dmaConfig.circular = DMA_CIRCULAR_ENABLE;
- dmaConfig.memoryTomemory = DMA_M2M_DISABLE;
- dmaConfig.priority = DMA_PRIORITY_LEVEL_HIGHT;
- DMA_Config(DMA1_CHANNEL_1, &dmaConfig);
- DMA_Enable(DMA1_CHANNEL_1);
- }
- void AD_Init(void)
- {
- RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_ADC1);
- RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOA);
-
- GPIO_Config_T GPIO_InitStructure;
- GPIO_InitStructure.mode = GPIO_MODE_AN;
- GPIO_InitStructure.pupd = GPIO_PUPD_NO;
- GPIO_InitStructure.pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3;
- GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
- GPIO_Config(GPIOA, &GPIO_InitStructure);
-
- ADC_Reset();
-
- ADC_Config_T ADC_InitStructure;
- ADC_InitStructure.resolution = ADC_RESOLUTION_12B;
- ADC_InitStructure.scanDir = ADC_SCAN_DIR_UPWARD;
- ADC_InitStructure.convMode = ADC_CONVERSION_CONTINUOUS; //连续扫描
- ADC_InitStructure.dataAlign = ADC_DATA_ALIGN_RIGHT; //右对齐
- ADC_InitStructure.extTrigEdge = ADC_EXT_TRIG_EDGE_NONE;
- ADC_InitStructure.extTrigConv = ADC_EXT_TRIG_CONV_TRG0;
- ADC_Config(&ADC_InitStructure);
-
- ADC_ConfigChannel(ADC_CHANNEL_0, ADC_SAMPLE_TIME_239_5);
- ADC_ConfigChannel(ADC_CHANNEL_1, ADC_SAMPLE_TIME_239_5);
- ADC_ConfigChannel(ADC_CHANNEL_2, ADC_SAMPLE_TIME_239_5);
- ADC_ConfigChannel(ADC_CHANNEL_3, ADC_SAMPLE_TIME_239_5);
-
- DMA_Init();
- ADC_ReadCalibrationFactor();
-
- ADC_EnableDMA();
- ADC_DMARequestMode(ADC_DMA_MODE_CIRCULAR);
-
- ADC_Enable();
- ADC_StartConversion();
- }
- uint16_t AD_getvalue(uint8_t index)
- {
- return adcData[index];
- }
配置DMA进行ADC数据的搬运,我们只需要在必要的时候读取buff中的数据即可得到ADC采集的数据,主循环中通过串口将采集的数据进行打印,查看数据是否正确
- uint16_t ADvalue;
- float v;
- int main (void)
- {
- LED_init();
- Serial_Init(115200);
- AD_Init();
- printf("APM32E030\r\n");
-
- while(1)
- {
- ADvalue=AD_getvalue(0);
- v=(float)ADvalue/4095*3.3;
- printf("PA0ADC:%f\n",v);
-
- ADvalue=AD_getvalue(1);
- v=(float)ADvalue/4095*3.3;
- printf("PA1ADC:%f\n",v);
-
- ADvalue=AD_getvalue(2);
- v=(float)ADvalue/4095*3.3;
- printf("PA2ADC:%f\n",v);
-
- ADvalue=AD_getvalue(3);
- v=(float)ADvalue/4095*3.3;
- printf("PA3ADC:%f\r\n",v);
- LED1_turn();
- Delay_ms(1000);
-
- rx_test(); //串口接收
- }
- }
- ADC单通道+参考电压/温度,实现ADC采样的与读取
目标:实现读取ADC数值
程序中使用ADC1的通道16/17进行ADC的读取参考电压,初始化程序如下- #include "ad.h" // Device header
- void AD_Init(void)
- {
- RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_ADC1);
- ADC_Reset();
- // ADC_EnableTempSensor(); //温度初始化
- ADC_EnableVrefint(); //参考电压初始化
-
- ADC_Config_T ADC_InitStructure;
- ADC_InitStructure.resolution = ADC_RESOLUTION_12B; //ADC数据分辨率
- ADC_InitStructure.scanDir = ADC_SCAN_DIR_UPWARD; //ADC扫描序列方向
- ADC_InitStructure.convMode = ADC_CONVERSION_CONTINUOUS; //连续扫描
- ADC_InitStructure.dataAlign = ADC_DATA_ALIGN_RIGHT; //右对齐
- ADC_InitStructure.extTrigEdge = ADC_EXT_TRIG_EDGE_NONE; //禁用外部触发转换模式
- ADC_InitStructure.extTrigConv = ADC_EXT_TRIG_CONV_TRG0; //ADC外部触发转换定时器1 TRG0
- ADC_Config(&ADC_InitStructure);
-
- // ADC_ConfigChannel(ADC_CHANNEL_16, ADC_SAMPLE_TIME_239_5);
- ADC_ConfigChannel(ADC_CHANNEL_17, ADC_SAMPLE_TIME_239_5);
-
- ADC_ReadCalibrationFactor(); //ADC 读取校准系数
-
- ADC_Enable();
-
- ADC_StartConversion(); //开始转换
- }
- void AD_getvalue(void)
- {
- uint32_t reference_adc_value = 0, tsen_adc_value = 0;
- ADC_DisableTempSensor();
- // ADC_ConfigChannel(ADC_CHANNEL_16, ADC_SAMPLE_TIME_239_5);
- // ADC_StartConversion();
- // while(ADC_ReadStatusFlag(ADC_FLAG_CC)==RESET); //转换结束标志
- // tsen_adc_value = ADC_ReadConversionValue();
- // printf("tsen_adc_value: %d\n", tsen_adc_value);
-
- ADC_StopConversion();
- ADC_ConfigChannel(ADC_CHANNEL_17, ADC_SAMPLE_TIME_239_5);
- ADC_StartConversion();
- while(ADC_ReadStatusFlag(ADC_FLAG_CC)==RESET); //转换结束标志
- reference_adc_value = ADC_ReadConversionValue();
- printf("reference_adc_value: %d\n", reference_adc_value);
- }
但是读取的结果与手册写的1.2v有出入,我读到的是1.5V,不知道哪里出了问题,中断与DMA的流程和之前的一样,都可以进行读取
- ADC多通道+参考电压/温度,实现ADC采样的与读取
目标:实现DMA读取ADC数值
程序中使用ADC1的通道进行ADC的读取,初始化程序如下- #include "ad.h" // Device header
- #define ADC_CH_SIZE 6
- uint16_t adcData[ADC_CH_SIZE];
- void DMA_Init(void)
- {
- DMA_Config_T dmaConfig;
- RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_DMA1);
- dmaConfig.peripheralAddress = ((uint32_t)ADC_BASE + 0x40);
- dmaConfig.memoryAddress = (uint32_t)&adcData;
- dmaConfig.direction = DMA_DIR_PERIPHERAL;
- dmaConfig.bufferSize = ADC_CH_SIZE;
- dmaConfig.peripheralInc = DMA_PERIPHERAL_INC_DISABLE;
- dmaConfig.memoryInc = DMA_MEMORY_INC_ENABLE;
- dmaConfig.peripheralDataSize = DMA_PERIPHERAL_DATASIZE_HALFWORD;
- dmaConfig.memoryDataSize = DMA_MEMORY_DATASIZE_HALFWORD;
- dmaConfig.circular = DMA_CIRCULAR_ENABLE;
- dmaConfig.memoryTomemory = DMA_M2M_DISABLE;
- dmaConfig.priority = DMA_PRIORITY_LEVEL_HIGHT;
- DMA_Config(DMA1_CHANNEL_1, &dmaConfig);
- DMA_Enable(DMA1_CHANNEL_1);
- }
- void AD_Init(void)
- {
- RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_ADC1);
- RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_GPIOA);
-
- GPIO_Config_T GPIO_InitStructure;
- GPIO_InitStructure.mode = GPIO_MODE_AN;
- GPIO_InitStructure.pupd = GPIO_PUPD_NO;
- GPIO_InitStructure.pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3;
- GPIO_InitStructure.speed = GPIO_SPEED_50MHz;
- GPIO_Config(GPIOA, &GPIO_InitStructure);
-
- ADC_Reset();
- ADC_EnableTempSensor();
- ADC_EnableVrefint();
-
- ADC_Config_T ADC_InitStructure;
- ADC_InitStructure.resolution = ADC_RESOLUTION_12B;
- ADC_InitStructure.scanDir = ADC_SCAN_DIR_UPWARD;
- ADC_InitStructure.convMode = ADC_CONVERSION_CONTINUOUS; //连续扫描
- ADC_InitStructure.dataAlign = ADC_DATA_ALIGN_RIGHT; //右对齐
- ADC_InitStructure.extTrigEdge = ADC_EXT_TRIG_EDGE_NONE;
- ADC_InitStructure.extTrigConv = ADC_EXT_TRIG_CONV_TRG0;
- ADC_Config(&ADC_InitStructure);
-
- ADC_ConfigChannel(ADC_CHANNEL_0, ADC_SAMPLE_TIME_239_5);
- ADC_ConfigChannel(ADC_CHANNEL_1, ADC_SAMPLE_TIME_239_5);
- ADC_ConfigChannel(ADC_CHANNEL_2, ADC_SAMPLE_TIME_239_5);
- ADC_ConfigChannel(ADC_CHANNEL_3, ADC_SAMPLE_TIME_239_5);
- ADC_ConfigChannel(ADC_CHANNEL_16, ADC_SAMPLE_TIME_239_5);
- ADC_ConfigChannel(ADC_CHANNEL_17, ADC_SAMPLE_TIME_239_5);
-
- DMA_Init();
- ADC_ReadCalibrationFactor();
-
- ADC_EnableDMA();
- ADC_DMARequestMode(ADC_DMA_MODE_CIRCULAR);
-
- ADC_Enable();
- ADC_StartConversion();
- }
- uint16_t AD_getvalue(uint8_t index)
- {
- return adcData[index];
- }
将每个通道保存到buff中,进行读取即可
- uint16_t ADvalue;
- float v;
- int main (void)
- {
- LED_init();
- Serial_Init(115200);
- AD_Init();
- printf("APM32E030\r\n");
-
- while(1)
- {
- ADvalue=AD_getvalue(0);
- v=(float)ADvalue/4095*3.3;
- printf("PA0ADC:%f\n",v);
-
- ADvalue=AD_getvalue(1);
- v=(float)ADvalue/4095*3.3;
- printf("PA1ADC:%f\n",v);
-
- ADvalue=AD_getvalue(2);
- v=(float)ADvalue/4095*3.3;
- printf("PA2ADC:%f\n",v);
-
- ADvalue=AD_getvalue(3);
- v=(float)ADvalue/4095*3.3;
- printf("PA3ADC:%f\r\n",v);
-
- ADvalue=AD_getvalue(4);
- printf("TempSensor:%d\r\n",ADvalue);
-
- ADvalue=AD_getvalue(5);
- printf("Vref:%d\r\n",ADvalue);
- LED1_turn();
- Delay_ms(1000);
-
- rx_test(); //串口接收
- }
- }
ADC的使用到此基本差不多了,对于基准电压的采集,以后再找问题
|
|