sggt/Core/Src/dac.c

227 lines
5.3 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.

/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file dac.c
* @brief This file provides code for the configuration
* of the DAC instances.
******************************************************************************
* @attention
*
* Copyright (c) 2024 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "dac.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
DAC_HandleTypeDef hdac;
/* DAC init function */
void MX_DAC_Init(void)
{
/* USER CODE BEGIN DAC_Init 0 */
/* USER CODE END DAC_Init 0 */
DAC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN DAC_Init 1 */
/* USER CODE END DAC_Init 1 */
/** DAC Initialization
*/
hdac.Instance = DAC;
if (HAL_DAC_Init(&hdac) != HAL_OK)
{
Error_Handler();
}
/** DAC channel OUT1 config
*/
sConfig.DAC_Trigger = DAC_TRIGGER_NONE;
sConfig.DAC_OutputBuffer = DAC_OUTPUTBUFFER_DISABLE;
if (HAL_DAC_ConfigChannel(&hdac, &sConfig, DAC_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN DAC_Init 2 */
HAL_DAC_Start(&hdac, DAC_CHANNEL_1);
/* USER CODE END DAC_Init 2 */
}
void HAL_DAC_MspInit(DAC_HandleTypeDef* dacHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(dacHandle->Instance==DAC)
{
/* USER CODE BEGIN DAC_MspInit 0 */
/* USER CODE END DAC_MspInit 0 */
/* DAC clock enable */
__HAL_RCC_DAC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**DAC GPIO Configuration
PA4 ------> DAC_OUT1
*/
GPIO_InitStruct.Pin = CV_DAC_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(CV_DAC_GPIO_Port, &GPIO_InitStruct);
/* DAC interrupt Init */
HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);
/* USER CODE BEGIN DAC_MspInit 1 */
/* USER CODE END DAC_MspInit 1 */
}
}
void HAL_DAC_MspDeInit(DAC_HandleTypeDef* dacHandle)
{
if(dacHandle->Instance==DAC)
{
/* USER CODE BEGIN DAC_MspDeInit 0 */
/* USER CODE END DAC_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_DAC_CLK_DISABLE();
/**DAC GPIO Configuration
PA4 ------> DAC_OUT1
*/
HAL_GPIO_DeInit(CV_DAC_GPIO_Port, CV_DAC_Pin);
/* DAC interrupt Deinit */
/* USER CODE BEGIN DAC:TIM6_DAC_IRQn disable */
/**
* Uncomment the line below to disable the "TIM6_DAC_IRQn" interrupt
* Be aware, disabling shared interrupt may affect other IPs
*/
/* HAL_NVIC_DisableIRQ(TIM6_DAC_IRQn); */
/* USER CODE END DAC:TIM6_DAC_IRQn disable */
/* USER CODE BEGIN DAC_MspDeInit 1 */
/* USER CODE END DAC_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
void dac_set_voltage(float *vol)
{
if (vol == NULL) return;
//对mux_signal.sv作限幅
if( *vol > 30.0f )
{
*vol = 30.0f;
}
else if ( *vol < 0.0f )
{
*vol = 0.0f;
}
float temp = *vol;
/**********在此处进行电压输出V校准temp为目标值**********/
temp = calibrate_vol_v_out(temp);
//校准后再进行一次限幅,以防运算出错
if( temp > 30.0f )
{
temp = 30.0f;
}
else if ( temp < 0.0f )
{
temp = 0.0f;
}
mux_signal.sv_calibrated = temp;
/**********************************************************/
temp /= 10.0f;
temp = temp * 4096 / 3.0f;
if (temp >= 4096)
temp = 4095;
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, temp);
}
uint8_t volv_out_cal_enable = 0;
float calibrate_vol_v_out(float raw)
{
float result = 0;
switch (volv_out_cal_enable)
{
case 0: //开机后只读一次
{
uint16_t cal_check = 0;
cal_check = eeprom_readdata(CAL_VOL_V_OUT_ADDR_FLAG) << 8;
cal_check |= eeprom_readdata(CAL_VOL_V_OUT_ADDR_FLAG + 8) & 0x00FF;
if(cal_check != 0xAAAA)
{
//不存在校准数据
volv_out_cal_enable = 2;
}
else
{
//存在校准数据
volv_out_cal_enable = 1;
//将读到的数据存储至vol_v_calibrate_table
eeprom_dataread_single(EEPROM_TAG_CAL_VOL_V_OUT);
}
}
break;
case 1: //执行校准
{
//计算区间间隔(按照规定的点数,在量程范围内平均分配)
float interval = (float32)(CALIBRATE_VOL_V_OUT_END - CALIBRATE_VOL_V_OUT_START)/(float32)(CALIBRATE_VOL_V_OUT_POINTS - 1);
for( uint8_t i = 0; i < CALIBRATE_VOL_V_OUT_POINTS - 1; i++)
{
if( (cali_paras.cali_vol_V_out[i] <= raw)&&(raw <= cali_paras.cali_vol_V_out[i + 1]) )
{
result = CALIBRATE_VOL_V_OUT_START + i*interval; //所处区间的左端点
result += interval * (raw - cali_paras.cali_vol_V_out[i])/(cali_paras.cali_vol_V_out[i + 1] - cali_paras.cali_vol_V_out[i]);
break;
}
}
}
break;
case 2: //不执行校准
{
result = raw;
}
break;
default:
break;
}
return result;
}
/* USER CODE END 1 */