fix_bsp_gpadc.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. #include "Platform.h"
  2. #include "bsp_timer.h"
  3. #include <math.h>
  4. #include "fix_bsp_gpadc.h"
  5. #define CALI_CENTER_VL 10000
  6. /* ---------------------------------------------------------------------------------------------------
  7. ----------------------------------------------------------------------------------------------------*/
  8. void fix_improving_adc_accuracy(void)
  9. {
  10. *((volatile unsigned *)(0x40002400 + 0x20)) =0x2e;
  11. for(int i=0;i<0x455;i++);
  12. }
  13. /* ---------------------------------------------------------------------------------------------------
  14. - 函数名称: adc_gpio_config
  15. - 函数功能: ADC引脚配置
  16. - 输入参数: 16bits 0---8bit位代表0--8通道,需要配置就对相应的bit位置1
  17. - 创建日期: 2019-04-18
  18. ----------------------------------------------------------------------------------------------------*/
  19. void fix_adc_gpio_config(uint16_t channels)
  20. {
  21. if(channels==0)//通道0--GADC_AIN0--GPIO21
  22. {
  23. gpio_mux_ctl(21,0);
  24. gpio_fun_sel(21,0);
  25. gpio_fun_inter(21,0);
  26. gpio_direction_input(21, 3);
  27. }else if(channels==1)//通道1--GADC_AIN0--GPIO20
  28. {
  29. gpio_mux_ctl(20,0);
  30. gpio_fun_sel(20,0);
  31. gpio_fun_inter(20,0);
  32. gpio_direction_input(20, 3);
  33. }else if(channels==2)//通道2--GADC_AIN0--GPIO19
  34. {
  35. gpio_mux_ctl(19,0);
  36. gpio_fun_sel(19,0);
  37. gpio_fun_inter(19,0);
  38. gpio_direction_input(19, 3);
  39. }else if(channels==3)//通道3--GADC_AIN0--GPIO18
  40. {
  41. gpio_mux_ctl(18,0);
  42. gpio_fun_sel(18,0);
  43. gpio_fun_inter(18,0);
  44. gpio_direction_input(18, 3);
  45. }else if(channels==4)//通道4--GADC_AIN0--GPIO0
  46. {
  47. gpio_mux_ctl(0,0);
  48. gpio_fun_sel(0,0);
  49. gpio_fun_inter(0,0);
  50. gpio_direction_input(0, 3);
  51. }else if(channels==5)//通道5--GADC_AIN0--GPIO1
  52. {
  53. gpio_mux_ctl(1,0);
  54. gpio_fun_sel(1,0);
  55. gpio_fun_inter(1,0);
  56. gpio_direction_input(1, 3);
  57. }else if(channels==6)//通道6--GADC_AIN0--GPIO4
  58. {
  59. gpio_mux_ctl(4,0);
  60. gpio_fun_sel(4,0);
  61. gpio_fun_inter(4,0);
  62. gpio_direction_input(4, 3);
  63. }else if(channels==7)//通道7--GADC_AIN0--GPIO5
  64. {
  65. gpio_mux_ctl(5,0);
  66. gpio_fun_sel(5,0);
  67. gpio_fun_inter(5,0);
  68. gpio_direction_input(5, 3);
  69. }else if(channels==8)//芯片供电电压的2/3 例如芯片供电为3.3V那么通道8采集电压为2.2V
  70. {
  71. }
  72. }
  73. /* ---------------------------------------------------------------------------------------------------
  74. ----------------------------------------------------------------------------------------------------*/
  75. void fix_gpadc_config_channel(uint16_t channel)
  76. {
  77. __write_hw_reg32(GPADC_CHAN_CTL ,channel);
  78. __write_hw_reg32(GPADC_FIFO_CTL , 0x10);
  79. __write_hw_reg32(GPADC_FIFO_CTL , 0x00);
  80. }
  81. uint16_t fix_data_average(uint16_t *data,uint16_t len)
  82. {
  83. uint16_t add_cnt = 0;
  84. uint32_t sum_data = 0;
  85. uint8_t filter_cnt = 0;
  86. filter_cnt = len/10;
  87. for(int i=0;i<len-1;i++)
  88. {
  89. for(int j=0;j<len-i-1;j++)
  90. {
  91. if(data[j]>data[j+1])
  92. {
  93. uint16_t temp = data[j];
  94. data[j] = data[j+1];
  95. data[j+1] = temp;
  96. }
  97. }
  98. }
  99. for(int i=6*filter_cnt;i<len-3*filter_cnt;i++)
  100. {
  101. sum_data += data[i];
  102. add_cnt++;
  103. }
  104. if(0 == add_cnt) return -1;
  105. else return sum_data/add_cnt;
  106. }
  107. /* ---------------------------------------------------------------------------------------------------
  108. - 函数名称: Init_adc
  109. - 函数功能: ADC初始化
  110. - 输入参数:无
  111. - 创建日期: 2019-04-18
  112. - 作 者:陈俊伟
  113. ----------------------------------------------------------------------------------------------------*/
  114. int fix_init_adc(uint8_t freq,uint8_t gadc_ref)
  115. {
  116. uint32_t adc_reg = 0;
  117. __write_hw_reg32(CPR_RSTCTL_CTLAPB_SW , 0x10000000);/*先 使GPADC_RSTN=0,再使 GPADC_RSTN=1,软复位 GPADC 模块*/
  118. __write_hw_reg32(CPR_RSTCTL_CTLAPB_SW , 0x10001000);/*先 使GPADC_RSTN=0,再使 GPADC_RSTN=1,软复位 GPADC 模块*/
  119. __write_hw_reg32(CPR_CTLAPBCLKEN_GRCTL , 0x20002000);//使能GPADC_PCLK_EN 的GPADC_PCLK时钟
  120. __write_hw_reg32(GPADC_FIFO_CTL , 0x10);//对 FIFO 进 行 一 次 清 空 操 作
  121. __write_hw_reg32(GPADC_FIFO_CTL , 0x00);//中断阈值
  122. if((freq>GADC_FREQ_500K)||(freq<GADC_FREQ_8M)) freq = GADC_FREQ_1M;
  123. if(GADC_REF_2_47V == gadc_ref)
  124. adc_reg = (freq<<8)|0x10 ;
  125. else
  126. adc_reg = (freq<<8)|0x12 ;
  127. __write_hw_reg32(GPADC_RF_CTL ,adc_reg);// 配置寄存器 GPADC_RF_CTL GPADC_PCLK/(gpadc_clkdiv*2)=16M/16=1M ,select 2.4V vref
  128. __write_hw_reg32(GPADC_MAIN_CTL , 0x09);// 配置寄存器 GPADC_MAIN_CTL 打开GPADC模块,,数据采集上升沿.
  129. __write_hw_reg32(GPADC_TIMER0 ,4); //通道切换等待时间
  130. //NVIC_EnableIRQ(GADC_IRQn);
  131. }
  132. int16_t fix_gpadc_val_update(uint8_t update_ch)
  133. {
  134. gadc_cache_t *temp_gadc_cache = NULL;
  135. uint16_t gadc_value[2*FIFO_DEEP] = {0};
  136. uint16_t gadc_count = 0;
  137. uint32_t val;
  138. temp_gadc_cache = (gadc_cache_t*)&val;
  139. for(int t=0;t<FIFO_DEEP;t++)
  140. {
  141. __read_hw_reg32(GPADC_FIFO,val);
  142. if(update_ch == temp_gadc_cache->chanel_1) gadc_value[gadc_count++] = temp_gadc_cache->value_1;
  143. if(update_ch == temp_gadc_cache->chanel_2) gadc_value[gadc_count++] = temp_gadc_cache->value_2;
  144. if((update_ch != 0)&&(0 == temp_gadc_cache->chanel_1)) break; //empty
  145. }
  146. if(gadc_count<=2) return -1;
  147. else return fix_data_average(gadc_value+2,gadc_count-2); //Remove the first FIFO data
  148. }
  149. uint16_t count = 0;
  150. char state=4;
  151. void test_xc_gpadc(void)
  152. {
  153. int gadc_calibration_get(uint32_t *value);
  154. uint16_t value = 0;
  155. uint16_t value_calibrated = 0;
  156. uint32_t calibration_param = 0;
  157. if(gadc_calibration_get(&calibration_param)>0)
  158. {
  159. printf("gadc_calibration_get success!,cali param=%d\n",calibration_param);
  160. }
  161. else
  162. {
  163. calibration_param = 10000;
  164. printf("gadc_calibration_get error!\n");
  165. }
  166. fix_init_adc(GADC_FREQ_1M,GADC_REF_2_47V);
  167. for(int i=0;i<4;i++)
  168. fix_adc_gpio_config(i+state);
  169. fix_gpadc_config_channel(state);
  170. while(1)
  171. {
  172. //If the delay is less, you have to test it well !
  173. for(int i=0;i<0x1000;i++);//delay
  174. value = fix_gpadc_val_update(state);
  175. value_calibrated = value * calibration_param / CALI_CENTER_VL ;
  176. int old_state = state;
  177. switch(state)
  178. {
  179. case 4:fix_gpadc_config_channel(5);state=5;break;
  180. case 5:fix_gpadc_config_channel(6);state=6;break;
  181. case 6:fix_gpadc_config_channel(7);state=7;break;
  182. case 7:fix_gpadc_config_channel(4);state=4;break;
  183. default:break;
  184. }
  185. if(count++>=1000)
  186. {
  187. count =0;
  188. //printf("%1d-%3d ",old_state,value);
  189. printf("channel:%d===cali=%d===before cali Voltage:%f V,after cali Voltage:%f V \r\n",\
  190. old_state,calibration_param,((value)*2.47)/(1.0*1024),((value_calibrated)*2.47)/(1.0*1024));
  191. //printf("channel:%d======Voltage:%f V\r\n",old_state,((value_calibrated)*3.3)/(1.0*1024));
  192. }
  193. }
  194. }
  195. static uint32_t calibration_param = 0;
  196. void user_config_adc_init(void)
  197. {
  198. int gadc_calibration_get(uint32_t *value);
  199. if(gadc_calibration_get(&calibration_param)>0)
  200. {
  201. printf("gadc_calibration_get success!,cali param=%d\n",calibration_param);
  202. }
  203. else
  204. {
  205. calibration_param = 10000;
  206. printf("gadc_calibration_get error!\n");
  207. }
  208. fix_init_adc(GADC_FREQ_1M,GADC_REF_2_47V);
  209. }
  210. //channel 0 对应adc4 1 对应adc5通过
  211. void user_config_adc_channel(uint8_t channel)
  212. {
  213. fix_adc_gpio_config(channel+state);
  214. fix_gpadc_config_channel(channel+state);
  215. //If the delay is less, you have to test it well !
  216. for(int i=0;i<0x3000;i++);//delay
  217. }
  218. uint16_t user_get_adc_data(uint8_t channel)
  219. {
  220. uint16_t value_calibrated = 0;
  221. uint16_t value = 0;
  222. value = fix_gpadc_val_update(state+channel);
  223. value_calibrated = value * calibration_param / CALI_CENTER_VL ;
  224. return value_calibrated;
  225. }