软件环境:keil 5.23
硬件环境:AC7811 demo板
有些客户使用我们芯片内部的温度传感器,但发现计算出来的温度值偏差太大,这里给大家提供一个计算温度的demo
- #include "ac78xx.h"
- #include "ac78xx_adc.h"
- uint32_t ADC_Average(uint32_t *uADC_Value, uint32_t num)
- {
- uint32_t Max, Min, AVERAGE, SUM, j;
- Max = uADC_Value[0];
- Min = uADC_Value[0];
- SUM = 0;
- AVERAGE = 0;
- j = 0;
- for (j = 0; j < num; j++)
- {
- SUM += uADC_Value[j];
- if(uADC_Value[j] > Max)
- {
- Max = uADC_Value[j];
- }
- else if (uADC_Value[j] < Min)
- {
- Min = uADC_Value[j];
- }
- }
- SUM = SUM - Max - Min;
- AVERAGE = SUM / (num - 2);
- return(AVERAGE);
- }
- uint32_t bandGapAVG = 0;
- uint32_t bandGapTmp[8];
- uint32_t adcVal = 0;
- uint8_t bIndex = 0;
- float bgVol = 0.0;
- float vt25Vol = 0.0;
- float vt25Temprature = 0.0;
- float referVol = 0.0, TsensorVol = 0.0;
- float g_temperatureVal = 0.0;
- uint32_t TsensorCali = 0;
- uint8_t VbandgapRT = 0;
- uint8_t VtsensorRT = 0;
- uint8_t RTERR = 0;
- #define TSENSOR_CALI_ENABLE
- float ADC_GetTemperature(void)
- {
- ADC_InitType tempAdcConfig = {0, 0, 0, 0, 0, 0, 0};
- ADC_TrigSourceType tempAdcTrigSource = {0, 0};
- ADC_InitType* adcConfig;
- ADC_TrigSourceType* adcTrigSource;
- float temperatureVal = 0.0;
-
- adcConfig = &tempAdcConfig;
- adcTrigSource = &tempAdcTrigSource;
- adcConfig->scanMode = 0;
- adcConfig->continousMode = 0;
- adcConfig->disContinousModeOnRegularGroup = 0;
- adcConfig->disContinousModeOnInjectGroup = 0;
- adcConfig->injectAutoMode = 0;
- ADC_Init(ADC, adcConfig);
- ADC_SetClockPrescaler(ADC, 7);
- ADC_TrigSourceInit(ADC, adcTrigSource);
- ADC_SetRegularGroupLength(ADC, 1);
- ADC_SetRegularGroupSequence(ADC, 1, ADC_CHANNEL_AD16_BANDGAP); ///set ADC_CHANNEL_AD16_BANDGAP for AD Sample
- ADC_ChannelSampleTimeSel(ADC, ADC_CHANNEL_AD16_BANDGAP, ADC_SampleTime_215Cycle);
- ADC_Cmd(ADC, ADC_ENABLE);
- #ifdef TSENSOR_CALI_ENABLE
- TsensorCali = *((uint32_t*)0x40003050);
- VbandgapRT = (uint8_t)(TsensorCali & 0x1F);
- VtsensorRT = (uint8_t)((TsensorCali >> 5) & 0xFF);
- RTERR = (uint8_t)((TsensorCali >> 13) & 0x3F);
- printf("[ADC]TsensorCali is %u %u %u %u\r\n", TsensorCali, VbandgapRT, VtsensorRT, RTERR);
- /* BG calibration */
- if (VbandgapRT >> 4)
- {
- bgVol = 1200 - (VbandgapRT & 0xF);
- }
- else
- {
- bgVol = 1200 + (VbandgapRT & 0xF);
- }
- /* Vtsensor calibration */
- if (VtsensorRT >> 7)
- {
- vt25Vol = 720 - (VtsensorRT & 0x7F) * 0.5;
- }
- else
- {
- vt25Vol = 720 + (VtsensorRT & 0x7F) * 0.5;
- }
- /* Temperature calibration */
- if (RTERR >> 5)
- {
- vt25Temprature = 25 - (RTERR & 0x0F) * 0.5;
- }
- else
- {
- vt25Temprature = 25 + (RTERR & 0x0F) * 0.5;
- }
- #else
- bgVol = 1200;
- vt25Vol = 720;
- vt25Temprature = 25;
- #endif
- for (bIndex = 0; bIndex < 8; bIndex++)
- {
- ADC_SoftwareStartRegularConvCmd(ADC, 1);
- while (!ADC_GetIntFlag(ADC, ADC_FLAG_EOC));
- bandGapTmp[bIndex] = ADC_GetRegularConversionValue(ADC);
- }
-
- bandGapAVG = ADC_Average(bandGapTmp , 8);
- referVol = 4096.0 * bgVol / bandGapAVG;
-
- ADC_SetRegularGroupSequence(ADC, 1, ADC_CHANNEL_AD17_TEMPSENSOR);
- ADC_ChannelSampleTimeSel(ADC, ADC_CHANNEL_AD17_TEMPSENSOR, ADC_SampleTime_215Cycle);
- udelay(5);
- ADC_SoftwareStartRegularConvCmd(ADC, ADC_ENABLE);
- while (!ADC_GetIntFlag(ADC, ADC_FLAG_EOC));
- adcVal = ADC_GetRegularConversionValue(ADC);
- TsensorVol = (adcVal / 4096.0) * referVol;
- temperatureVal = (vt25Vol - TsensorVol) / 1.629 + vt25Temprature;
-
- printf("[ADC]Tsensor temperature:%f\r\n", temperatureVal);
- return temperatureVal;
- }
误差嘛,我也没有严格的测试过,但是对比直接通过数据手册的参数计算,感觉误差确实要小一点。
|