#include "Includes.h" /* 2021/09/17 1、在芯片FT测试过程中,将ADC工艺误差校正。 2、ADC 校准值(数据)存储于FLASH 第240K 位置,占用8Byte.(4+4Byte 校准数据和取反校验) 3、校准中心值CALI_CENTER_VL=10000 ,ADC计算时,将ADC原始值乘以校准值再除以中心值(10000) value_calibrated = value * calibration_param / CALI_CENTER_VL ; 4、读取校准值接口:int gadc_calibration_get(uint32_t *value) 具体用法请参考adc-demo,调用接口返回值大于0表示正确获取到校准值。 2022/02/11 1、增加3.3V参考电压时的校准参数。 */ #define PROG_SECTOR_NUM 60 // = 4*60 = 240k #define CALI_CENTER_VL 10000 #define CALI_OFFSET_VL 1000 /** * Copyright (c) 2022 - 2025, XinChip * All rights reserved. * Author : D */ void adc_gpio_config(uint8_t io_gpadc_channel) { if(io_gpadc_channel==0xff) return; gpio_mux_ctl(io_gpadc_channel,0); gpio_fun_sel(io_gpadc_channel,0); gpio_fun_inter(io_gpadc_channel,0); gpio_direction_input(io_gpadc_channel, 3);/*FLOATING*/ } /** * Copyright (c) 2022 - 2025, XinChip * All rights reserved. * Author : D */ void gpadc_config_channel(uint16_t channel) { __write_hw_reg32(GPADC_CHAN_CTL ,channel); __write_hw_reg32(GPADC_FIFO_CTL , 0x10); __write_hw_reg32(GPADC_FIFO_CTL , 0x00); } /** * Copyright (c) 2022 - 2025, XinChip * All rights reserved. * Author : D */ extern void init_adc(uint8_t freq,uint8_t gadc_ref) { uint32_t adc_reg = 0; __write_hw_reg32(CPR_RSTCTL_CTLAPB_SW , 0x10000000);/*先使GPADC_RSTN=0,再使 GPADC_RSTN=1软复位 GPADC 模块*/ __write_hw_reg32(CPR_RSTCTL_CTLAPB_SW , 0x10001000); __write_hw_reg32(CPR_CTLAPBCLKEN_GRCTL , 0x20002000);/*使能GPADC_PCLK_EN 的GPADC_PCLK时钟*/ __write_hw_reg32(GPADC_FIFO_CTL , 0x10);/*对FIFO进行一次清空操作*/ __write_hw_reg32(GPADC_FIFO_CTL , 0x00); if((freq>GADC_FREQ_500K)||(freq CALI_CENTER_VL-CALI_OFFSET_VL)&&(vl[0] < CALI_CENTER_VL+CALI_OFFSET_VL) )) { value[0] = vl[0]; value[1] = vl[1]; return 1; } else { return -1; } } /** * Copyright (c) 2022 - 2025, XinChip * All rights reserved. * Author : D */ uint16_t data_average(uint16_t *data,uint16_t len) { uint16_t add_cnt = 0; uint32_t sum_data = 0; uint8_t filter_cnt = 0; filter_cnt = len/10; for(int i=0; idata[j+1]) { uint16_t temp = data[j]; data[j] = data[j+1]; data[j+1] = temp; } } } for(int i=6*filter_cnt; ichanel_1) gadc_value[gadc_count++] = temp_gadc_cache->value_1; if(update_ch == temp_gadc_cache->chanel_2) gadc_value[gadc_count++] = temp_gadc_cache->value_2; if((update_ch != 0)&&(0 == temp_gadc_cache->chanel_1)) break; //empty } if(gadc_count<=2) return -1; else return data_average(gadc_value+2,gadc_count-2); //Remove the first FIFO data } /** * Copyright (c) 2022 - 2025, XinChip * All rights reserved. * Author : D */ void test_gpadc_3_3V(void) { uint16_t count = 0; char state=4; uint16_t value = 0; uint16_t value_calibrated = 0; uint32_t calibration_param[2] = {0}; if(gadc_calibration_get(calibration_param)>0) { printf("[3.3v] gadc_calibration_get success!,cali param=%d\n",calibration_param[1]); } else { calibration_param[1] = 10000; printf("[3.3v] gadc_calibration_get error!\n"); } adc_gpio_config(IO_GPADC_CHANNEL4); adc_gpio_config(IO_GPADC_CHANNEL5); adc_gpio_config(IO_GPADC_CHANNEL6); adc_gpio_config(IO_GPADC_CHANNEL7); init_adc(GADC_FREQ_1M,GADC_REF_AVDD); gpadc_config_channel(state); while(1) { //If the delay is less, you have to test it well ! for(int i=0; i<0x1000; i++); //delay value = gpadc_val_update(state); value_calibrated = value * calibration_param[1] / CALI_CENTER_VL ; int old_state = state; switch(state) { case 4: gpadc_config_channel(5); state=5; break; case 5: gpadc_config_channel(6); state=6; break; case 6: gpadc_config_channel(7); state=7; break; case 7: gpadc_config_channel(4); state=4; break; default: break; } if(count++>=1000) { count =0; //printf("%1d-%3d ",old_state,value); printf("[3.3v] channel:%d:0x%04X===cali=%d===before cali Voltage:%f V,after cali Voltage:%f V \r\n",\ old_state,value,calibration_param[1],((value)*3.3)/(1.0*1024),((value_calibrated)*3.3)/(1.0*1024)); //printf("channel:%d======Voltage:%f V\r\n",old_state,((value_calibrated)*3.3)/(1.0*1024)); } } } /** * Copyright (c) 2022 - 2025, XinChip * All rights reserved. * Author : D */ void test_gpadc_2_47V(void) { uint16_t count = 0; char state=4; uint16_t value = 0; uint16_t value_calibrated = 0; uint32_t calibration_param[2] = {0}; if(gadc_calibration_get(calibration_param)>0) { printf("[2.47v] gadc_calibration_get success!,cali param=%d\n",calibration_param[0]); } else { calibration_param[0] = 10000; printf("[2.47v] gadc_calibration_get error!\n"); } adc_gpio_config(IO_GPADC_CHANNEL4); adc_gpio_config(IO_GPADC_CHANNEL5); adc_gpio_config(IO_GPADC_CHANNEL6); adc_gpio_config(IO_GPADC_CHANNEL7); init_adc(GADC_FREQ_1M,GADC_REF_2_47V); gpadc_config_channel(state); while(1) { //If the delay is less, you have to test it well ! for(int i=0; i<0x1000; i++); //delay value = gpadc_val_update(state); value_calibrated = value * calibration_param[0] / CALI_CENTER_VL ; int old_state = state; switch(state) { case 4: gpadc_config_channel(5); state=5; break; case 5: gpadc_config_channel(6); state=6; break; case 6: gpadc_config_channel(7); state=7; break; case 7: gpadc_config_channel(4); state=4; break; default: break; } if(count++>=1000) { count =0; //printf("%1d-%3d ",old_state,value); printf("[2.47v] channel:%d:0x%04X===cali=%d===before cali Voltage:%f V,after cali Voltage:%f V \r\n",\ old_state,value,calibration_param[0],((value)*2.47)/(1.0*1024),((value_calibrated)*2.47)/(1.0*1024)); //printf("channel:%d======Voltage:%f V\r\n",old_state,((value_calibrated)*3.3)/(1.0*1024)); } } } /** * Copyright (c) 2022 - 2025, XinChip * All rights reserved. * Author : D */ void test_gpadc(void) { test_gpadc_3_3V(); // test_gpadc_2_47V(); }