1. 简介
杰发的芯片都自带内部温度检测,在ADC通道中获取即可。
7801自带了温度检测例程,7840不带,因此在这里分享一下相关温度检测代码。
根据产线反馈,7840在常温时候25℃比较准,温箱测试,高温和低温下有5℃的误差。
2. 使用BG校准,增大采样时间
直接采集内部温度adc通道,值不是很准确,可以考虑使用内部BG对ADC值进行校准。
void ADC_Init(void)
{
adc_converter_config_t adcConfig;
/*! ADC输入端口(电位器)配置*/
GPIO_DRV_SetMuxModeSel(VR1_PORT, VR1_PIN, PORT_PIN_DISABLED); /*! 电位器VR1*/
GPIO_DRV_SetMuxModeSel(VR2_PORT, VR2_PIN, PORT_PIN_DISABLED); /*! 电位器VR2*/
/*! ADC配置
配置ADC为12位分辨率,工作模式为MODE3规则组扫描+注入组扫描模式多通道单次转换,规则组长度为4。
每触发一次进行一次ADC转换,每次转换规则组中的4个通道。
*/
ADC_DRV_Init(ADC_INDEX);
ADC_DRV_InitConverterStruct(&adcConfig);
adcConfig.clockDivide = ADC_CLK_DIVIDE_6; /*! ADC时钟分频。ADC时钟源选择在时钟初始化里配置,此例程选择为SPLLDIV2_CLK,频率为60MHz*/
adcConfig.resolution = ADC_RESOLUTION_12BIT; /*! ADC分辨率设置*/
adcConfig.regularTrigger = ADC_TRIGGER_INTERNAL; /*! 规则组触发源类型选择*/
adcConfig.injectTrigger = ADC_TRIGGER_INTERNAL; /*! 注入组触发源类型选择*/
adcConfig.dmaEnable = false; /*! DMA使能位*/
adcConfig.voltageRef = ADC_VOLTAGEREF_VREF; /*! ADC参考电压源选择,VREF/VDDA*/
adcConfig.scanModeEn = true; /*! 工作模式配置:扫描模式使能位,多通道时需要使能扫描模式,单个通道时不需要使能扫描*/
adcConfig.continuousModeEn = false; /*! 工作模式配置:连续模式使能位,1:触发后可连续转换,0:触发一次只转换一次,转换完成后停止*/
adcConfig.regularDiscontinuousModeEn = false; /*! 工作模式配置:规则组不连续模式使能位*/
adcConfig.injectDiscontinuousModeEn = false; /*! 工作模式配置:注入组不连续模式使能位*/
adcConfig.injectAutoModeEn = false; /*! 工作模式配置:自动注入模式使能位*/
adcConfig.intervalModeEn = false; /*! 工作模式配置:间隔模式使能位*/
adcConfig.regularDiscontinuousNum = 0; /*! 规则组子组长度 (用于mode7)*/
adcConfig.regularSequenceLength = 4; /*! 规则组长度设置*/
adcConfig.injectSequenceLength = 0; /*! 注入组长度设置*/
adcConfig.powerEn = true; /*! ADC上电*/
ADC_DRV_ConfigConverter(ADC_INDEX, &adcConfig); /*! 初始化ADC配置*/
/*! ADC通道配置*/
ADC_ConfigChannel(ADC_INDEX, ADC_RSEQ_0, VR1_ADC_CH); /*! 电位器VR1对应通道*/
ADC_ConfigChannel(ADC_INDEX, ADC_RSEQ_1, VR2_ADC_CH); /*! 电位器VR2对应通道*/
ADC_ConfigChannel(ADC_INDEX, ADC_RSEQ_2, ADC_CH_TSENSOR); /*! 内部温度传感器通道*/
ADC_ConfigChannel(ADC_INDEX, ADC_RSEQ_3, ADC_CH_BANDGAP); /*! ADC_CH_BANDGAP */
//ADC_ConfigChannel(ADC_INDEX, ADC_RSEQ_4, ADC_CH_SUPPLY); /*! 内部供电电压通道*/
}
对采样时间没有要求的话,在初始化时候可以增加采样时间
/*!
ADC采样转换时间计算:
FCLK 时钟源为SPLLDIV2_CLK,频率为60MHz
ADCCLK = FCLK/clockDivide = 60/6 = 10MHz
总转换时间 = (SPT+ resolution(12/10/8))×ADCCLK周期+5个FCLK = (5+12)/10+5/60 ≈ 1.78us
注意:12bit分辨率最大转换率为1Msps,10bit分辨率最大转换率为1.2Msps,8bit分辨率最大转换率为1.4Msps
*/
周期5是1.78us,按照公式计算,185是 (5+12)/10+185/60 = 4.78us
在计算时候使用BG进行校准
bg电压在开发板上测试,3.3v时候测出来是1500,5V时候测出来960左右。
BG电压实际上1.2V,即1200mV,对应的是1200的ad值才对,目前7801上测试1200很准,可能7840的值和7801不一样。
void ADC_TriggerTest(void)
{
ADC_DRV_SoftwareStartRegularConvert(ADC_INDEX); /*! ADC软件触发*/
while (!ADC_DRV_GetConvCompleteFlag(ADC_INDEX, ADC_RSEQ_3)); /*! 等待ADC最后一个通道转换完成*/
ADC_DRV_GetSeqResult(ADC_INDEX, ADC_RSEQ_0, &g_adc_array[0]); /*! 获取规则组0的转换值*/
ADC_DRV_GetSeqResult(ADC_INDEX, ADC_RSEQ_1, &g_adc_array[1]);
ADC_DRV_GetSeqResult(ADC_INDEX, ADC_RSEQ_2, &g_adc_array[2]);
ADC_DRV_GetSeqResult(ADC_INDEX, ADC_RSEQ_3, &g_adc_array[3]);
//ADC_DRV_GetSeqResult(ADC_INDEX, ADC_RSEQ_3, &g_adc_array[4]);
/*! 打印ADC各通道转换结果*/
convertVal = (float)g_adc_array[2] / (float)g_adc_array[3]; // bgADC /1200 = TempADC/TempVol
convertVol = convertVal*1200;
temperatureVal = 25 - (convertVol - 673 )/1.788 ;
}