更新:

1、电压mV输出校准完成;
2、电阻Ω输出校准完成;
3、mux_signal.sv补充限幅;
This commit is contained in:
吴俊潮 2025-06-26 10:02:34 +08:00
parent 88c0dbc6e3
commit caedfcaa43
12 changed files with 19357 additions and 22624 deletions

View File

@ -1,11 +1,3 @@
/*
* @Author: DaMingSY zxm5337@163.com
* @Date: 2024-10-10 11:17:45
* @LastEditors: DaMingSY zxm5337@163.com
* @LastEditTime: 2024-10-11 15:09:07
* @FilePath: \signal_generator\App\DAC7811\dac7811.c
* @Description: ,`customMade`, koroFileHeader查看配置 : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
#include "FreeRTOS.h" #include "FreeRTOS.h"
#include "task.h" #include "task.h"
#include "dac7811.h" #include "dac7811.h"
@ -40,12 +32,33 @@ void fun_dac7811_spi1_init()
void fun_dac7811_operate(float32 *data_sv) void fun_dac7811_operate(float32 *data_sv)
{ {
if (data_sv == NULL) if (data_sv == NULL) return;
return;
uint16_t reg_data = 0; if(*data_sv > 4000)
{
*data_sv = 4000;
}
else if (*data_sv < 0)
{
*data_sv = 0;
}
reg_data = (uint16_t)(*data_sv); float32 temp = *data_sv;
/**********在此处进行电阻输出Ω校准temp为目标值**********/
temp = calibrate_res_ohm_out(temp);
if(temp > 4000)
{
temp = 4000;
}
else if (temp < 0)
{
temp = 0;
}
mux_signal.sv_calibrated = temp;
/**********************************************************/
uint16_t reg_data = (uint16_t)(temp);
reg_data |= 0x1000; reg_data |= 0x1000;
reg_data &= 0x1fff; reg_data &= 0x1fff;
@ -62,3 +75,66 @@ void fun_dac7811_operate(float32 *data_sv)
//DAC7811_CS(GPIO_PIN_SET); //DAC7811_CS(GPIO_PIN_SET);
} }
} }
float res_ohm_out_calibrate_table[CALIBRATE_RES_OHM_OUT_POINTS] = {0};
uint8_t resohm_out_cal_enable = 0;
float32 calibrate_res_ohm_out(float32 raw)
{
float result = 0;
switch (resohm_out_cal_enable)
{
case 0: //开机后只读一次
{
uint16_t cal_check = 0;
cal_check = eeprom_readdata(CAL_RES_OHM_OUT_ADDR_FLAG) << 8;
cal_check |= eeprom_readdata(CAL_RES_OHM_OUT_ADDR_FLAG + 8) & 0x00FF;
if(cal_check != 0xAAAA)
{
//不存在校准数据
resohm_out_cal_enable = 2;
}
else
{
//存在校准数据
resohm_out_cal_enable = 1;
//将读到的数据存储至res_ohm_out_calibrate_table[CALIBRATE_RES_OHM_OUT_POINTS]
eeprom_dataread_single(EEPROM_TAG_CAL_RES_OHM_OUT);
}
}
break;
case 1: //执行校准
{
//计算区间间隔(按照规定的点数,在量程范围内平均分配)
float interval = (float32)(CALIBRATE_RES_OHM_OUT_END - CALIBRATE_RES_OHM_OUT_START)/(float32)(CALIBRATE_RES_OHM_OUT_POINTS - 1);
for( uint8_t i = 0; i < CALIBRATE_RES_OHM_OUT_POINTS - 1; i++)
{
if( (res_ohm_out_calibrate_table[i] <= raw)&&(raw <= res_ohm_out_calibrate_table[i + 1]) )
{
result = CALIBRATE_RES_OHM_OUT_START + i*interval; //所处区间的左端点
result += interval * (raw - res_ohm_out_calibrate_table[i])/(res_ohm_out_calibrate_table[i + 1] - res_ohm_out_calibrate_table[i]);
break;
}
}
}
break;
case 2: //不执行校准
{
result = raw;
}
break;
default:
break;
}
return result;
}

