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); | ||
|  | } |