analog_input.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. #include "at32f403a_407.h"
  2. #include "analog_input.h"
  3. #include "shift_reg.h"
  4. #include "utility.h"
  5. #include "FreeRTOS.h"
  6. #include "task.h"
  7. #include "settings_api.h"
  8. #include "adc_transport.h"
  9. #include "ms5192t.h"
  10. #include "monitoring.h"
  11. #include <stdio.h>
  12. #undef DBG
  13. #define DBG if(1)
  14. uint8_t input_mux; // выход сдвигового регистра U1010 (управляет MUX 301, 401)
  15. // мультиплексоры отвечат за коммутацию аналоговых входов и АЦП
  16. uint16_t input_mode; // режим измерения аналоговых каналов (ток или напряжение)
  17. // 0000 0000 0000 0000
  18. // младшие 6 (с 1..6) бит - каналы с 1 по 6 соответственно
  19. // биты 9..14 - каналы с 7 по 12 соответственно
  20. ANALOG_IN_t channel_name[NUMBER_ADC_CH] = {AN_INP_1, AN_INP_2, AN_INP_3,
  21. AN_INP_4, AN_INP_5, AN_INP_6,
  22. V_ISO_CL, V_ISO,
  23. AN_INP_7, AN_INP_8, AN_INP_9,
  24. AN_INP_10, AN_INP_11, AN_INP_12,
  25. CRNT_LIM_U_BFR_R, CRNT_LIM_U_ABFR_R};
  26. uint16_t adc_raw_data[NUMBER_ADC_CH];
  27. //en_crnt_alrm_in
  28. // Установить режим измерения канало с 1 по 12.
  29. void ai_set_meas_mode(void)
  30. {
  31. uint8_t bit = 0;
  32. for (uint8_t i = 1; i < 13; i++)
  33. {
  34. bit = settings.ai_mode_bits & (1 << (i - 1));
  35. ai_set_mode((MEAS_CHAN_MODE_t)bit, i);
  36. }
  37. }
  38. // Настройка внешнего ADC
  39. bool ai_adc_init(void)
  40. {
  41. uint8_t ret;
  42. unsigned long value;
  43. adc_gpio_init();
  44. for (uint32_t i = 0; i < 100; i++) {
  45. MS5192T_Reset();
  46. ret = MS5192T_Init();
  47. DBG printf("ADC init status: %s\r\n", ret == 1 ? "OK" : "FAILED");
  48. if (ret == 1)
  49. break;
  50. vTaskDelay(10);
  51. }
  52. if (!ret) {
  53. mon_set_err(ERR_WORD_1, ADC_ERR, true);
  54. return false;
  55. }
  56. // Запрос регистра конфигурации для (0x710 - значение по умолчанию)
  57. value = MS5192T_GetRegisterValue(MS5192T_REG_CONF, 2, 1);
  58. DBG printf("ADC cfg reg: 0x%X: ", value);
  59. DBG print_binary_half_word((uint16_t)value);
  60. // Коэф-т усиления: 1
  61. DBG printf("ADC. Set gain rate 1\r\n");
  62. MS5192T_SetGain(MS5192T_GAIN_1);
  63. value = MS5192T_GetRegisterValue(MS5192T_REG_CONF, 2, 1);
  64. DBG printf("ADC cfg reg: 0x%X: ", value);
  65. DBG print_binary_half_word((uint16_t)value);
  66. // Униполярный режим
  67. DBG printf("Set unipolar input mode...\r\n");
  68. MS5192T_SetPolar(MS5192T_CONF_UNIPOLAR);
  69. value = MS5192T_GetRegisterValue(MS5192T_REG_CONF, 2, 1);
  70. DBG printf("ADC cfg reg: 0x%X: ", value);
  71. DBG print_binary_half_word((uint16_t)value);
  72. // Регистр статуса
  73. value = MS5192T_GetRegisterValue(MS5192T_REG_STAT, 1, 1);
  74. DBG printf("ADC status reg: 0x%X: ", value);
  75. DBG print_binary_byte((uint8_t)value);
  76. // Установка внутреннего опорного напряжения
  77. MS5192T_SetIntReference(MS5192T_REFSEL_INT); // select internal 1.17V reference
  78. value = MS5192T_GetRegisterValue(MS5192T_REG_CONF, 2, 1);
  79. DBG printf("ADC cfg reg: 0x%X: ", value);
  80. DBG print_binary_half_word((uint16_t)value);
  81. // Регистр режима (MODE register)
  82. value = MS5192T_GetRegisterValue(MS5192T_REG_MODE, 2, 1);
  83. DBG printf("ADC mode reg: 0x%X: ", value);
  84. DBG print_binary_half_word((uint16_t)value);
  85. // Установить update rate
  86. DBG printf("Set update rate.\r\n");
  87. MS5192T_SetUpdateRate(MS5192T_UP_RATE_500);
  88. value = MS5192T_GetRegisterValue(MS5192T_REG_MODE, 2, 1);
  89. DBG printf("ADC mode reg: 0x%X: ", value);
  90. DBG print_binary_half_word((uint16_t)value);
  91. // Калибровка
  92. // 1 - ый канал
  93. MS5192T_Calibrate(MS5192T_MODE_CAL_INT_ZERO, MS5192T_CH_AIN1P_AIN1M);
  94. MS5192T_Calibrate(MS5192T_MODE_CAL_INT_FULL, MS5192T_CH_AIN1P_AIN1M);
  95. // 2 - ой канал
  96. MS5192T_Calibrate(MS5192T_MODE_CAL_INT_ZERO, MS5192T_CH_AIN2P_AIN2M);
  97. MS5192T_Calibrate(MS5192T_MODE_CAL_INT_FULL, MS5192T_CH_AIN2P_AIN2M);
  98. //MS5192T_SetChannel(MS5192T_CH_AIN1P_AIN1M);
  99. return true;
  100. }
  101. // Оцифровка всех каналов (входы + дополнительные каналы)
  102. void ai_processing(void)
  103. {
  104. //unsigned long value;
  105. #if 0
  106. ai_connect_channel(AN_INP_4);
  107. vTaskDelay(10);
  108. MS5192T_SetChannel(MS5192T_CH_AIN1P_AIN1M);
  109. vTaskDelay(10);
  110. value = MS5192T_SingleConversion();
  111. printf("ADC channel [AN_INP_1] data raw: 0x%X, %f\r\n", value, (double)value*0.00001785305/0.0961538);
  112. ai_connect_channel(AN_INP_10);
  113. vTaskDelay(10);
  114. MS5192T_SetChannel(MS5192T_CH_AIN2P_AIN2M);
  115. vTaskDelay(10);
  116. value = MS5192T_SingleConversion();
  117. printf("ADC channel [AN_INP_7] data raw: 0x%X, %f\r\n", value, (double)value*0.00001785305/0.0961538);
  118. #endif
  119. #if 0
  120. ai_connect_channel(AN_INP_2);
  121. vTaskDelay(10);
  122. MS5192T_SetChannel(MS5192T_CH_AIN1P_AIN1M);
  123. vTaskDelay(10);
  124. value = MS5192T_SingleConversion();
  125. printf("ADC channel [AN_INP_1] data raw: 0x%X, %f\r\n", value, (double)value*0.00001785305/0.0961538);
  126. ai_connect_channel(AN_INP_8);
  127. vTaskDelay(10);
  128. MS5192T_SetChannel(MS5192T_CH_AIN2P_AIN2M);
  129. vTaskDelay(10);
  130. value = MS5192T_SingleConversion();
  131. printf("ADC channel [AN_INP_7] data raw: 0x%X, %f\r\n", value, (double)value*0.00001785305/0.0961538);
  132. ai_connect_channel(V_ISO_CL);
  133. vTaskDelay(10);
  134. MS5192T_SetChannel(MS5192T_CH_AIN1P_AIN1M);
  135. vTaskDelay(10);
  136. value = MS5192T_SingleConversion();
  137. printf("ADC channel [V_ISO_CL] data raw: 0x%X, %f\r\n", value, (double)value*0.00001785305/0.0961538);
  138. ai_connect_channel(AN_INP_9);
  139. vTaskDelay(10);
  140. MS5192T_SetChannel(MS5192T_CH_AIN2P_AIN2M);
  141. vTaskDelay(10);
  142. value = MS5192T_SingleConversion();
  143. printf("ADC channel [AN_INP_9] data raw: 0x%X, %f\r\n", value, (double)value*0.00001785305/0.0961538);
  144. #endif
  145. #if 1
  146. for (uint8_t i = 0; i < 8; i++)
  147. {
  148. adc_get_two_channles(channel_name[i], channel_name[i + 8]);
  149. //printf("one: %u, two: %u\r\n", i, i + 8);
  150. }
  151. #if 0
  152. printf("end\r\n");
  153. adc_print_data();
  154. printf("end\r\n");
  155. #endif
  156. #endif
  157. }
  158. //
  159. void adc_get_two_channles(ANALOG_IN_t one, ANALOG_IN_t two)
  160. {
  161. ai_connect_channel(one);
  162. vTaskDelay(10);
  163. MS5192T_SetChannel(MS5192T_CH_AIN1P_AIN1M);
  164. vTaskDelay(10);
  165. adc_raw_data[one] = MS5192T_SingleConversion();
  166. ai_connect_channel(two);
  167. vTaskDelay(10);
  168. MS5192T_SetChannel(MS5192T_CH_AIN2P_AIN2M);
  169. vTaskDelay(10);
  170. adc_raw_data[two] = MS5192T_SingleConversion();
  171. }
  172. //
  173. void adc_print_data(void)
  174. {
  175. printf("AN_INP_1: 0x%X, %f\r\n", adc_raw_data[AN_INP_1], (double) adc_raw_data[AN_INP_1]*0.00001785305/0.0961538);
  176. printf("AN_INP_2: 0x%X, %f\r\n", adc_raw_data[AN_INP_2], (double) adc_raw_data[AN_INP_2]*0.00001785305/0.0961538);
  177. printf("AN_INP_3: 0x%X, %f\r\n", adc_raw_data[AN_INP_3], (double) adc_raw_data[AN_INP_3]*0.00001785305/0.0961538);
  178. printf("AN_INP_4: 0x%X, %f\r\n", adc_raw_data[AN_INP_4], (double) adc_raw_data[AN_INP_4]*0.00001785305/0.0961538);
  179. printf("AN_INP_5: 0x%X, %f\r\n", adc_raw_data[AN_INP_5], (double) adc_raw_data[AN_INP_5]*0.00001785305/0.0961538);
  180. printf("AN_INP_6: 0x%X, %f\r\n", adc_raw_data[AN_INP_6], (double) adc_raw_data[AN_INP_6]*0.00001785305/0.0961538);
  181. printf("AN_INP_7: 0x%X, %f\r\n", adc_raw_data[AN_INP_7], (double) adc_raw_data[AN_INP_7]*0.00001785305/0.0961538);
  182. printf("AN_INP_8: 0x%X, %f\r\n", adc_raw_data[AN_INP_8], (double) adc_raw_data[AN_INP_8]*0.00001785305/0.0961538);
  183. printf("AN_INP_9: 0x%X, %f\r\n", adc_raw_data[AN_INP_9], (double) adc_raw_data[AN_INP_9]*0.00001785305/0.0961538);
  184. printf("AN_INP_10: 0x%X, %f\r\n", adc_raw_data[AN_INP_10], (double) adc_raw_data[AN_INP_10]*0.00001785305/0.0961538);
  185. printf("AN_INP_11: 0x%X, %f\r\n", adc_raw_data[AN_INP_11], (double) adc_raw_data[AN_INP_11]*0.00001785305/0.0961538);
  186. printf("AN_INP_12: 0x%X, %f\r\n", adc_raw_data[AN_INP_12], (double) adc_raw_data[AN_INP_12]*0.00001785305/0.0961538);
  187. printf("V_ISO_CL: 0x%X, %f\r\n", adc_raw_data[V_ISO_CL], (double) adc_raw_data[V_ISO_CL]*0.00001785305/0.0961538);
  188. printf("V_ISO: 0x%X, %f\r\n", adc_raw_data[V_ISO], (double) adc_raw_data[V_ISO]*0.00001785305/0.0961538);
  189. printf("CRNT_LIM_U_BFR_R: 0x%X, %f\r\n", adc_raw_data[CRNT_LIM_U_BFR_R], (double) adc_raw_data[CRNT_LIM_U_BFR_R]*0.00001785305/0.0961538);
  190. printf("CRNT_LIM_U_ABFR_R: 0x%X, %f\r\n", adc_raw_data[CRNT_LIM_U_ABFR_R], (double) adc_raw_data[CRNT_LIM_U_ABFR_R]*0.00001785305/0.0961538);
  191. }
  192. //
  193. void adc_task(void *params)
  194. {
  195. for (;;)
  196. {
  197. ai_processing();
  198. vTaskDelay(10);
  199. }
  200. }
  201. // Подключить канал к АЦП
  202. // Одновременно могут быть подключены только 2 канала из наборов:
  203. // 1: AN_INP_1, AN_INP_2, AN_INP_3, AN_INP_4, AN_INP_5, AN_INP_6, V_ISO_CL,
  204. // V_ISO
  205. //
  206. // 2: AN_INP_7, AN_INP_8, AN_INP_9, AN_INP_10, AN_INP_11, AN_INP_12,
  207. // CRNT_LIM_U_BFR_R, CRNT_LIM_U_ABFR_R
  208. void ai_connect_channel(uint8_t channel)
  209. {
  210. if (channel < MUX_401_CH)
  211. {
  212. input_mux &= 0x70;
  213. switch (channel)
  214. {
  215. case AN_INP_1: input_mux |= 0x03; break; // U301 Y3
  216. case AN_INP_2: input_mux |= 0x00; break; // U301 Y0
  217. case AN_INP_3: input_mux |= 0x05; break; // U301 Y5
  218. case AN_INP_4: input_mux |= 0x07; break; // U301 Y7
  219. case AN_INP_5: input_mux |= 0x06; break; // U301 Y6
  220. case AN_INP_6: input_mux |= 0x04; break; // U301 Y4
  221. case V_ISO_CL: input_mux |= 0x01; break; // U301 Y1
  222. case V_ISO : input_mux |= 0x02; break; // U301 Y2
  223. default: break;
  224. }
  225. }
  226. else
  227. {
  228. input_mux &= 0x07;
  229. switch (channel)
  230. {
  231. case AN_INP_7: input_mux |= (0x04 << 4); break; // U401 Y4
  232. case AN_INP_8: input_mux |= (0x06 << 4); break; // U401 Y6
  233. case AN_INP_9: input_mux |= (0x07 << 4); break; // U401 Y7
  234. case AN_INP_10:input_mux |= (0x05 << 4); break; // U401 Y5
  235. case AN_INP_11:input_mux |= (0x02 << 4); break; // U401 Y2
  236. case AN_INP_12:input_mux |= (0x01 << 4); break; // U401 Y1
  237. case CRNT_LIM_U_BFR_R: input_mux |= (0x00 << 4); break; // U401 Y0
  238. case CRNT_LIM_U_ABFR_R: input_mux |= (0x03 << 4); break; // U401 Y3
  239. default: break;
  240. }
  241. }
  242. sh_ai_connect(input_mux);
  243. //printf("Analog input connect register: ");
  244. //print_binary_byte(input_mux);
  245. }
  246. // Утсновить режим измерения канала (ток или напряжение)
  247. void ai_set_mode(MEAS_CHAN_MODE_t mode, uint8_t channel)
  248. {
  249. if (mode == MEAS_CURRENT)
  250. {
  251. if (channel < 7)
  252. input_mode |= (1 << (channel - 1));
  253. else
  254. input_mode |= (1 << (channel + 1));
  255. }
  256. else
  257. if (channel < 7)
  258. input_mode &= ~(1 << (channel - 1));
  259. else
  260. input_mode &= ~(1 << (channel + 1));
  261. sh_ai_mode(input_mode);
  262. printf("Analog input mode: ");
  263. print_binary_half_word(input_mode);
  264. }
  265. //
  266. void ai_connect_test(void)
  267. {
  268. ai_connect_channel(AN_INP_1);
  269. ai_connect_channel(AN_INP_2);
  270. ai_connect_channel(AN_INP_3);
  271. ai_connect_channel(AN_INP_4);
  272. ai_connect_channel(AN_INP_5);
  273. ai_connect_channel(AN_INP_6);
  274. ai_connect_channel(V_ISO_CL);
  275. ai_connect_channel(V_ISO);
  276. ai_connect_channel(AN_INP_7);
  277. ai_connect_channel(AN_INP_8);
  278. ai_connect_channel(AN_INP_9);
  279. ai_connect_channel(AN_INP_10);
  280. ai_connect_channel(AN_INP_11);
  281. ai_connect_channel(AN_INP_12);
  282. ai_connect_channel(CRNT_LIM_U_BFR_R);
  283. ai_connect_channel(CRNT_LIM_U_ABFR_R);
  284. }
  285. //
  286. void ai_mode_test(void)
  287. {
  288. for (uint8_t i = 1; i < 13; i++)
  289. {
  290. ai_set_mode(MEAS_VOLTAGE, i);
  291. }
  292. }