芯海科技
直播中

殷永枫

4年用户 13经验值
擅长:嵌入式技术 控制/MCU
私信 关注
[ADC/AFE]

请问有关于CS32A010系列的ADC模块的单端采样例程吗;

使用CS32A010K8V7的MCU进行ADC中断单端采样,无法采到一个稳定的值,不断的在变化,请问如何解决;

int main(void)
{
adc_config_t adc_config;
pga_config_t pga_config;
vref_config_t vref_config;

/* Init USART1 */
//cs_eval_com_init();

//printf("ADC convert example!\r\n");

/* Interrupt every 1ms */
SysTick_Config(SystemCoreClock / 1000);
delay(2000);

/* Clock enable */
__RCU_AHB_CLK_ENABLE(RCU_AHB_PERI_GPIOA);
__RCU_APB1_CLK_ENABLE(RCU_APB1_PERI_ADADC);
__RCU_FUNC_ENABLE(LRC2_CLK);

/* adc clock = LRC2(1.024MHz) */
rcu_adcclk_config(RCU_ADCLK_CFG_LRC2);

if(rcu_lrc2_stabilization_wait() == ERROR)
{
//printf("LRC2 not ready\r\n");
/* Stop here */
while(1);
}
else
{
//printf("LRC2 ready\r\n");
}

adc_def_init(ADC1);

/* Step1:Inner-vref must soft start */
adc_vref_soft_start(ADC1);

/* Step2:Config AD-ADC */
adc_config_struct_init(&adc_config);
adc_config.abandont_num = ADC_ABANDONT_DATA_4;
adc_config.average_num = ADC_AVERAGE_NUM_16;
adc_config.convert_mode = ADC_SINGLE_CONVERT_MODE;
adc_config.data_rate = ADC_DATARATE_MODE_4;
adc_config.gain_select = ADC_GAIN_1;
adc_config.ovrwr_mode = ADC_DATA_OVER_WRITE;
adc_config.power_mode = ADC_HIGH_POWER_MODE;
adc_config.rst_num = ADC_RST_CYCLE_2048;
adc_config.setup_time = ADC_SETUP_TIME_CYCLE_2048;

adc_init(ADC1, &adc_config);

/* Step3:Config PGA */
pga_config.din_select = PGA_BOTH_PMOS_NMOS;
pga_config.pga1_enable = ENABLE;
pga_config.pga_chop = PGA_CHOP_DISABLE;
pga_config.pga_gain = ADC_PGA_GAIN_1;

adc_pga_init(&pga_config);

/* Step4:Config VREF */
vref_config.buffer_enable = ENABLE;
vref_config.driver = ADC_VREF_DRV_MAX_5MA;
vref_config.ref_select = ADC_REF_SELECT_INNER_2P048V;
vref_config.vref_enable = ENABLE;

adc_vref_init(&vref_config);

/* Step5:Filter select */
adc_digital_filter_select(ADC1, ADC_FILTER_LOW_LATENCY);

/* Step6:trigger config -- soft */
adc_trigger_config(ADC1, ADC_TRIGGER_MODE_SOFT, ADC_TRIGGER_SRC_RTC);

adc_chop_freq_set(ADC1,ADC_CHOP_DIV_256);

/* ADC_FILTER_LOW_LATENCY Inner channel for calibrate N:VREFP/2 P:VREFP/2 */
adc_channel_config(ADC1, ADC_INPUT_CHANNEL_14, ADC_INPUT_CHANNEL_14);
while(!adc_software_calibration_set(ADC1,&adc_config,&pga_config,&vref_config));

adc_nvic_config();

while(1)
{
/* ADC_FILTER_LOW_LATENCY Outer channel P:ADCIN1 N:ADCIN0 */
adc_channel_config(ADC1, ADC_INPUT_CHANNEL_0, ADC_INPUT_CHANNEL_0);

if(__ADC_FLAG_STATUS_GET(ADC1, ADC_FLAG_DATA_EOCH) == RESET)
{
    adc_conversion_start(ADC1);
}

delay(200);

}

}

void ADC1_IRQHandler(void)
{

if(__ADC_FLAG_STATUS_GET(ADC1,ADC_FLAG_DATA_EOCH))
{
    adc_data_convert_low_latency(__ADC_CONV_VALUE_GET(ADC1));
}
if(__ADC_FLAG_STATUS_GET(ADC1,ADC_FLAG_WDG_EVENT))
{
    printf("out range !!!!!\r\n");
    __ADC_FLAG_CLEAR(ADC1,ADC_FLAG_WDG_EVENT);
}
printf("end!!! \r\n\n");

}

void adc_data_convert_low_latency(uint32_t adc_data)
{

if(adc_data & 0x800000)
{
    adc_data = (~(adc_data & 0xFFFFFF))+1;
    adc_data &= 0x00FFFFFF;
    
    gconvt_data = (double)adc_data * 1.0235074 * 2.048 / 0x7FFFFF;
    //printf("adc_data %x, adc convert value -%fV \r\n", adc_data,convt_data);
    
}
else
{
    adc_data &= 0x00FFFFFF;
    gconvt_data = (double)adc_data * 1.0235074 * 2.048/ 0x7FFFFF;
    //printf("adc_data %x, adc convert value +%fV \r\n", adc_data,convt_data);
}

}
根据pack包中的ChipSea.CS32A01X_DFP.1.1.3中ADC_Intterupt例程更改的,ADC采样不完整;

回帖(1)

殷永枫

2024-7-30 17:10:25
根据ADC采样原理,差分采样得知,有3种方法,
一种是将ADC的单端采样输入引脚和一个不用的ADC输入引脚组成差分对,将组成差分对的那个引脚与GND引脚相连;
一种是将ADC的单端采样输入引脚和内部ADC_CHANNEL_12组成差分对进行计算;
一种是将ADC的单端采样输入引脚和内部ADC_CHANNEL_14组成差分对进行计算;
举报

更多回帖

发帖
×
20
完善资料,
赚取积分