#include "FreeRTOS.h" #include "task.h" #include "dac8552.h" #include "gpio.h" #include "spi.h" dac8552x_object dac8552; void dac8552_cs(cs_state_type state) { if (state == CS_L) { DAC8552_SYNC(GPIO_PIN_RESET); } else { DAC8552_SYNC(GPIO_PIN_SET); } } void dac8552_transmit_data(uint8_t *data, uint16_t len) { HAL_SPI_Transmit(&hspi3, data, len, 1000); } void dac8552_init(dac8552x_object *dac, dac8552_write write, dac8552_chip_select cs) { if ((dac == NULL) || (write == NULL) || (cs == NULL)) { return; } dac->write_data = write; dac->chip_selcet = cs; } void set_dac8552_channel_value(dac8552x_object *dac, dac8552_ld_type ld, dac8552_bs_type bs, dac8552_pd_type pd, uint16_t data) { uint32_t input = 0; uint8_t sdata[3]; input = data; input = input | (ld << 20); input = input | (bs << 18); input = input | (pd << 16); sdata[0] = (uint8_t)(input >> 16); sdata[1] = (uint8_t)(input >> 8); sdata[2] = (uint8_t)input; dac->chip_selcet(CS_L); vTaskDelay(10); dac->write_data(sdata, 3); dac->chip_selcet(CS_H); } void dac8552_operation(float32 *data1, float32 *data2) { dac8552_init(&dac8552, dac8552_transmit_data, dac8552_cs); uint16_t data = 0; if (data1 != NULL) { //对mux_signal.sv作限幅 if(*data1 > 25.0f) { *data1 = 25.0f; } else if(*data1 < 0.0f) { *data1 = 0.0f; } float32 temp1 = *data1; /**********在此处进行电流输出(mA)校准,temp1为目标值**********/ temp1 = calibrate_cur_ma_out(temp1); //校准后再进行一次限幅,以防运算出错 if(temp1 > 25.0f) { temp1 = 25.0f; } else if(temp1 < 0.0f) { temp1 = 0.0f; } mux_signal.sv_calibrated = temp1; /**********************************************************/ temp1 = (temp1) * 100.0f; data = (uint16_t)(65535.0f * temp1 / 2500.0f); set_dac8552_channel_value(&dac8552, LD_CH_B, SEL_BUF_B, PD_NONE, data); // set_dac8552_channel_value(&dac8552, LD_CH_A, SEL_BUF_A, PD_NONE, data); } if (data2 != NULL) { //对mux_signal.sv作限幅 if(*data2 > 2.5f) { *data2 = 2.5f; } else if(*data2 < -2.5f) { *data2 = -2.5f; } float32 temp2 = *data2; /**********在此处进行电压输出(mV)校准,temp2为目标值**********/ temp2 = calibrate_vol_mv_out(temp2); //校准后再进行一次限幅,以防运算出错 if(temp2 > 2.5f) { temp2 = 2.5f; } else if(temp2 < -2.5f) { temp2 = -2.5f; } mux_signal.sv_calibrated = temp2; /**********************************************************/ temp2 = temp2 * 0.5f + 1.25f; data = (uint16_t)(65535.0f * temp2 / 2.5f); // set_dac8552_channel_value(&dac8552, LD_CH_B, SEL_BUF_B, PD_NONE, data); set_dac8552_channel_value(&dac8552, LD_CH_A, SEL_BUF_A, PD_NONE, data); } } uint8_t curma_out_cal_enable = 0; float32 calibrate_cur_ma_out(float32 raw) { float result = 0; switch (curma_out_cal_enable) { case 0: //开机后只读一次 { uint16_t cal_check = 0; cal_check = eeprom_readdata(CAL_CUR_MA_OUT_ADDR_FLAG) << 8; cal_check |= eeprom_readdata(CAL_CUR_MA_OUT_ADDR_FLAG + 8) & 0x00FF; if(cal_check != 0xAAAA) { //不存在校准数据 curma_out_cal_enable = 2; } else { //存在校准数据 curma_out_cal_enable = 1; //将读到的数据存储至cur_ma_out_calibrate_table[CALIBRATE_CUR_MA_OUT_POINTS] eeprom_dataread_single(EEPROM_TAG_CAL_CUR_MA_OUT); } } break; case 1: //执行校准 { //计算区间间隔(按照规定的点数,在量程范围内平均分配) float interval = (float32)(CALIBRATE_CUR_MA_OUT_END - CALIBRATE_CUR_MA_OUT_START)/(float32)(CALIBRATE_CUR_MA_OUT_POINTS - 1); for( uint8_t i = 0; i < CALIBRATE_CUR_MA_OUT_POINTS - 1; i++) { if( (cali_paras.cali_cur_mA_out[i] <= raw)&&(raw <= cali_paras.cali_cur_mA_out[i + 1]) ) { result = CALIBRATE_CUR_MA_OUT_START + i*interval; //所处区间的左端点 result += interval * (raw - cali_paras.cali_cur_mA_out[i])/(cali_paras.cali_cur_mA_out[i + 1] - cali_paras.cali_cur_mA_out[i]); break; } } } break; case 2: //不执行校准 { result = raw; } break; default: break; } return result; } uint8_t volmv_out_cal_enable = 0; float32 calibrate_vol_mv_out(float32 raw) { float result = 0; switch (volmv_out_cal_enable) { case 0: //开机后只读一次 { uint16_t cal_check = 0; cal_check = eeprom_readdata(CAL_VOL_MV_OUT_ADDR_FLAG) << 8; cal_check |= eeprom_readdata(CAL_VOL_MV_OUT_ADDR_FLAG + 8) & 0x00FF; if(cal_check != 0xAAAA) { //不存在校准数据 volmv_out_cal_enable = 2; } else { //存在校准数据 volmv_out_cal_enable = 1; //将读到的数据存储至vol_mv_out_calibrate_table[CALIBRATE_VOL_MV_OUT_POINTS] eeprom_dataread_single(EEPROM_TAG_CAL_VOL_MV_OUT); } } break; case 1: //执行校准 { //计算区间间隔(按照规定的点数,在量程范围内平均分配) float interval = (float32)(CALIBRATE_VOL_MV_OUT_END - CALIBRATE_VOL_MV_OUT_START)/(float32)(CALIBRATE_VOL_MV_OUT_POINTS - 1); for( uint8_t i = 0; i < CALIBRATE_VOL_MV_OUT_POINTS - 1; i++) { if( (cali_paras.cali_vol_mV_out[i] <= raw)&&(raw <= cali_paras.cali_vol_mV_out[i + 1]) ) { result = CALIBRATE_VOL_MV_OUT_START + i*interval; //所处区间的左端点 result += interval * (raw - cali_paras.cali_vol_mV_out[i])/(cali_paras.cali_vol_mV_out[i + 1] - cali_paras.cali_vol_mV_out[i]); break; } } } break; case 2: //不执行校准 { result = raw; } break; default: break; } return result; }