analog_input.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  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 "mux.h"
  12. #include <stdio.h>
  13. #undef DBG
  14. #define DBG if(1)
  15. #if defined (MAI_12)
  16. //uint16_t ai_state_bit;
  17. uint8_t ai_mux; // выход сдвигового регистра U1010 (управляет MUX 301, 401)
  18. // мультиплексоры отвечат за коммутацию аналоговых входов и АЦП
  19. uint16_t ai_mode; // режим измерения аналоговых каналов (ток или напряжение)
  20. // 0000 0000 0000 0000
  21. // младшие 6 (с 1..6) бит - каналы с 1 по 6 соответственно
  22. // биты 9..14 - каналы с 7 по 12 соответственно
  23. uint16_t ai_alarm; // слово аварий входов
  24. #if 1
  25. ANALOG_IN_t channel_name[NUMBER_ADC_CH] = {AN_INP_1, AN_INP_2, AN_INP_3,
  26. AN_INP_4, AN_INP_5, AN_INP_6,
  27. V_ISO_CL, V_ISO,
  28. AN_INP_7, AN_INP_8, AN_INP_9,
  29. AN_INP_10, AN_INP_11, AN_INP_12,
  30. CRNT_LIM_U_BFR_R, CRNT_LIM_U_ABFR_R};
  31. #endif
  32. #if 0
  33. ANALOG_IN_t channel_name[NUMBER_ADC_CH] = {AN_INP_1, AN_INP_2, AN_INP_3,
  34. AN_INP_4, AN_INP_5, AN_INP_6,
  35. AN_INP_7, AN_INP_8, AN_INP_9,
  36. AN_INP_10, AN_INP_11, AN_INP_12,
  37. V_ISO_CL, V_ISO,
  38. CRNT_LIM_U_BFR_R, CRNT_LIM_U_ABFR_R};
  39. #endif
  40. uint16_t adc_raw_data[NUMBER_ADC_CH];
  41. led_t ai_alarm_led[12] = {IO_1_R, IO_2_R, IO_3_R, IO_4_R,
  42. IO_5_R, IO_6_R, IO_7_R, IO_8_R,
  43. IO_9_R, IO_10_R, IO_11_R, IO_12_R};
  44. led_t ai_input_led[12] = {IO_1_G, IO_2_G, IO_3_G, IO_4_G,
  45. IO_5_G, IO_6_G, IO_7_G, IO_8_G,
  46. IO_9_G, IO_10_G, IO_11_G, IO_12_G};
  47. uint16_t ai_state_bit; // состояние аналоговых входов (вкл/выкл) битовое поле
  48. //
  49. void ai_init(void)
  50. {
  51. // Зеленые LED сигнализируют (вкл/выкл) входов.
  52. ai_led_update();
  53. // Сдвиговые регистры
  54. sh_init();
  55. // Режим измерения
  56. ai_set_meas_mode();
  57. // Питание внешних датчиков
  58. ai_ext_sens_power(settings.ext_sens_power);
  59. // Внешинй ADC
  60. ai_adc_init();
  61. }
  62. //
  63. void ai_led_update(void)
  64. {
  65. for (int i = 0; i < AI_NUMBER; i++)
  66. {
  67. if (settings.ai[i].state) {
  68. leds[ai_input_led[i]].state = LED_ON;
  69. }
  70. else {
  71. leds[ai_input_led[i]].state = LED_OFF;
  72. }
  73. }
  74. }
  75. // Установить режим измерения каналов с 1 по 12.
  76. void ai_set_meas_mode(void)
  77. {
  78. #if 0
  79. for (uint8_t i = 1; i < 13; i++)
  80. {
  81. if (settings.ai_mode_bits & (1 << (i - 1)))
  82. ai_set_mode_word((MEAS_CHAN_MODE_t)1, i);
  83. else
  84. ai_set_mode_word((MEAS_CHAN_MODE_t)0, i);
  85. }
  86. #endif
  87. for (int i = 0; i < AI_NUMBER; i++)
  88. {
  89. if (settings.ai[i].mode)
  90. ai_set_mode_word((MEAS_CHAN_MODE_t)1, i);
  91. }
  92. }
  93. // Настройка внешнего ADC
  94. bool ai_adc_init(void)
  95. {
  96. uint8_t ret;
  97. unsigned long value;
  98. adc_gpio_init();
  99. for (uint32_t i = 0; i < 100; i++) {
  100. MS5192T_Reset();
  101. ret = MS5192T_Init();
  102. DBG printf("ADC init status: %s\r\n", ret == 1 ? "OK" : "FAILED");
  103. if (ret == 1)
  104. break;
  105. vTaskDelay(10);
  106. }
  107. if (!ret) {
  108. mon_set_err(ERR_WORD_1, ADC_ERR, true);
  109. return false;
  110. }
  111. // Запрос регистра конфигурации для (0x710 - значение по умолчанию)
  112. value = MS5192T_GetRegisterValue(MS5192T_REG_CONF, 2, 1);
  113. DBG printf("ADC cfg reg: 0x%X: ", value);
  114. DBG print_binary_half_word((uint16_t)value);
  115. // Коэф-т усиления: 1
  116. DBG printf("ADC. Set gain rate 1\r\n");
  117. MS5192T_SetGain(MS5192T_GAIN_1);
  118. value = MS5192T_GetRegisterValue(MS5192T_REG_CONF, 2, 1);
  119. DBG printf("ADC cfg reg: 0x%X: ", value);
  120. DBG print_binary_half_word((uint16_t)value);
  121. // Униполярный режим
  122. DBG printf("Set unipolar input mode...\r\n");
  123. MS5192T_SetPolar(MS5192T_CONF_UNIPOLAR);
  124. value = MS5192T_GetRegisterValue(MS5192T_REG_CONF, 2, 1);
  125. DBG printf("ADC cfg reg: 0x%X: ", value);
  126. DBG print_binary_half_word((uint16_t)value);
  127. // Регистр статуса
  128. value = MS5192T_GetRegisterValue(MS5192T_REG_STAT, 1, 1);
  129. DBG printf("ADC status reg: 0x%X: ", value);
  130. DBG print_binary_byte((uint8_t)value);
  131. // Установка внутреннего опорного напряжения
  132. MS5192T_SetIntReference(MS5192T_REFSEL_INT); // select internal 1.17V reference
  133. value = MS5192T_GetRegisterValue(MS5192T_REG_CONF, 2, 1);
  134. DBG printf("ADC cfg reg: 0x%X: ", value);
  135. DBG print_binary_half_word((uint16_t)value);
  136. // Регистр режима (MODE register)
  137. value = MS5192T_GetRegisterValue(MS5192T_REG_MODE, 2, 1);
  138. DBG printf("ADC mode reg: 0x%X: ", value);
  139. DBG print_binary_half_word((uint16_t)value);
  140. // Установить update rate
  141. DBG printf("Set update rate.\r\n");
  142. MS5192T_SetUpdateRate(MS5192T_UP_RATE_500);
  143. value = MS5192T_GetRegisterValue(MS5192T_REG_MODE, 2, 1);
  144. DBG printf("ADC mode reg: 0x%X: ", value);
  145. DBG print_binary_half_word((uint16_t)value);
  146. // Калибровка
  147. // 1 - ый канал
  148. MS5192T_Calibrate(MS5192T_MODE_CAL_INT_ZERO, MS5192T_CH_AIN1P_AIN1M);
  149. MS5192T_Calibrate(MS5192T_MODE_CAL_INT_FULL, MS5192T_CH_AIN1P_AIN1M);
  150. // 2 - ой канал
  151. MS5192T_Calibrate(MS5192T_MODE_CAL_INT_ZERO, MS5192T_CH_AIN2P_AIN2M);
  152. MS5192T_Calibrate(MS5192T_MODE_CAL_INT_FULL, MS5192T_CH_AIN2P_AIN2M);
  153. return true;
  154. }
  155. // Оцифровка всех каналов (входы + дополнительные каналы)
  156. void ai_processing(void)
  157. {
  158. #if 0
  159. for (uint8_t i = 0; i < 8; i++)
  160. {
  161. adc_get_two_channles(channel_name[i], channel_name[i + 8]);
  162. }
  163. #endif
  164. for (uint8_t i = 0; i < 6; i++)
  165. {
  166. adc_get_two_channles(channel_name[i], channel_name[i + 8]);
  167. }
  168. #if 0
  169. printf("end\r\n");
  170. adc_print_data();
  171. printf("end\r\n");
  172. #endif
  173. }
  174. //
  175. void adc_get_two_channles(ANALOG_IN_t one, ANALOG_IN_t two)
  176. {
  177. //if (settings.ai[one]) )
  178. printf("One: %u, two: %u\r\n", one, two);
  179. #if 0
  180. ai_connect_channel(one);
  181. vTaskDelay(1);
  182. MS5192T_SetChannel(MS5192T_CH_AIN1P_AIN1M);
  183. adc_raw_data[one] = MS5192T_SingleConversion();
  184. ai_connect_channel(two);
  185. vTaskDelay(1);
  186. MS5192T_SetChannel(MS5192T_CH_AIN2P_AIN2M);
  187. adc_raw_data[two] = MS5192T_SingleConversion();
  188. #endif
  189. }
  190. // Дополнительные каналы (V_ISO_CL, V_ISO, CRNT_LIM_U_BFR_R, CRNT_LIM_U_ABFR_R)
  191. void adc_get_add_channels(void)
  192. {}
  193. //
  194. void adc_print_data(void)
  195. {
  196. printf("\033[2J"); // Очистить
  197. printf("\033[H"); // Переместить курсор в левый верхний угол
  198. 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);
  199. 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);
  200. 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);
  201. 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);
  202. 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);
  203. 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);
  204. 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);
  205. 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);
  206. 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);
  207. 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);
  208. 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);
  209. 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);
  210. 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);
  211. printf("V_ISO: 0x%X, %f\r\n", adc_raw_data[V_ISO], (double) adc_raw_data[V_ISO]*0.00001785305/0.0961538);
  212. 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);
  213. 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);
  214. }
  215. //
  216. void adc_task(void *params)
  217. {
  218. for (;;)
  219. {
  220. ai_alarm = sh_ai_mode(ai_mode);
  221. //ai_processing();
  222. ai_leds_processing();
  223. //vTaskDelay(10);
  224. }
  225. }
  226. // Подключить канал к АЦП
  227. // Одновременно могут быть подключены только 2 канала из наборов:
  228. // 1: AN_INP_1, AN_INP_2, AN_INP_3, AN_INP_4, AN_INP_5, AN_INP_6, V_ISO_CL,
  229. // V_ISO
  230. //
  231. // 2: AN_INP_7, AN_INP_8, AN_INP_9, AN_INP_10, AN_INP_11, AN_INP_12,
  232. // CRNT_LIM_U_BFR_R, CRNT_LIM_U_ABFR_R
  233. void ai_connect_channel(uint8_t channel)
  234. {
  235. if (channel < MUX_401_CH)
  236. {
  237. ai_mux &= 0xF0;
  238. switch (channel)
  239. {
  240. case AN_INP_1: ai_mux |= 0x03; break; // U301 Y3
  241. case AN_INP_2: ai_mux |= 0x00; break; // U301 Y0
  242. case AN_INP_3: ai_mux |= 0x05; break; // U301 Y5
  243. case AN_INP_4: ai_mux |= 0x07; break; // U301 Y7
  244. case AN_INP_5: ai_mux |= 0x06; break; // U301 Y6
  245. case AN_INP_6: ai_mux |= 0x04; break; // U301 Y4
  246. case V_ISO_CL: ai_mux |= 0x01; break; // U301 Y1
  247. case V_ISO : ai_mux |= 0x02; break; // U301 Y2
  248. default: break;
  249. }
  250. }
  251. else
  252. {
  253. ai_mux &= 0x87;
  254. switch (channel)
  255. {
  256. case AN_INP_7: ai_mux |= (0x04 << 4); break; // U401 Y4
  257. case AN_INP_8: ai_mux |= (0x06 << 4); break; // U401 Y6
  258. case AN_INP_9: ai_mux |= (0x07 << 4); break; // U401 Y7
  259. case AN_INP_10:ai_mux |= (0x05 << 4); break; // U401 Y5
  260. case AN_INP_11:ai_mux |= (0x02 << 4); break; // U401 Y2
  261. case AN_INP_12:ai_mux |= (0x01 << 4); break; // U401 Y1
  262. case CRNT_LIM_U_BFR_R: ai_mux |= (0x00 << 4); break; // U401 Y0
  263. case CRNT_LIM_U_ABFR_R: ai_mux |= (0x03 << 4); break; // U401 Y3
  264. default: break;
  265. }
  266. }
  267. sh_ai_connect(ai_mux);
  268. //printf("Analog input connect register: ");
  269. //print_binary_byte(ai_mux);
  270. }
  271. //
  272. void ai_set(void)
  273. {
  274. for (int i = 0; i < AI_NUMBER; i++)
  275. {
  276. if (((settings.ai_state_bits >> i) & 1) != settings.ai[i].state)
  277. {
  278. settings.ai[i].state = ((settings.ai_state_bits >> i) & 1);
  279. if (settings.ai[i].state == 0) {
  280. leds[ai_input_led[i]].state = LED_OFF;
  281. }
  282. else {
  283. leds[ai_input_led[i]].state = LED_ON;
  284. }
  285. }
  286. }
  287. }
  288. // Утсновить режим измерения канала (ток или напряжение)
  289. void ai_set_mode(MEAS_CHAN_MODE_t mode, uint8_t channel)
  290. {
  291. if (mode == MEAS_CURRENT)
  292. {
  293. if (channel < 7)
  294. ai_mode |= (1 << (channel - 1));
  295. else
  296. ai_mode |= (1 << (channel + 1));
  297. }
  298. else
  299. if (channel < 7)
  300. ai_mode &= ~(1 << (channel - 1));
  301. else
  302. ai_mode &= ~(1 << (channel + 1));
  303. sh_ai_mode(ai_mode);
  304. //printf("Analog input mode: ");
  305. print_binary_half_word(ai_mode);
  306. }
  307. // Формируем слово режима работы каналов (ai_mode)
  308. void ai_set_mode_word(MEAS_CHAN_MODE_t mode, uint8_t channel)
  309. {
  310. #if 0
  311. if (mode == MEAS_CURRENT)
  312. {
  313. if (channel < 7)
  314. ai_mode |= (1 << (channel - 1));
  315. else
  316. ai_mode |= (1 << (channel + 1));
  317. }
  318. else
  319. if (channel < 7)
  320. ai_mode &= ~(1 << (channel - 1));
  321. else
  322. ai_mode &= ~(1 << (channel + 1));
  323. #endif
  324. if (mode == MEAS_CURRENT)
  325. {
  326. if (channel < 7)
  327. ai_mode |= (1 << channel);
  328. else
  329. ai_mode |= (1 << channel);
  330. }
  331. else
  332. if (channel < 7)
  333. ai_mode &= ~(1 << channel);
  334. else
  335. ai_mode &= ~(1 << channel);
  336. }
  337. // Сигнал питания внешних датчиков
  338. void ai_ext_sens_power(uint16_t state)
  339. {
  340. if (state)
  341. ai_mux |= 0x80;
  342. else
  343. ai_mux &= ~(0x80);
  344. }
  345. // Управления LED
  346. void ai_leds_processing(void)
  347. {
  348. //uint16_t foo = 0x800;
  349. #if 0
  350. // Управление индикацией вкл/выкл входов
  351. for (uint8_t i = 0; i < AI_NUMBER; i++) {
  352. if (settings.ai_state_bits & (1 << i)) {
  353. }
  354. }
  355. #endif
  356. // Управление индикацией аварий (12 красных LED) (слово ai_alarm)
  357. for (uint8_t i = 0; i < AI_NUMBER; i++) {
  358. if (ai_alarm & (1 << i)) {
  359. leds[ai_alarm_led[i]].state = LED_ON;
  360. }
  361. else {
  362. leds[ai_alarm_led[i]].state = LED_OFF;
  363. }
  364. }
  365. }
  366. //
  367. void ai_connect_test(void)
  368. {
  369. ai_connect_channel(AN_INP_1);
  370. ai_connect_channel(AN_INP_2);
  371. ai_connect_channel(AN_INP_3);
  372. ai_connect_channel(AN_INP_4);
  373. ai_connect_channel(AN_INP_5);
  374. ai_connect_channel(AN_INP_6);
  375. ai_connect_channel(V_ISO_CL);
  376. ai_connect_channel(V_ISO);
  377. ai_connect_channel(AN_INP_7);
  378. ai_connect_channel(AN_INP_8);
  379. ai_connect_channel(AN_INP_9);
  380. ai_connect_channel(AN_INP_10);
  381. ai_connect_channel(AN_INP_11);
  382. ai_connect_channel(AN_INP_12);
  383. ai_connect_channel(CRNT_LIM_U_BFR_R);
  384. ai_connect_channel(CRNT_LIM_U_ABFR_R);
  385. }
  386. //
  387. void ai_mode_test(void)
  388. {
  389. for (uint8_t i = 1; i < 13; i++)
  390. {
  391. ai_set_mode(MEAS_VOLTAGE, i);
  392. }
  393. }
  394. #endif