View File

@ -1,11 +1,19 @@
#ifndef __DAC7811_H #ifndef __DAC7811_H
#define __DAC7811_H_ #define __DAC7811_H_
#include "data_type_def.h"
#include "data_type_def.h"
#include "eeprom_spi.h"
#define CALIBRATE_RES_OHM_OUT_START 0
#define CALIBRATE_RES_OHM_OUT_END 4000
#define CALIBRATE_RES_OHM_OUT_POINTS 11 #define CALIBRATE_RES_OHM_OUT_POINTS 11
extern BOOL dac7811_spi_init_flag; extern BOOL dac7811_spi_init_flag;
extern float res_ohm_out_calibrate_table[CALIBRATE_RES_OHM_OUT_POINTS];
extern uint8_t resohm_out_cal_enable;
void fun_dac7811_operate(float32 *data_pv); void fun_dac7811_operate(float32 *data_pv);
float32 calibrate_res_ohm_out(float32 raw);
#endif #endif

View File

@ -56,13 +56,27 @@ void set_dac8552_channel_value(dac8552x_object *dac, dac8552_ld_type ld, dac8552
void dac8552_operation(float32 *data1, float32 *data2) void dac8552_operation(float32 *data1, float32 *data2)
{ {
uint16_t data = 0;
float32 temp1 = *data1, temp2 = *data2;
dac8552_init(&dac8552, dac8552_transmit_data, dac8552_cs); dac8552_init(&dac8552, dac8552_transmit_data, dac8552_cs);
uint16_t data = 0;
if (data1 != NULL) if (data1 != NULL)
{ {
temp1 = calibrate_cur_ma(temp1); //对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) if(temp1 > 25.0f)
{ {
temp1 = 25.0f; temp1 = 25.0f;
@ -72,6 +86,7 @@ void dac8552_operation(float32 *data1, float32 *data2)
temp1 = 0.0f; temp1 = 0.0f;
} }
mux_signal.sv_calibrated = temp1; mux_signal.sv_calibrated = temp1;
/**********************************************************/
temp1 = (temp1) * 100.0f; temp1 = (temp1) * 100.0f;
data = (uint16_t)(65535.0f * temp1 / 2500.0f); data = (uint16_t)(65535.0f * temp1 / 2500.0f);
@ -81,13 +96,33 @@ void dac8552_operation(float32 *data1, float32 *data2)
if (data2 != NULL) if (data2 != NULL)
{ {
//-2.5~2.5v输出 //对mux_signal.sv作限幅
if (*data2 < -2.5f) if(*data2 > 2.5f)
*data2 = -2.5f; {
else if (*data2 > 2.5f)
*data2 = 2.5f; *data2 = 2.5f;
}
else if(*data2 < -2.5f)
{
*data2 = -2.5f;
}
temp2 = (*data2) * 0.5f + 1.25f; 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); 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_B, SEL_BUF_B, PD_NONE, data);
set_dac8552_channel_value(&dac8552, LD_CH_A, SEL_BUF_A, PD_NONE, data); set_dac8552_channel_value(&dac8552, LD_CH_A, SEL_BUF_A, PD_NONE, data);
@ -96,9 +131,9 @@ void dac8552_operation(float32 *data1, float32 *data2)
float cur_ma_out_calibrate_table[CALIBRATE_CUR_MA_OUT_POINTS] = {0}; float cur_ma_out_calibrate_table[CALIBRATE_CUR_MA_OUT_POINTS] = {0};
uint8_t curma_out_cal_enable = 0; uint8_t curma_out_cal_enable = 0;
float32 calibrate_cur_ma(float32 raw) float32 calibrate_cur_ma_out(float32 raw)
{ {
float result = 0; float result = 0;
switch (curma_out_cal_enable) switch (curma_out_cal_enable)
{ {
@ -155,4 +190,65 @@ float result = 0;
return result; return result;
} }
float vol_mv_out_calibrate_table[CALIBRATE_VOL_MV_OUT_POINTS] = {0};
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( (vol_mv_out_calibrate_table[i] <= raw)&&(raw <= vol_mv_out_calibrate_table[i + 1]) )
{
result = CALIBRATE_VOL_MV_OUT_START + i*interval; //所处区间的左端点
result += interval * (raw - vol_mv_out_calibrate_table[i])/(vol_mv_out_calibrate_table[i + 1] - vol_mv_out_calibrate_table[i]);
break;
}
}
}
break;
case 2: //不执行校准
{
result = raw;
}
break;
default:
break;
}
return result;
}

View File

@ -47,10 +47,13 @@ typedef struct dac8552_object
extern dac8552x_object dac8552; extern dac8552x_object dac8552;
extern float cur_ma_out_calibrate_table[CALIBRATE_CUR_MA_OUT_POINTS]; extern float cur_ma_out_calibrate_table[CALIBRATE_CUR_MA_OUT_POINTS];
extern uint8_t curma_out_cal_enable; extern uint8_t curma_out_cal_enable;
extern float vol_mv_out_calibrate_table[CALIBRATE_VOL_MV_OUT_POINTS];
extern uint8_t volmv_out_cal_enable;
void dac8552_init(dac8552x_object *dac, dac8552_write write, dac8552_chip_select cs); void dac8552_init(dac8552x_object *dac, dac8552_write write, dac8552_chip_select cs);
void dac8552_operation(float32 *data1, float32 *data2); void dac8552_operation(float32 *data1, float32 *data2);
float32 calibrate_cur_ma(float32 raw); float32 calibrate_cur_ma_out(float32 raw);
float32 calibrate_vol_mv_out(float32 raw);
#endif #endif

View File

@ -613,11 +613,41 @@ void eeprom_datasave_single(uint8_t tag)
break; break;
case EEPROM_TAG_CAL_VOL_MV_OUT: case EEPROM_TAG_CAL_VOL_MV_OUT:
{} {
uint32_t flt[CALIBRATE_VOL_MV_OUT_POINTS] = {0};
memcpy(flt, vol_mv_out_calibrate_table, sizeof(flt));
for(uint8_t i = 0; i < CALIBRATE_VOL_MV_OUT_POINTS; i++)
{
temp_h = flt[i] >> 24;
temp_mh = flt[i] >> 16;
temp_ml = flt[i] >> 8;
temp_l = flt[i] & 0xFF;
eeprom_writedata(CAL_VOL_MV_OUT_ADDR_START + 32*i, temp_h);
eeprom_writedata(CAL_VOL_MV_OUT_ADDR_START + 32*i + 8, temp_mh);
eeprom_writedata(CAL_VOL_MV_OUT_ADDR_START + 32*i + 16, temp_ml);
eeprom_writedata(CAL_VOL_MV_OUT_ADDR_START + 32*i + 24, temp_l);
}
}
break; break;
case EEPROM_TAG_CAL_RES_OHM_OUT: case EEPROM_TAG_CAL_RES_OHM_OUT:
{} {
uint32_t flt[CALIBRATE_RES_OHM_OUT_POINTS] = {0};
memcpy(flt, res_ohm_out_calibrate_table, sizeof(flt));
for(uint8_t i = 0; i < CALIBRATE_RES_OHM_OUT_POINTS; i++)
{
temp_h = flt[i] >> 24;
temp_mh = flt[i] >> 16;
temp_ml = flt[i] >> 8;
temp_l = flt[i] & 0xFF;
eeprom_writedata(CAL_RES_OHM_OUT_ADDR_START + 32*i, temp_h);
eeprom_writedata(CAL_RES_OHM_OUT_ADDR_START + 32*i + 8, temp_mh);
eeprom_writedata(CAL_RES_OHM_OUT_ADDR_START + 32*i + 16, temp_ml);
eeprom_writedata(CAL_RES_OHM_OUT_ADDR_START + 32*i + 24, temp_l);
}
}
break; break;
default: default:
@ -877,11 +907,53 @@ void eeprom_dataread_single(uint8_t tag)
break; break;
case EEPROM_TAG_CAL_VOL_MV_OUT: case EEPROM_TAG_CAL_VOL_MV_OUT:
{} {
uint32_t flt[CALIBRATE_VOL_MV_OUT_POINTS] = {0};
for(uint8_t i = 0; i < CALIBRATE_VOL_MV_OUT_POINTS; i++)
{
temp_h = eeprom_readdata(CAL_VOL_MV_OUT_ADDR_START + 32*i);
temp_mh = eeprom_readdata(CAL_VOL_MV_OUT_ADDR_START + 32*i + 8);
temp_ml = eeprom_readdata(CAL_VOL_MV_OUT_ADDR_START + 32*i + 16);
temp_l = eeprom_readdata(CAL_VOL_MV_OUT_ADDR_START + 32*i + 24);
flt[i] = (temp_h << 24)|(temp_mh << 16)|(temp_ml << 8)|(temp_l);
memcpy(&error_check, flt + i, 4);
if( ((int16_t)error_check > VOL[1].up)||((int16_t)error_check < VOL[1].low) )
{
//任意一个点异常,随即退出,不启用校准
volmv_out_cal_enable = 2;
return;
}
}
memcpy(vol_mv_out_calibrate_table, flt, sizeof(vol_mv_out_calibrate_table));
}
break; break;
case EEPROM_TAG_CAL_RES_OHM_OUT: case EEPROM_TAG_CAL_RES_OHM_OUT:
{} {
uint32_t flt[CALIBRATE_RES_OHM_OUT_POINTS] = {0};
for(uint8_t i = 0; i < CALIBRATE_RES_OHM_OUT_POINTS; i++)
{
temp_h = eeprom_readdata(CAL_RES_OHM_OUT_ADDR_START + 32*i);
temp_mh = eeprom_readdata(CAL_RES_OHM_OUT_ADDR_START + 32*i + 8);
temp_ml = eeprom_readdata(CAL_RES_OHM_OUT_ADDR_START + 32*i + 16);
temp_l = eeprom_readdata(CAL_RES_OHM_OUT_ADDR_START + 32*i + 24);
flt[i] = (temp_h << 24)|(temp_mh << 16)|(temp_ml << 8)|(temp_l);
memcpy(&error_check, flt + i, 4);
if( ((int16_t)error_check > RES.up)||((int16_t)error_check < RES.low) )
{
//任意一个点异常,随即退出,不启用校准
resohm_out_cal_enable = 2;
return;
}
}
memcpy(res_ohm_out_calibrate_table, flt, sizeof(res_ohm_out_calibrate_table));
}
break; break;
} }
} }

