2025-04-26 16:03:23 +08:00

393 lines
10 KiB
C
Raw Permalink 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.

/** ##########################################################################
** Filename :
** Project :
** Module :
** Processor :
** Version :
** Compiler :
** Date/Time :
** Abstract :
** Contents :
** Note :
**
** (c) Copyright dmdz Co.,Ltd
** --------------------------------------------------------------------------
** R E V I S I O N H I S T O R Y
** --------------------------------------------------------------------------
** Date Ver Author Description
** -20191106- --V01-- --LYJ--- --初版--
** -20230602- --V1.0-- --mingyea--- --修改--
** #########################################################################*/
/*---------------------------------------------------------------------------
- I N C L U D E F I L E S
----------------------------------------------------------------------------*/
#include "queue_entity.h"
#include "logic_timer.h"
#include "adc.h"
#include "gpio.h"
#include "common_memory.h"
#include "dma.h"
/*---------------------------------------------------------------------------
- D E F I N E S / M A C R O S
----------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
- T Y P E D E F I N I T I O N S
----------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
- S T A T I C V A R I A B L E S
----------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
* G L O B A L V A R I A B L E S
----------------------------------------------------------------------------*/
adc_s g_adc;
/*---------------------------------------------------------------------------
- C O N S T A N T S
----------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------
- F U N C T I O N P R O T O T Y P E
----------------------------------------------------------------------------*/
static void adc_data_operate(void);
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters :
|Output parameters :
|Return value :
|Description :ADC中断服务函数
----------------------------------------------------------------------------*/
void ADC_IRQHandler(void)
{
u8 i;
u32 l_adc_org;
#ifdef ADC_DEBUG_EN
g_adc.test[0]++;
#endif
if((FL_ENABLE == FL_ADC_IsEnabledIT_EndOfConversion(ADC))
&& (FL_SET == FL_ADC_IsActiveFlag_EndOfConversion(ADC)))
{
#ifdef ADC_DEBUG_EN
g_adc.test[1]++;
#endif
i=g_adc.channel_id;
if(i<ADC_LOGIC_CHANNEL_MAX)
{
//将原始值读取
l_adc_org = FL_ADC_ReadConversionData(ADC);
g_adc.channel[i].init_value = l_adc_org;
}
g_adc.channel_id++;
if(g_adc.channel_id>=ADC_LOGIC_CHANNEL_MAX)
{
g_adc.channel_id=0u;
#ifdef ADC_DEBUG_EN
g_adc.test[2]++;
#endif
}
#if 0
if(ADCChannelCount == 0)
{
/* 获取外部通道采样值 */
GetVSample = FL_ADC_ReadConversionData(ADC);
ADCChannelCount++;
}
else
{
/* 获取VREF1P2采样值 */
Get122VSample = FL_ADC_ReadConversionData(ADC);
ADCChannelCount = 0;
ADCComplete = 1U;
}
#endif
}
FL_ADC_ClearFlag_EndOfConversion(ADC);
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters :
|Output parameters :
|Return value :
|Description :ADC初始化
----------------------------------------------------------------------------*/
void AdcInit(void)
{
/* ADC 时钟设置 */
FL_ADC_CommonInit((FL_ADC_CommonInitTypeDef*)&g_ADC_CommonInitStruct);
FL_ADC_Init(ADC, (FL_ADC_InitTypeDef*)&g_ADC_InitStruct);
#ifdef ADC_ENABLE_DMA_MODE
FL_ADC_EnableDMAReq(ADC);
#else
/* 使能通道转换完成中断 */
FL_ADC_EnableIT_EndOfConversion(ADC);
/* NVIC中断配置 */
NVIC_ClearPendingIRQ(ADC_IRQn);
NVIC_DisableIRQ(ADC_IRQn);
NVIC_SetPriority(ADC_IRQn, NVIC_PRIORITY_ADC);
NVIC_EnableIRQ(ADC_IRQn);
#endif
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters : channel_id 见宏 ADC_LOGIC_CHN_BAT 等
|Output parameters :
|Return value :
|Description :
----------------------------------------------------------------------------*/
void adc_init()
{
u8 i;
AdcInit();
dma_init();
common_memory_clear((u8*)&g_adc,sizeof(g_adc));
#if 0
/* 使能通道ADC_IN1 */
FL_ADC_EnableSequencerChannel(ADC, ADC_CHANNEL_1_PHY_ID);
FL_ADC_EnableSequencerChannel(ADC, ADC_CHANNEL_0_PHY_ID);
/* 使能通道ADC_VREF1P2 */
FL_ADC_EnableSequencerChannel(ADC, FL_ADC_INTERNAL_VREF1P2);
#else
//倒序
for(i = 0u; i < ADC_LOGIC_CHANNEL_MAX; i++)
{
FL_ADC_EnableSequencerChannel(ADC, g_adc_drv_channel[i]);
}
#endif
/* 使能VREF BUFFER */
/* 为了考虑功耗BUFFER可关闭从使能到ADC可以正常采样需要100us的建立时间本例程配置慢速通道较长的采样时间来保证建立时间满足。 */
FL_VREF_EnableVREFBuffer(VREF);
FL_ADC_ClearFlag_EndOfConversion(ADC); /* 清标志 */
/* 启动ADC */
FL_ADC_Enable(ADC);
/* 开始转换 */
FL_ADC_EnableSWConversion(ADC);
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters :
|Output parameters :
|Return value :
|Description :
----------------------------------------------------------------------------*/
void adc_de_init(void)
{
FL_ADC_DeInit(ADC);
//FL_ADC_Disable(ADC);
FL_DMA_DeInit(DMA);
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters :
|Output parameters :
|Return value :
|Description : 任務
----------------------------------------------------------------------------*/
void adc_task(void)
{
adc_data_operate();
adc_manage_task();
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters :
|Output parameters :
|Return value :
|Description :
----------------------------------------------------------------------------*/
static void adc_data_operate(void)
{
u8 i;
#ifdef ADC0_CHANNEL_FILETER_EN
u8 k;
u16 l_refh;
u8 l_count=0u;
u8 l_total=0u;
u16 l_sum=0u;
#endif
#ifdef ADC_ENABLE_DMA_MODE
if(FL_DMA_IsActiveFlag_TransferComplete(DMA, FL_DMA_CHANNEL_ADC))
{
#ifdef ADC_DEBUG_EN
g_adc.test[3]++;
#endif
FL_DMA_ClearFlag_TransferComplete(DMA, FL_DMA_CHANNEL_ADC);
#if ADC_ENABLE_DMA_MODE == 0u
FL_ADC_ClearFlag_EndOfConversion(ADC); /* 清标志 */
FL_ADC_Disable(ADC); /* 关闭ADC */
for(i = 0u; i < ADC_LOGIC_CHANNEL_MAX; i++)
{
FL_ADC_DisableSequencerChannel(ADC, g_adc_drv_channel[i]);
}
#endif
i=ADC_LOGIC_CHANNEL_VREF1P2;
g_adc.channel[i].result_value = ( (u32)( (u32)(g_adc.init_value[i] *1000u) / ADC_RESOLUTION_MASK) * (u32)ADC_VREFH)/1000u;
for(i = ADC_LOGIC_CHANNEL_USE_START; i <= ADC_LOGIC_CHANNEL_END; i++)
{
#if 0
g_adc.channel[i].result_value = ( (u32)( (u32)(g_adc.init_value[i] *1000u) / ADC_RESOLUTION_MASK) * (u32)ADC_VREFH)/1000u;
#else //ADC_VREF1P2
g_adc.channel[i].result_value = ((uint64_t)g_adc.init_value[i] * 3000ul * (ADC_VREF)) / ((uint32_t)g_adc.init_value[ADC_LOGIC_CHANNEL_VREF1P2] * 4095);
#endif
}
//如果是单次模式
#if ADC_ENABLE_DMA_MODE == 0u
g_adc.timecount =0u;
g_adc.state =0u;
dma_init();
for(i = 0u; i < ADC_LOGIC_CHANNEL_MAX; i++)
{
FL_ADC_EnableSequencerChannel(ADC, g_adc_drv_channel[i]);
}
/* 使能VREF BUFFER */
/* 为了考虑功耗BUFFER可关闭从使能到ADC可以正常采样需要100us的建立时间本例程配置慢速通道较长的采样时间来保证建立时间满足。 */
FL_VREF_EnableVREFBuffer(VREF);
FL_ADC_ClearFlag_EndOfConversion(ADC); /* 清标志 */
/* 启动ADC */
FL_ADC_Enable(ADC);
/* 开始转换 */
FL_ADC_EnableSWConversion(ADC);
#endif
}
#else
i=ADC_LOGIC_CHANNEL_VREF1P2;
g_adc.channel[i].result_value = ( (u32)( (u32)(g_adc.channel[i].init_value *1000u) / ADC_RESOLUTION_MASK) * (u32)ADC_VREFH)/1000u;
for(i = ADC_LOGIC_CHANNEL_USE_START; i <= ADC_LOGIC_CHANNEL_END; i++)
{
#if 0
g_adc.channel[i].result_value = ( (u32)( (u32)(g_adc.channel[i].init_value *1000u) / ADC_RESOLUTION_MASK) * (u32)ADC_VREFH)/1000u;
#else //ADC_VREF1P2
g_adc.channel[i].result_value = ( (u32)( (u32)(g_adc.channel[i].init_value *ADC_VREF1P2) / g_adc.channel[ADC_LOGIC_CHANNEL_VREF1P2].init_value) );
#endif
}
#endif
//濾波計算
#ifdef ADC0_CHANNEL_FILETER_EN
for(i = 0u; i < ADC_LOGIC_CHANNEL_MAX; i++)
{
l_count = g_adc.channel[i].filter_count;
if(g_adc.channel[i].filter_over == 0u)
{
l_total = l_count+1u;
}
else
{
l_total = ADC0_CHANNEL_FILTER_TIME;
}
g_adc.channel[i].filter_buf[l_count] = g_adc.channel[i].result_value;
l_sum=0u;
for(k=0u;k<l_total;k++)
{
l_sum += g_adc.channel[i].filter_buf[k];
}
g_adc.channel[i].result_filter_value = l_sum/l_total;
//
g_adc.channel[i].filter_count++;
if(g_adc.channel[i].filter_count>=ADC0_CHANNEL_FILTER_TIME)
{
g_adc.channel[i].filter_count=0u;
g_adc.channel[i].filter_over=1u;
}
}
#endif
#if ADC_ENABLE_DMA_MODE == 0u
g_adc.timecount++;
if(g_adc.timecount>=ADC_TASK_TIMEOUT)
{
#ifdef ADC_DEBUG_EN
g_adc.test[4]++;
#endif
g_adc.timecount=0u;
adc_init();
}
g_adc.state =0u;
#endif
}
/*---------------------------------------------------------------------------
|Prototype :
|Called by :
|Preconditions :
|Input parameters : channel_id 见宏 ADC_LOGIC_CHN_BAT 等
|Output parameters :
|Return value :
|Description : 读取最终的值
----------------------------------------------------------------------------*/
adc_voltage_t adc_get_voltage_value(u8 channel_id)
{
adc_voltage_t l_result =0;
if(channel_id<ADC_LOGIC_CHANNEL_MAX)
{
#ifdef ADC0_CHANNEL_FILETER_EN
l_result = g_adc.channel[channel_id].result_filter_value;
#else
l_result = g_adc.channel[channel_id].result_value;
#endif
}
return l_result;
}
/*end line*/