analog_input.c 11 KB

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