sggt/Core/Src/dac.c

220 lines
5.2 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 */
float vol_v_out_calibrate_table[CALIBRATE_VOL_V_OUT_POINTS] = {0};
uint8_t volv_out_cal_enable = 0;
void dac_set_voltage(float *vol)
{
if (vol == NULL)
return;
float temp = *vol;
/**********在此处进行电压输出V校准temp为目标值**********/
temp = calibrate_vol_v(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);
}
float calibrate_vol_v(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( (vol_v_out_calibrate_table[i] <= raw)&&(raw <= vol_v_out_calibrate_table[i + 1]) )
{
result = CALIBRATE_VOL_V_OUT_START + i*interval; //所处区间的左端点
result += interval * (raw - vol_v_out_calibrate_table[i])/(vol_v_out_calibrate_table[i + 1] - vol_v_out_calibrate_table[i]);
break;
}
}
}
break;
case 2: //不执行校准
{
result = raw;
}
break;
default:
break;
}
return result;
}
/* USER CODE END 1 */