sggt/App/DAC8552/dac8552.c

253 lines
6.0 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}