View File

@ -150,11 +150,25 @@ void deal_calibrate_affair(void)
break; break;
case CAL_FLAG_VOUT_MV_OUT: case CAL_FLAG_VOUT_MV_OUT:
{} {
//存入vol_v_calibrate_table[CALIBRATE_VOL_V_OUT_POINTS]的数据
eeprom_datasave_single(EEPROM_TAG_CAL_VOL_MV_OUT);
//写入0xAAAA标志
eeprom_writedata(CAL_VOL_MV_OUT_ADDR_FLAG, 0xAA);
eeprom_writedata(CAL_VOL_MV_OUT_ADDR_FLAG + 8, 0xAA);
}
break; break;
case CAL_FLAG_RES_OHM_OUT: case CAL_FLAG_RES_OHM_OUT:
{} {
//存入vol_v_calibrate_table[CALIBRATE_VOL_V_OUT_POINTS]的数据
eeprom_datasave_single(EEPROM_TAG_CAL_RES_OHM_OUT);
//写入0xAAAA标志
eeprom_writedata(CAL_RES_OHM_OUT_ADDR_FLAG, 0xAA);
eeprom_writedata(CAL_RES_OHM_OUT_ADDR_FLAG + 8, 0xAA);
}
break; break;
case CAL_FLAG_CUR_MA_IN: case CAL_FLAG_CUR_MA_IN:

