#include "at32f403a_407.h" #include "analog_input.h" #include "shift_reg.h" #include "utility.h" #include "FreeRTOS.h" #include "task.h" #include "settings_api.h" #include "adc_transport.h" #include "ms5192t.h" #include "monitoring.h" #include #undef DBG #define DBG if(1) uint8_t input_mux; // выход сдвигового регистра U1010 (управляет MUX 301, 401) // мультиплексоры отвечат за коммутацию аналоговых входов и АЦП uint16_t input_mode; // режим измерения аналоговых каналов (ток или напряжение) // 0000 0000 0000 0000 // младшие 6 (с 1..6) бит - каналы с 1 по 6 соответственно // биты 9..14 - каналы с 7 по 12 соответственно ANALOG_IN_t channel_name[NUMBER_ADC_CH] = {AN_INP_1, AN_INP_2, AN_INP_3, AN_INP_4, AN_INP_5, AN_INP_6, V_ISO_CL, V_ISO, AN_INP_7, AN_INP_8, AN_INP_9, AN_INP_10, AN_INP_11, AN_INP_12, CRNT_LIM_U_BFR_R, CRNT_LIM_U_ABFR_R}; uint16_t adc_raw_data[NUMBER_ADC_CH]; //en_crnt_alrm_in // Установить режим измерения канало с 1 по 12. void ai_set_meas_mode(void) { uint8_t bit = 0; for (uint8_t i = 1; i < 13; i++) { bit = settings.ai_mode_bits & (1 << (i - 1)); ai_set_mode((MEAS_CHAN_MODE_t)bit, i); } } // Настройка внешнего ADC bool ai_adc_init(void) { uint8_t ret; unsigned long value; adc_gpio_init(); for (uint32_t i = 0; i < 100; i++) { MS5192T_Reset(); ret = MS5192T_Init(); DBG printf("ADC init status: %s\r\n", ret == 1 ? "OK" : "FAILED"); if (ret == 1) break; vTaskDelay(10); } if (!ret) { mon_set_err(ERR_WORD_1, ADC_ERR, true); return false; } // Запрос регистра конфигурации для (0x710 - значение по умолчанию) value = MS5192T_GetRegisterValue(MS5192T_REG_CONF, 2, 1); DBG printf("ADC cfg reg: 0x%X: ", value); DBG print_binary_half_word((uint16_t)value); // Коэф-т усиления: 1 DBG printf("ADC. Set gain rate 1\r\n"); MS5192T_SetGain(MS5192T_GAIN_1); value = MS5192T_GetRegisterValue(MS5192T_REG_CONF, 2, 1); DBG printf("ADC cfg reg: 0x%X: ", value); DBG print_binary_half_word((uint16_t)value); // Униполярный режим DBG printf("Set unipolar input mode...\r\n"); MS5192T_SetPolar(MS5192T_CONF_UNIPOLAR); value = MS5192T_GetRegisterValue(MS5192T_REG_CONF, 2, 1); DBG printf("ADC cfg reg: 0x%X: ", value); DBG print_binary_half_word((uint16_t)value); // Регистр статуса value = MS5192T_GetRegisterValue(MS5192T_REG_STAT, 1, 1); DBG printf("ADC status reg: 0x%X: ", value); DBG print_binary_byte((uint8_t)value); // Установка внутреннего опорного напряжения MS5192T_SetIntReference(MS5192T_REFSEL_INT); // select internal 1.17V reference value = MS5192T_GetRegisterValue(MS5192T_REG_CONF, 2, 1); DBG printf("ADC cfg reg: 0x%X: ", value); DBG print_binary_half_word((uint16_t)value); // Регистр режима (MODE register) value = MS5192T_GetRegisterValue(MS5192T_REG_MODE, 2, 1); DBG printf("ADC mode reg: 0x%X: ", value); DBG print_binary_half_word((uint16_t)value); // Установить update rate DBG printf("Set update rate.\r\n"); MS5192T_SetUpdateRate(MS5192T_UP_RATE_500); value = MS5192T_GetRegisterValue(MS5192T_REG_MODE, 2, 1); DBG printf("ADC mode reg: 0x%X: ", value); DBG print_binary_half_word((uint16_t)value); // Калибровка // 1 - ый канал MS5192T_Calibrate(MS5192T_MODE_CAL_INT_ZERO, MS5192T_CH_AIN1P_AIN1M); MS5192T_Calibrate(MS5192T_MODE_CAL_INT_FULL, MS5192T_CH_AIN1P_AIN1M); // 2 - ой канал MS5192T_Calibrate(MS5192T_MODE_CAL_INT_ZERO, MS5192T_CH_AIN2P_AIN2M); MS5192T_Calibrate(MS5192T_MODE_CAL_INT_FULL, MS5192T_CH_AIN2P_AIN2M); //MS5192T_SetChannel(MS5192T_CH_AIN1P_AIN1M); return true; } // Оцифровка всех каналов (входы + дополнительные каналы) void ai_processing(void) { //unsigned long value; #if 0 ai_connect_channel(AN_INP_4); vTaskDelay(10); MS5192T_SetChannel(MS5192T_CH_AIN1P_AIN1M); vTaskDelay(10); value = MS5192T_SingleConversion(); printf("ADC channel [AN_INP_1] data raw: 0x%X, %f\r\n", value, (double)value*0.00001785305/0.0961538); ai_connect_channel(AN_INP_10); vTaskDelay(10); MS5192T_SetChannel(MS5192T_CH_AIN2P_AIN2M); vTaskDelay(10); value = MS5192T_SingleConversion(); printf("ADC channel [AN_INP_7] data raw: 0x%X, %f\r\n", value, (double)value*0.00001785305/0.0961538); #endif #if 0 ai_connect_channel(AN_INP_2); vTaskDelay(10); MS5192T_SetChannel(MS5192T_CH_AIN1P_AIN1M); vTaskDelay(10); value = MS5192T_SingleConversion(); printf("ADC channel [AN_INP_1] data raw: 0x%X, %f\r\n", value, (double)value*0.00001785305/0.0961538); ai_connect_channel(AN_INP_8); vTaskDelay(10); MS5192T_SetChannel(MS5192T_CH_AIN2P_AIN2M); vTaskDelay(10); value = MS5192T_SingleConversion(); printf("ADC channel [AN_INP_7] data raw: 0x%X, %f\r\n", value, (double)value*0.00001785305/0.0961538); ai_connect_channel(V_ISO_CL); vTaskDelay(10); MS5192T_SetChannel(MS5192T_CH_AIN1P_AIN1M); vTaskDelay(10); value = MS5192T_SingleConversion(); printf("ADC channel [V_ISO_CL] data raw: 0x%X, %f\r\n", value, (double)value*0.00001785305/0.0961538); ai_connect_channel(AN_INP_9); vTaskDelay(10); MS5192T_SetChannel(MS5192T_CH_AIN2P_AIN2M); vTaskDelay(10); value = MS5192T_SingleConversion(); printf("ADC channel [AN_INP_9] data raw: 0x%X, %f\r\n", value, (double)value*0.00001785305/0.0961538); #endif #if 1 for (uint8_t i = 0; i < 8; i++) { adc_get_two_channles(channel_name[i], channel_name[i + 8]); //printf("one: %u, two: %u\r\n", i, i + 8); } #if 0 printf("end\r\n"); adc_print_data(); printf("end\r\n"); #endif #endif } // void adc_get_two_channles(ANALOG_IN_t one, ANALOG_IN_t two) { ai_connect_channel(one); vTaskDelay(10); MS5192T_SetChannel(MS5192T_CH_AIN1P_AIN1M); vTaskDelay(10); adc_raw_data[one] = MS5192T_SingleConversion(); ai_connect_channel(two); vTaskDelay(10); MS5192T_SetChannel(MS5192T_CH_AIN2P_AIN2M); vTaskDelay(10); adc_raw_data[two] = MS5192T_SingleConversion(); } // void adc_print_data(void) { 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); 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); printf("V_ISO: 0x%X, %f\r\n", adc_raw_data[V_ISO], (double) adc_raw_data[V_ISO]*0.00001785305/0.0961538); 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); 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); } // void adc_task(void *params) { for (;;) { ai_processing(); vTaskDelay(10); } } // Подключить канал к АЦП // Одновременно могут быть подключены только 2 канала из наборов: // 1: AN_INP_1, AN_INP_2, AN_INP_3, AN_INP_4, AN_INP_5, AN_INP_6, V_ISO_CL, // V_ISO // // 2: AN_INP_7, AN_INP_8, AN_INP_9, AN_INP_10, AN_INP_11, AN_INP_12, // CRNT_LIM_U_BFR_R, CRNT_LIM_U_ABFR_R void ai_connect_channel(uint8_t channel) { if (channel < MUX_401_CH) { input_mux &= 0x70; switch (channel) { case AN_INP_1: input_mux |= 0x03; break; // U301 Y3 case AN_INP_2: input_mux |= 0x00; break; // U301 Y0 case AN_INP_3: input_mux |= 0x05; break; // U301 Y5 case AN_INP_4: input_mux |= 0x07; break; // U301 Y7 case AN_INP_5: input_mux |= 0x06; break; // U301 Y6 case AN_INP_6: input_mux |= 0x04; break; // U301 Y4 case V_ISO_CL: input_mux |= 0x01; break; // U301 Y1 case V_ISO : input_mux |= 0x02; break; // U301 Y2 default: break; } } else { input_mux &= 0x07; switch (channel) { case AN_INP_7: input_mux |= (0x04 << 4); break; // U401 Y4 case AN_INP_8: input_mux |= (0x06 << 4); break; // U401 Y6 case AN_INP_9: input_mux |= (0x07 << 4); break; // U401 Y7 case AN_INP_10:input_mux |= (0x05 << 4); break; // U401 Y5 case AN_INP_11:input_mux |= (0x02 << 4); break; // U401 Y2 case AN_INP_12:input_mux |= (0x01 << 4); break; // U401 Y1 case CRNT_LIM_U_BFR_R: input_mux |= (0x00 << 4); break; // U401 Y0 case CRNT_LIM_U_ABFR_R: input_mux |= (0x03 << 4); break; // U401 Y3 default: break; } } sh_ai_connect(input_mux); //printf("Analog input connect register: "); //print_binary_byte(input_mux); } // Утсновить режим измерения канала (ток или напряжение) void ai_set_mode(MEAS_CHAN_MODE_t mode, uint8_t channel) { if (mode == MEAS_CURRENT) { if (channel < 7) input_mode |= (1 << (channel - 1)); else input_mode |= (1 << (channel + 1)); } else if (channel < 7) input_mode &= ~(1 << (channel - 1)); else input_mode &= ~(1 << (channel + 1)); sh_ai_mode(input_mode); printf("Analog input mode: "); print_binary_half_word(input_mode); } // void ai_connect_test(void) { ai_connect_channel(AN_INP_1); ai_connect_channel(AN_INP_2); ai_connect_channel(AN_INP_3); ai_connect_channel(AN_INP_4); ai_connect_channel(AN_INP_5); ai_connect_channel(AN_INP_6); ai_connect_channel(V_ISO_CL); ai_connect_channel(V_ISO); ai_connect_channel(AN_INP_7); ai_connect_channel(AN_INP_8); ai_connect_channel(AN_INP_9); ai_connect_channel(AN_INP_10); ai_connect_channel(AN_INP_11); ai_connect_channel(AN_INP_12); ai_connect_channel(CRNT_LIM_U_BFR_R); ai_connect_channel(CRNT_LIM_U_ABFR_R); } // void ai_mode_test(void) { for (uint8_t i = 1; i < 13; i++) { ai_set_mode(MEAS_VOLTAGE, i); } }