258 lines
6.8 KiB
C
258 lines
6.8 KiB
C
/********************************** (C) COPYRIGHT *******************************
|
|
* File Name : CH59x_adc.c
|
|
* Author : WCH
|
|
* Version : V1.2
|
|
* Date : 2021/11/17
|
|
* Description
|
|
*********************************************************************************
|
|
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
|
|
* Attention: This software (modified or not) and binary are used for
|
|
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
|
|
*******************************************************************************/
|
|
|
|
#include "CH59x_common.h"
|
|
|
|
/*********************************************************************
|
|
* @fn ADC_DataCalib_Rough
|
|
*
|
|
* @brief 采样数据粗调,获取偏差值,必须先配置ADC后调用此函数获取校准值
|
|
*
|
|
* @param none
|
|
*
|
|
* @return 偏差
|
|
*/
|
|
signed short ADC_DataCalib_Rough(void) // 采样数据粗调,获取偏差值
|
|
{
|
|
uint16_t i;
|
|
uint32_t sum = 0;
|
|
uint8_t ch = 0; // 备份通道
|
|
uint8_t cfg = 0; // 备份
|
|
|
|
ch = R8_ADC_CHANNEL;
|
|
cfg = R8_ADC_CFG;
|
|
|
|
R8_ADC_CFG |= RB_ADC_OFS_TEST; // 进入测试模式
|
|
R8_ADC_CFG &= ~RB_ADC_DIFF_EN; // 关闭差分
|
|
|
|
R8_ADC_CONVERT |= RB_ADC_START;
|
|
while(R8_ADC_CONVERT & RB_ADC_START);
|
|
for(i = 0; i < 16; i++)
|
|
{
|
|
R8_ADC_CONVERT |= RB_ADC_START;
|
|
while(R8_ADC_CONVERT & RB_ADC_START);
|
|
sum += (~R16_ADC_DATA) & RB_ADC_DATA;
|
|
}
|
|
sum = (sum + 8) >> 4;
|
|
|
|
R8_ADC_CFG = cfg; // 恢复配置值
|
|
R8_ADC_CHANNEL = ch;
|
|
|
|
return (2048 - sum);
|
|
}
|
|
|
|
/*********************************************************************
|
|
* @fn ADC_ExtSingleChSampInit
|
|
*
|
|
* @brief 外部信号单通道采样初始化
|
|
*
|
|
* @param sp - refer to ADC_SampClkTypeDef
|
|
* @param ga - refer to ADC_SignalPGATypeDef
|
|
*
|
|
* @return none
|
|
*/
|
|
void ADC_ExtSingleChSampInit(ADC_SampClkTypeDef sp, ADC_SignalPGATypeDef ga)
|
|
{
|
|
R8_TKEY_CFG &= ~RB_TKEY_PWR_ON;
|
|
R8_ADC_CFG = RB_ADC_POWER_ON | RB_ADC_BUF_EN | (sp << 6) | ((ga&0xF) << 4);
|
|
if( ga & ADC_PGA_2_ )
|
|
{
|
|
R8_ADC_CONVERT |= RB_ADC_PGA_GAIN2;
|
|
}
|
|
else
|
|
{
|
|
R8_ADC_CONVERT &= ~RB_ADC_PGA_GAIN2;
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
* @fn ADC_ExtDiffChSampInit
|
|
*
|
|
* @brief 外部信号差分通道采样初始化
|
|
*
|
|
* @param sp - refer to ADC_SampClkTypeDef
|
|
* @param ga - refer to ADC_SignalPGATypeDef
|
|
*
|
|
* @return none
|
|
*/
|
|
void ADC_ExtDiffChSampInit(ADC_SampClkTypeDef sp, ADC_SignalPGATypeDef ga)
|
|
{
|
|
R8_TKEY_CFG &= ~RB_TKEY_PWR_ON;
|
|
R8_ADC_CFG = RB_ADC_POWER_ON | RB_ADC_DIFF_EN | (sp << 6) | ((ga&0xF) << 4);
|
|
if( ga & ADC_PGA_2_ )
|
|
{
|
|
R8_ADC_CONVERT |= RB_ADC_PGA_GAIN2;
|
|
}
|
|
else
|
|
{
|
|
R8_ADC_CONVERT &= ~RB_ADC_PGA_GAIN2;
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
* @fn ADC_InterTSSampInit
|
|
*
|
|
* @brief 内置温度传感器采样初始化
|
|
*
|
|
* @param none
|
|
*
|
|
* @return none
|
|
*/
|
|
void ADC_InterTSSampInit(void)
|
|
{
|
|
R8_TKEY_CFG &= ~RB_TKEY_PWR_ON;
|
|
R8_TEM_SENSOR = RB_TEM_SEN_PWR_ON;
|
|
R8_ADC_CHANNEL = CH_INTE_VTEMP;
|
|
R8_ADC_CFG = RB_ADC_POWER_ON | RB_ADC_DIFF_EN | (3 << 4);
|
|
R8_ADC_CONVERT &= ~RB_ADC_PGA_GAIN2;
|
|
}
|
|
|
|
/*********************************************************************
|
|
* @fn ADC_InterBATSampInit
|
|
*
|
|
* @brief 内置电池电压采样初始化
|
|
*
|
|
* @param none
|
|
*
|
|
* @return none
|
|
*/
|
|
void ADC_InterBATSampInit(void)
|
|
{
|
|
R8_TKEY_CFG &= ~RB_TKEY_PWR_ON;
|
|
R8_ADC_CHANNEL = CH_INTE_VBAT;
|
|
R8_ADC_CFG = RB_ADC_POWER_ON | RB_ADC_BUF_EN | (0 << 4); // 使用-12dB模式
|
|
R8_ADC_CONVERT &= ~RB_ADC_PGA_GAIN2;
|
|
}
|
|
|
|
/*********************************************************************
|
|
* @fn TouchKey_ChSampInit
|
|
*
|
|
* @brief 触摸按键通道采样初始化
|
|
*
|
|
* @param none
|
|
*
|
|
* @return none
|
|
*/
|
|
void TouchKey_ChSampInit(void)
|
|
{
|
|
R8_ADC_CFG = RB_ADC_POWER_ON | RB_ADC_BUF_EN | (ADC_PGA_0 << 4) | (SampleFreq_8 << 6);
|
|
R8_ADC_CONVERT &= ~RB_ADC_PGA_GAIN2;
|
|
R8_TKEY_CFG |= RB_TKEY_PWR_ON;
|
|
}
|
|
|
|
/*********************************************************************
|
|
* @fn ADC_ExcutSingleConver
|
|
*
|
|
* @brief ADC执行单次转换
|
|
*
|
|
* @param none
|
|
*
|
|
* @return ADC转换后的数据
|
|
*/
|
|
uint16_t ADC_ExcutSingleConver(void)
|
|
{
|
|
R8_ADC_CONVERT |= RB_ADC_START;
|
|
while(R8_ADC_CONVERT & RB_ADC_START);
|
|
|
|
return (R16_ADC_DATA & RB_ADC_DATA);
|
|
}
|
|
|
|
/*********************************************************************
|
|
* @fn TouchKey_ExcutSingleConver
|
|
*
|
|
* @brief TouchKey转换后数据
|
|
*
|
|
* @param charg - Touchkey充电时间,5bits有效, t=charg*Tadc
|
|
* @param disch - Touchkey放电时间,3bits有效, t=disch*Tadc
|
|
*
|
|
* @return 当前TouchKey等效数据
|
|
*/
|
|
uint16_t TouchKey_ExcutSingleConver(uint8_t charg, uint8_t disch)
|
|
{
|
|
R8_TKEY_COUNT = (disch << 5) | (charg & 0x1f);
|
|
R8_TKEY_CONVERT = RB_TKEY_START;
|
|
while(R8_TKEY_CONVERT & RB_TKEY_START);
|
|
return (R16_ADC_DATA & RB_ADC_DATA);
|
|
}
|
|
|
|
/*********************************************************************
|
|
* @fn ADC_AutoConverCycle
|
|
*
|
|
* @brief 设置连续 ADC的周期
|
|
*
|
|
* @param cycle - 采样周期计算方法为(256-cycle)*16*Tsys
|
|
*
|
|
* @return none
|
|
*/
|
|
void ADC_AutoConverCycle(uint8_t cycle)
|
|
{
|
|
R8_ADC_AUTO_CYCLE = cycle;
|
|
}
|
|
|
|
/*********************************************************************
|
|
* @fn ADC_DMACfg
|
|
*
|
|
* @brief 配置DMA功能
|
|
*
|
|
* @param s - 是否打开DMA功能
|
|
* @param startAddr - DMA 起始地址
|
|
* @param endAddr - DMA 结束地址
|
|
* @param m - 配置DMA模式
|
|
*
|
|
* @return none
|
|
*/
|
|
void ADC_DMACfg(uint8_t s, uint32_t startAddr, uint32_t endAddr, ADC_DMAModeTypeDef m)
|
|
{
|
|
if(s == DISABLE)
|
|
{
|
|
R8_ADC_CTRL_DMA &= ~(RB_ADC_DMA_ENABLE | RB_ADC_IE_DMA_END);
|
|
}
|
|
else
|
|
{
|
|
R16_ADC_DMA_BEG = startAddr&0xFFFF;
|
|
R16_ADC_DMA_END = endAddr&0xFFFF;
|
|
if(m)
|
|
{
|
|
R8_ADC_CTRL_DMA |= RB_ADC_DMA_LOOP | RB_ADC_IE_DMA_END | RB_ADC_DMA_ENABLE;
|
|
}
|
|
else
|
|
{
|
|
R8_ADC_CTRL_DMA &= ~RB_ADC_DMA_LOOP;
|
|
R8_ADC_CTRL_DMA |= RB_ADC_IE_DMA_END | RB_ADC_DMA_ENABLE;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*********************************************************************
|
|
* @fn adc_to_temperature_celsius
|
|
*
|
|
* @brief Convert ADC value to temperature(Celsius)
|
|
*
|
|
* @param adc_val - adc value
|
|
*
|
|
* @return temperature (Celsius)
|
|
*/
|
|
|
|
int adc_to_temperature_celsius(uint16_t adc_val)
|
|
{
|
|
uint32_t C25 = 0;
|
|
int temp;
|
|
|
|
C25 = (*((PUINT32)ROM_CFG_TMP_25C));
|
|
|
|
/* current temperature = standard temperature + (adc deviation * adc linearity coefficient) */
|
|
temp = (((C25 >> 16) & 0xFFFF) ? ((C25 >> 16) & 0xFFFF) : 25) + \
|
|
(adc_val - ((int)(C25 & 0xFFFF))) * 100 / 283;
|
|
|
|
return (temp);
|
|
}
|