View File

@ -658,6 +658,7 @@ void fun_get_sig16132_ch(uint8_t channel, float32 *data)
else if (channel == 4) //-2.5~2.5V输出反馈 else if (channel == 4) //-2.5~2.5V输出反馈
{ {
*data = 2.0f * voltage - 2.5f; *data = 2.0f * voltage - 2.5f;
*data *= 1000; //V -> mV
} }
else if (channel == 5) // 4`20mA输入检测 else if (channel == 5) // 4`20mA输入检测
{ {

View File

@ -46,7 +46,7 @@ void MX_DAC_Init(void);
/* USER CODE BEGIN Prototypes */ /* USER CODE BEGIN Prototypes */
void dac_set_voltage(float *vol); void dac_set_voltage(float *vol);
float calibrate_vol_v(float raw); float calibrate_vol_v_out(float raw);
extern float vol_v_out_calibrate_table[CALIBRATE_VOL_V_OUT_POINTS]; extern float vol_v_out_calibrate_table[CALIBRATE_VOL_V_OUT_POINTS];
extern uint8_t volv_out_cal_enable; extern uint8_t volv_out_cal_enable;

View File

@ -129,14 +129,23 @@ uint8_t volv_out_cal_enable = 0;
void dac_set_voltage(float *vol) void dac_set_voltage(float *vol)
{ {
if (vol == NULL) if (vol == NULL) return;
return;
//对mux_signal.sv作限幅
if( *vol > 30.0f )
{
*vol = 30.0f;
}
else if ( *vol < 0.0f )
{
*vol = 0.0f;
}
float temp = *vol; float temp = *vol;
/**********在此处进行电压输出V校准temp为目标值**********/ /**********在此处进行电压输出V校准temp为目标值**********/
temp = calibrate_vol_v(temp); temp = calibrate_vol_v_out(temp);
//限幅 //校准后再进行一次限幅,以防运算出错
if( temp > 30.0f ) if( temp > 30.0f )
{ {
temp = 30.0f; temp = 30.0f;
@ -145,7 +154,6 @@ void dac_set_voltage(float *vol)
{ {
temp = 0.0f; temp = 0.0f;
} }
mux_signal.sv_calibrated = temp; mux_signal.sv_calibrated = temp;
/**********************************************************/ /**********************************************************/
@ -158,7 +166,7 @@ void dac_set_voltage(float *vol)
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, temp); HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, temp);
} }
float calibrate_vol_v(float raw) float calibrate_vol_v_out(float raw)
{ {
float result = 0; float result = 0;

File diff suppressed because one or more lines are too long

View File

@ -275,6 +275,16 @@
<WinNumber>1</WinNumber> <WinNumber>1</WinNumber>
<ItemText>cur_ma_out_calibrate_table,0x0A</ItemText> <ItemText>cur_ma_out_calibrate_table,0x0A</ItemText>
</Ww> </Ww>
<Ww>
<count>24</count>
<WinNumber>1</WinNumber>
<ItemText>vol_mv_out_calibrate_table</ItemText>
</Ww>
<Ww>
<count>25</count>
<WinNumber>1</WinNumber>
<ItemText>res_ohm_out_calibrate_table</ItemText>
</Ww>
</WatchWindow1> </WatchWindow1>
<WatchWindow2> <WatchWindow2>
<Ww> <Ww>

File diff suppressed because it is too large Load Diff