ADC.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. #include <stdbool.h>
  2. #include "ADC.h"
  3. #include "gd32e23x.h"
  4. #include "SysTick.h"
  5. #include "Timer.h"
  6. #include "math.h"
  7. #include "common.h"
  8. #include "IM1253E.h"
  9. uint32_t DCPDU_Iin_Zero = 0;
  10. uint32_t DCPDU_Win_Zero = 0;
  11. bool adc_data_ok_flag = false;
  12. bool Init_IM1253E_flag = false;
  13. bool Start_Read_Flag = false;
  14. bool IM1253E_OK_flag = false;
  15. bool Read_IM1253E_flag = false;
  16. #define UART1_BUF_SIZE 64
  17. extern unsigned char u8_TX_Length;
  18. extern unsigned char RX_Length;
  19. extern unsigned char u8_RX_Index;
  20. extern unsigned char B_Rx_Data_ING;
  21. extern unsigned char B_Rx_Finish;
  22. extern unsigned char u8_RxBuf[UART1_BUF_SIZE];
  23. uint8_t adc_sample_n; //采样次数
  24. #if SUPPORT_2_V_GA_CHN
  25. uint16_t adc_original_value[ADC_CH_N+ADC_V_CHN]={0};
  26. uint16_t adc_calc_value[ADC_Avg_N][ADC_CH_N+ADC_V_CHN];
  27. uint32_t adc_Avg_value[ADC_CH_N+ADC_V_CHN];
  28. extern uint16_t adc_data_zero[ADC_CH_N+ADC_V_CHN];
  29. #else
  30. uint16_t adc_original_value[ADC_CH_N]={0};
  31. uint16_t adc_calc_value[ADC_Avg_N][ADC_CH_N];
  32. uint32_t adc_Avg_value[ADC_CH_N];
  33. extern uint16_t adc_data_zero[ADC_CH_N];
  34. #endif
  35. #if SUPPORT_2_V_GA_CHN
  36. uint16_t adc_data_zero[ADC_CH_N+ADC_V_CHN]= {0};
  37. #else
  38. uint16_t adc_data_zero[ADC_CH_N]= {0};
  39. #endif
  40. void Init_ADC(void)
  41. {
  42. board_t *board = get_board();
  43. adc_sample_n = 0;
  44. ConfigADCGPIO();
  45. while(!dma_flag_get(DMA_CH0,DMA_FLAG_FTF));
  46. dma_flag_clear(DMA_CH0,DMA_FLAG_FTF);
  47. for(int i = 0;i < 8;i++)
  48. {
  49. adc_data_zero[i] = 0x149;
  50. }
  51. #if (SUPPORT_IM1253E == 0)
  52. #if SUPPORT_ADC_GATHER_V
  53. adc_data_zero[ADC_VOL] = adc_original_value[ADC_VOL] = 0x01;
  54. #endif
  55. #else
  56. Init_IM1253E_flag = true;
  57. uint8_t temp1 = 0;
  58. uint8_t temp2 = 0;
  59. uint32_t temp0 = 0;
  60. while(Init_IM1253E_flag)
  61. {
  62. if(Read_IM1253E_flag)
  63. {
  64. Read_IM1253E_flag = false;
  65. Read_IM1253E_REG(Device_addr_IM1253E,V_REG_ADDR,8);//Device_addr_IM1253E
  66. }
  67. if(B_Rx_Finish)
  68. {
  69. uint32_t temp_da[8] = {0};
  70. B_Rx_Finish = false;
  71. for(int j = 0;j < 8;j++)
  72. {
  73. temp_da[j] = 0;
  74. for(int i = 0;i < 4;i++)
  75. {
  76. temp1 = 8 * i;
  77. temp1 = 24 - temp1;
  78. temp2 = 4 * j;
  79. temp2 += 3;
  80. temp2 += i;
  81. temp0 = u8_RxBuf[temp2] << temp1;
  82. temp_da[j] += temp0;
  83. }
  84. }
  85. DCPDU_Iin_Zero = temp_da[1] / 10;
  86. DCPDU_Win_Zero = temp_da[2] / 10;
  87. board->md_data.r_data.input.voltage = temp_da[0] / 10;
  88. for(int i = 0;i < RelaySlaveChaNum;i++)
  89. {
  90. board->md_data.r_data.output[i].voltage = board->md_data.r_data.input.voltage;
  91. }
  92. Init_IM1253E_flag = false;
  93. IM1253E_OK_flag = true;
  94. }
  95. }
  96. #endif
  97. }
  98. void ConfigADCGPIO(void)
  99. {
  100. //使能RCU相关时钟
  101. rcu_periph_clock_enable(ADC_0_5_RCU); //使能GPIOA的时钟
  102. rcu_periph_clock_enable(ADC_67_RCU); //使能GPIOB的时钟
  103. //使能ADC时钟
  104. rcu_periph_clock_enable(RCU_ADC);
  105. //使能DMA的时钟
  106. rcu_periph_clock_enable(RCU_DMA);
  107. //配置ADC时钟
  108. rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6);
  109. //设置GPIO为ADC接口
  110. #if SUPPORT_2_V_GA_CHN
  111. gpio_mode_set(ADC_0_5_IO, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, ADC_ch0|ADC_ch1|ADC_ch2|ADC_ch3|ADC_ch4|ADC_ch5|ADC_Vol_ch1|ADC_Vol_ch2);
  112. #else
  113. gpio_mode_set(ADC_0_5_IO, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, ADC_ch0|ADC_ch1|ADC_ch2|ADC_ch3|ADC_ch4|ADC_ch5);
  114. #endif
  115. gpio_mode_set(ADC_67_IO, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, ADC_ch6|ADC_ch7);
  116. //复位ADC外设
  117. adc_deinit();
  118. //配置DMA
  119. ADC_dma_config();
  120. //内部ADC配置
  121. adc_special_function_config(ADC_SCAN_MODE,ENABLE); //配置ADC扫描转换模式
  122. adc_special_function_config(ADC_CONTINUOUS_MODE,ENABLE); //配置ADC连续转换模式
  123. adc_external_trigger_source_config(ADC_REGULAR_CHANNEL,ADC_EXTTRIG_REGULAR_NONE); //配置ADC外部触发是软件触发
  124. adc_data_alignment_config(ADC_DATAALIGN_RIGHT); //配置ADC数据对齐方式是右对齐
  125. adc_resolution_config(ADC_RESOLUTION_12B); //配置ADC为12位
  126. #if SUPPORT_2_V_GA_CHN
  127. adc_channel_length_config(ADC_REGULAR_CHANNEL, ADC_CH_N+ADC_V_CHN);
  128. adc_regular_channel_config(8U, ADC_CHANNEL_3, ADC_SAMPLETIME_55POINT5);
  129. adc_regular_channel_config(9U, ADC_CHANNEL_2, ADC_SAMPLETIME_55POINT5);
  130. #else
  131. adc_channel_length_config(ADC_REGULAR_CHANNEL, ADC_CH_N); //配置ADC规则通道组成或注入通道组的长度,因为用到8个通道,所以是8
  132. #endif
  133. adc_regular_channel_config(0U, ADC_CHANNEL_0, ADC_SAMPLETIME_55POINT5);
  134. adc_regular_channel_config(1U, ADC_CHANNEL_1, ADC_SAMPLETIME_55POINT5);
  135. adc_regular_channel_config(2U, ADC_CHANNEL_4, ADC_SAMPLETIME_55POINT5);
  136. adc_regular_channel_config(3U, ADC_CHANNEL_5, ADC_SAMPLETIME_55POINT5);
  137. adc_regular_channel_config(4U, ADC_CHANNEL_6, ADC_SAMPLETIME_55POINT5);
  138. adc_regular_channel_config(5U, ADC_CHANNEL_7, ADC_SAMPLETIME_55POINT5);
  139. adc_regular_channel_config(6U, ADC_CHANNEL_8, ADC_SAMPLETIME_55POINT5);
  140. adc_regular_channel_config(7U, ADC_CHANNEL_9, ADC_SAMPLETIME_55POINT5);
  141. adc_enable();
  142. adc_enable();
  143. //delay_ms(2);
  144. adc_calibration_enable(); //校准复位
  145. adc_dma_mode_enable(); //使能DMA
  146. adc_software_trigger_enable(ADC_REGULAR_CHANNEL); //软件触发
  147. adc_software_trigger_enable(ADC_REGULAR_CHANNEL);
  148. //dma_interrupt_enable(DMA_CH0,DMA_INT_FTF);
  149. }
  150. void ADC_dma_config(void)
  151. {
  152. //通道参数配置
  153. dma_parameter_struct dma_data_parameter;
  154. //使能ADC时钟
  155. rcu_periph_clock_enable(RCU_ADC);
  156. //使能DMA的时钟
  157. rcu_periph_clock_enable(RCU_DMA);
  158. //复位DMA通道
  159. dma_deinit(DMA_CH0);
  160. //初始化DMA为单数据模式
  161. dma_data_parameter.periph_addr = (uint32_t)(&ADC_RDATA); //设置DMA外设地址,也是DMA数据传输的源地址,ADC单次采样转换结束后,会将数据存入ADC_RDATA地址中
  162. dma_data_parameter.periph_inc = DMA_PERIPH_INCREASE_DISABLE; //设置DMA数据传输的源地址自增算法取消,ADC每次转换后数据存入地址不变
  163. dma_data_parameter.memory_addr = (uint32_t)(adc_original_value); //设置DMA存储器地址,也是DMA数据传输的目标地址
  164. dma_data_parameter.memory_inc = DMA_MEMORY_INCREASE_ENABLE; //设置DMA数据传输目标地址自增算法使能,因为DMA每个周期需要传送八个数据,所以在一个周期内,目标地址要自增
  165. dma_data_parameter.periph_width = DMA_PERIPHERAL_WIDTH_16BIT; //设置DMA从外设中读出数据的位数,因为ADC转换后的数值是12位,用16位数值表示,所以这里设置为1字
  166. dma_data_parameter.memory_width = DMA_MEMORY_WIDTH_16BIT; //设置DMA存入存储器的数据位数
  167. dma_data_parameter.direction = DMA_PERIPHERAL_TO_MEMORY; //设置DMA的数据传输方向
  168. #if SUPPORT_2_V_GA_CHN
  169. dma_data_parameter.number = ADC_CH_N + ADC_V_CHN;
  170. #else
  171. dma_data_parameter.number = ADC_CH_N; //设置DMA一个周期要传输的数据个数,用了8个通道的ADC,所以在一个周期内要传输8个数据
  172. #endif
  173. dma_data_parameter.priority = DMA_PRIORITY_HIGH; //设置DMA数据传输高优先级
  174. dma_circulation_enable(DMA_CH0); //DMA循环模式使能,这样DMA在传输8个数据后,存储地址复位,自动开启下一轮传输
  175. dma_init(DMA_CH0, &dma_data_parameter); //初始化DMA
  176. dma_memory_to_memory_disable(DMA_CH0); //这里用不上,所以存储器到存储器DMA传输取消
  177. dma_channel_enable(DMA_CH0); //使能DMA通道
  178. }
  179. uint32_t DC_I_calfunction(uint16_t da,uint8_t channel)
  180. {
  181. uint32_t temp_i = 0;
  182. uint32_t temp_v = 0;
  183. if(da > 0)
  184. {
  185. switch(channel)
  186. {
  187. #if SPPPORT_BIG_HAL
  188. case 0:
  189. case 1:
  190. case 4:
  191. case 5:
  192. {
  193. temp_v = da;
  194. if(da < 0xA)
  195. {
  196. temp_v = 0;
  197. }
  198. temp_v *= ADC_Vref;
  199. temp_v *= 1000;
  200. temp_v = temp_v >> 12;
  201. temp_v *= 2.5;
  202. temp_i = temp_v;
  203. temp_i /= 10;//去掉第3位小数
  204. temp_i *= 10;
  205. //temp_i += 200;
  206. if(temp_i <= 80)
  207. temp_i = 0;
  208. }
  209. break;
  210. #endif
  211. default:
  212. {
  213. temp_v = da;
  214. temp_v *= ADC_Vref;
  215. temp_v *= 1000;
  216. temp_v = temp_v >> 12;//temp_v /= ADC_Fulscale;
  217. temp_v /= A_gain;
  218. temp_i = temp_v / I_sens;
  219. temp_i /= 10;//去掉第3位小数
  220. temp_i *= 10;
  221. //temp_i += 70;
  222. if(temp_i <= 200)
  223. temp_i = 0;
  224. }
  225. }
  226. return temp_i;
  227. }
  228. else
  229. {
  230. return 0;
  231. }
  232. }
  233. static uint16_t sort_buff[ADC_CH_N][ADC_Avg_N] = {0};
  234. static void buff_sort(uint16_t *arr,int num)
  235. {
  236. int i,j;
  237. uint16_t tmp;
  238. for(j=0; j < num;j++)
  239. {
  240. for(i =0; i < (num -j-1);i++)
  241. {
  242. if(arr[i+1] > arr[i])
  243. {
  244. tmp = arr[i+1];
  245. arr[i+1] = arr[i];
  246. arr[i] = tmp;
  247. }
  248. }
  249. }
  250. }
  251. void read_adc_val(void)
  252. {
  253. int8_t i = 0;
  254. if(adc_sample_n < ADC_Avg_N)
  255. {
  256. for(i = 0;i < ADC_CH_N ;i++)
  257. {
  258. sort_buff[i][adc_sample_n] = adc_original_value[i];
  259. }
  260. adc_sample_n++;
  261. }
  262. else
  263. {
  264. adc_sample_n = 0;
  265. for(i = 0;i < ADC_CH_N ;i++)
  266. {
  267. uint16_t *arr = &sort_buff[i][0];
  268. buff_sort(arr,ADC_Avg_N);
  269. adc_Avg_value[i] = sort_buff[i][6];
  270. if(adc_Avg_value[i] > adc_data_zero[i])
  271. {
  272. adc_Avg_value[i] -= adc_data_zero[i];
  273. }
  274. else
  275. {
  276. adc_Avg_value[i] = 0;
  277. }
  278. }
  279. adc_data_ok_flag = true;
  280. }
  281. }