Hello to everyone on the NXP support team.
I am currently working on a project using the S32K314, RTD 7.0.0, and FreeRTOS. I am trying to implement the measurement of the voltage of an external device connected to the MCU, the internal temperature (TEMPSENSE) of the MCU, the internal voltage (ANAMUX) of the MCU, and the bandgap voltage using the MCAL's ADC module. Looking at the measurement results, the voltage of the external device and the bandgap voltage seem to be measured correctly, but the values of the internal temperature and internal voltage of the MCU are different from what I expected.
Expected value:
MCU internal voltage (VDD_HV_A):
8192 (2.5V, 14-bit resolution)
Actual measured value:
Approximately 6800–7100 (2.07–2.13V, 14-bit resolution)
The MCU power supply voltage is 5.0V. The ADC hardware unit is set to ADC0, and the ADC measurement target is configured as follows:
ADC initialization code:
void AdcAdapter_Init ( void )
{
Adc_Calibrate ( ADC0 , & calStatus ) ;
Adc_SetupResultBuffer ( ADC0 , Group0Result ) ;
IP_DCM_GPR -> DCMRWF1 = ( IP_DCM_GPR -> DCMRWF1
| DCM_GPR_DCMRWF1_SUPPLY_MON_EN ( 1 )
| DCM_GPR_DCMRWF1_VDD_HV_A_VLT_DVDR_EN ( 1 )
| DCM_GPR_DCMRWF1_VDD_HV_B_VLT_DVDR_EN ( 1 )
| DCM_GPR_DCMRWF1_VDD_1_5_VLT_DVDR_EN ( 1 )
) ;
IP_DCM_GPR -> DCMRWF1 = ( IP_DCM_GPR -> DCMRWF1 & ~ DCM_GPR_DCMRWF1_SUPPLY_MON_SEL_MASK ) | DCM_GPR_DCMRWF1_SUPPLY_MON_SEL ( 0U ) ; // VDD_HV_A_DIV
Adc_StartGroupConversion ( ADC0 ) ; // AdcConversionStart
}ADC data acquisition (all periodic tasks)
void AdcAdapter_RunCyclic ( void )
{
Adc_StatusType ret = ADC_IDLE ;
Std_ReturnType adcStatus ;
uint16 temperature ;
// 変換完了チェック
ret = Adc_GetGroupStatus ( ADC0 ) ;
if ( ( ret == ADC_COMPLETED ) || ( ret == ADC_STREAM_COMPLETED ) ) {
// 結果を取得
Adc_ReadGroup ( ADC0 , Group0Result ) ;
// 次の変換を開始
Adc_StartGroupConversion ( ADC0 ) ;
} else {
// エラーログ
}
/* Adc_TempSenseGetTemp Singed Q11.4 */
adcStatus = Adc_TempSenseGetTemp ( ADC0 , mcuTemperature ) ;
if ( E_OK == adcStatus ) {
temperature = Adc_TempSenseCalculateTemp ( ADC0 , mcuTemperature ) ;
} else {
// エラーログ
}
}I believe the ADC values for the ADC0 group can be updated using `Adc_ReadGroup`, but I think you need to use `Adc_TempSenseGetTemp` and `Adc_TempSenseCalculateTemp` to check the MCU's internal temperature. Please let me know if I've overlooked any settings.
Hi Senlent-san,
Thank you for your quick response.
I have already reviewed the sample code you provided and believe I have incorporated it into my code.
I interpreted the table you provided as a table of register settings for each clock supplied to the ADC block. However, I was unable to determine which of the ADC settings in MCAL they correspond to.
Since I am unable to provide the source code, I am attaching an image of the ADC settings. Please let me know which settings I should change.
If there are any other settings screens you need, please let me know.
Hi@Teruhiko
I didn't see the complete ADC configuration in the information you provided, so please double-check that the ADC clock matches the datasheet requirements.
If possible, you can share your test project with me, and I'll check it for you.
by the way, take a look at the demo in the link below:
Hi Senlent-san,
Thank you for your advice.
Following your advice, I changed the settings as shown below to set the TEMPSENSE sampling time to 1.2 usec.
160MHz = 0.00625usec
1.2usec/0.00625usec = 192
I created a task with a 1-second cycle in FreeRTOS and acquired the ADC values for the MCU voltage (VDD_HV_A) and MCU temperature (TEMPSENSE) every second (collecting 30 seconds’ worth of data).
For the MCU voltage, I used the bandgap voltage and converted it to mV using the following compensation formula.
(The bandgap voltage showed almost no fluctuation, with a value of around 3975 (approximately 1.2 V) obtained.)
AdcCorrection = (1200(mV) * Adc_VCC_HV_A) / Adc_bandgap
Mcu Voltage = AdcCorrection * 2 (2 is the voltage division ratio of VDD_HV_A)
Additionally, the McuTemp data comes from `Adc_TempSenseGetTemp(ADC0, &mcuTemperature)`.
Even taking into account the ADC conversion error of +/- 5.0%, I believe the variation is too large. Are there any suggested solutions?
Hi@Teruhiko
From the configuration screenshots and code you provided, I don't see any obvious errors. However, it's important to note that the temperature sensor's sampling time must be greater than 1.2µs; otherwise, it will affect the sampling accuracy. Therefore, I suggest you double check the sampling time before testing.
The image for ADC_Config>AdcHwUnit was compressed, resulting in a loss of resolution, so I am re-uploading it.
<#1>
<#2>
<#3>
Hi Senlent-san,
Thank you for attaching the documentation. Since I am currently measuring channels 32–63, I understand that this corresponds to Sampling Duration 1.
Thank you for your prompt response. The issue has been resolved.
Hi@Teruhiko
You can directly read the raw data from the temperature channel to observe whether there are fluctuations. If the fluctuations are large, you can continue to try increasing the sampling time.
Hi Senlent-san,
I interpreted the information in Table 317 as follows.
When fmc = 160 MHz:
・ Set the prescaler for calibration to 4
・ Set the prescaler for normal ADC conversion to 2
・ Set “ADC High Speed” to Disable
The data obtained by applying these settings is shown in the table below.
Although averaging reduced the variation, I feel that the variation in the MCU’s internal temperature is still quite significant.
The table below shows the MCU temperature data converted from ADC values to °C.
(To convert the ADC values to °C, I divided the ADC values by 16.)
A variation of 2.55 degrees over a 16-point average is extremely large. I understand that the MCU temperature fluctuates depending on the processing load, but is it normal for it to change this much instantaneously?
When measuring the internal temperature of the MCU, is averaging the correct approach?
Hi Senlent-san,
Thank you for you reply.
As shown in the figure below, the values stabilized after I increased the Sampling Duration 1/Duration 2 values. I thought the default setting was Sampling Duration 0, but how can I switch between Sampling Duration 0, 1, and 2?
(Based on the prescale setting, since the ADC clock is 80 MHz, the duration equivalent to 1.2 μs is 96.)