|
|
楼主 |
发表于 2025-11-25 19:08:19
|
查看全部
APM32E030多频率ADC采样实现方案
针对APM32E030内置温度传感器与外部电压电流采样的不同频率需求,我提供几种实用的实现方案:
方案一:定时器触发 + ADC扫描模式(推荐)
这是最高效的硬件解决方案,利用APM32E030的定时器和ADC扫描功能。
- // 配置定义
- #define VOLTAGE_CHANNEL 0 // 电压采样通道
- #define CURRENT_CHANNEL 1 // 电流采样通道
- #define TEMP_CHANNEL 16 // 内置温度传感器通道
- #define SAMPLE_BUFFER_SIZE 100
- // 采样缓冲区
- uint16_t voltage_buffer[SAMPLE_BUFFER_SIZE];
- uint16_t current_buffer[SAMPLE_BUFFER_SIZE];
- uint16_t temp_buffer[10]; // 温度缓冲区较小
- volatile uint32_t voltage_current_count = 0;
- volatile uint32_t temp_count = 0;
- volatile uint8_t temp_sampling_flag = 0;
- // 定时器配置
- void TIM_Config(void)
- {
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
-
- // 5kHz定时器 - 用于电压电流采样
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
- TIM_TimeBaseStructure.TIM_Period = (SystemCoreClock / 5000) - 1; // 5kHz
- TIM_TimeBaseStructure.TIM_Prescaler = 0;
- TIM_TimeBaseStructure.TIM_ClockDivision = 0;
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
-
- // 2Hz定时器 - 用于温度采样
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
- TIM_TimeBaseStructure.TIM_Period = (SystemCoreClock / 2) - 1; // 2Hz
- TIM_TimeBaseStructure.TIM_Prescaler = 0;
- TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);
-
- // 启用定时器中断
- TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
- TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE);
-
- NVIC_EnableIRQ(TIM3_IRQn);
- NVIC_EnableIRQ(TIM6_IRQn);
-
- TIM_Cmd(TIM3, ENABLE);
- TIM_Cmd(TIM6, ENABLE);
- }
- // ADC配置
- void ADC_Config(void)
- {
- ADC_InitTypeDef ADC_InitStructure;
- GPIO_InitTypeDef GPIO_InitStructure;
-
- // 启用ADC时钟
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
-
- // 配置ADC通道对应的GPIO(外部传感器)
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; // PA0, PA1
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
-
- // ADC基本配置
- ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
- ADC_InitStructure.ADC_ScanConvMode = DISABLE; // 单通道模式
- ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; // 单次转换
- ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
- ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
- ADC_InitStructure.ADC_NbrOfConversion = 1;
- ADC_Init(ADC1, &ADC_InitStructure);
-
- // 启用温度传感器
- ADC_TempSensorVrefintCmd(ENABLE);
-
- // 启用ADC
- ADC_Cmd(ADC1, ENABLE);
-
- // 等待ADC稳定
- Delay_ms(1);
- }
- // 定时器3中断 - 5kHz电压电流采样
- void TIM3_IRQHandler(void)
- {
- if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)
- {
- TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
-
- // 交替采样电压和电流
- static uint8_t vc_alternate = 0;
-
- if(vc_alternate == 0)
- {
- // 采样电压
- ADC_RegularChannelConfig(ADC1, VOLTAGE_CHANNEL, 1, ADC_SampleTime_239_5Cycles);
- ADC_StartConversion(ADC1);
- while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
- voltage_buffer[voltage_current_count % SAMPLE_BUFFER_SIZE] = ADC_GetConversionValue(ADC1);
- }
- else
- {
- // 采样电流
- ADC_RegularChannelConfig(ADC1, CURRENT_CHANNEL, 1, ADC_SampleTime_239_5Cycles);
- ADC_StartConversion(ADC1);
- while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
- current_buffer[voltage_current_count % SAMPLE_BUFFER_SIZE] = ADC_GetConversionValue(ADC1);
-
- voltage_current_count++;
- }
-
- vc_alternate = !vc_alternate;
- }
- }
- // 定时器6中断 - 2Hz温度采样
- void TIM6_IRQHandler(void)
- {
- if (TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET)
- {
- TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
- temp_sampling_flag = 1; // 设置标志,在主循环中处理
- }
- }
- // 主循环中的温度采样处理
- void ProcessTemperatureSampling(void)
- {
- if(temp_sampling_flag)
- {
- temp_sampling_flag = 0;
-
- // 采样温度
- ADC_RegularChannelConfig(ADC1, TEMP_CHANNEL, 1, ADC_SampleTime_239_5Cycles);
- ADC_StartConversion(ADC1);
- while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
- uint16_t temp_raw = ADC_GetConversionValue(ADC1);
-
- // 温度转换(需要根据芯片手册校准)
- float temperature = ConvertToTemperature(temp_raw);
-
- temp_buffer[temp_count % 10] = temp_raw;
- temp_count++;
-
- // 温度数据处理
- ProcessTemperatureData(temperature);
- }
- }
复制代码
|
|