sggt/App/DAC7811/dac7811.c

140 lines
3.4 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 "dac7811.h"
#include "ads1220.h"
#include "spi.h"
#include "gpio.h"
#include "stm32f407xx.h"
BOOL dac7811_spi_init_flag = FALSE;
void fun_dac7811_spi1_init()
{
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
ADS1220_CS(GPIO_PIN_SET);
//DAC7811_CS(GPIO_PIN_SET);
}
void fun_dac7811_operate(float32 *data_sv)
{
if (data_sv == NULL) return;
if(*data_sv > 4000)
{
*data_sv = 4000;
}
else if (*data_sv < 0)
{
*data_sv = 0;
}
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 &= 0x1fff;
if (dac7811_spi_init_flag == FALSE)
{
fun_dac7811_spi1_init();
ads1220_spi_init_flag = FALSE;
dac7811_spi_init_flag = TRUE;
}
else
{
//DAC7811_CS(GPIO_PIN_RESET);
HAL_SPI_Transmit(&hspi1, (uint8_t *)(&reg_data), 1, 1000);
//DAC7811_CS(GPIO_PIN_SET);
}
}
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( (cali_paras.cali_res_ohm_out[i] <= raw)&&(raw <= cali_paras.cali_res_ohm_out[i + 1]) )
{
result = CALIBRATE_RES_OHM_OUT_START + i*interval; //所处区间的左端点
result += interval * (raw - cali_paras.cali_res_ohm_out[i])/(cali_paras.cali_res_ohm_out[i + 1] - cali_paras.cali_res_ohm_out[i]);
break;
}
}
}
break;
case 2: //不执行校准
{
result = raw;
}
break;
default:
break;
}
return result;
}