#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) { uint16_t data = 0; float32 temp1 = *data1, temp2 = *data2; dac8552_init(&dac8552, dac8552_transmit_data, dac8552_cs); if (data1 != NULL) { temp1 = calibrate_cur_ma(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) { //-2.5~2.5v输出 if (*data2 < -2.5f) *data2 = -2.5f; else if (*data2 > 2.5f) *data2 = 2.5f; temp2 = (*data2) * 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); } } float cur_ma_out_calibrate_table[CALIBRATE_CUR_MA_OUT_POINTS] = {0}; uint8_t curma_out_cal_enable = 0; float32 calibrate_cur_ma(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( (cur_ma_out_calibrate_table[i] <= raw)&&(raw <= cur_ma_out_calibrate_table[i + 1]) ) { result = CALIBRATE_CUR_MA_OUT_START + i*interval; //所处区间的左端点 result += interval * (raw - cur_ma_out_calibrate_table[i])/(cur_ma_out_calibrate_table[i + 1] - cur_ma_out_calibrate_table[i]); break; } } } break; case 2: //不执行校准 { result = raw; } break; default: break; } return result; }