This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
The TRM for the 28075, in section 8.3.4, states that the internal junction temperature can be sampled at ADCIN13 on ADCA by enabling it with the TSNSCTL register. However, there is no further information about how to interpret the ADC value and convert it to a temperature. Is there another document or some sample code that shows how to do this?
Devin,
As a follow up question to my earlier reply: is there a nominal equation that we can use to calculate the junction temperature while we are waiting for the calibrated TMS parts? Even though the accuracy will be off, it will allow us to proceed with firmware development.
Thanks,
Angelo
Hi Angelo,
I'll let Devin address your specific question, but I want to caution that the temp sensor accuracy likely will not be a guaranteed min/max spec in the TMS DS, and I expect it may be +/-15 degrees TYP. It is not that it can't be used as a general gauge of the junction temperature, but want you to have the proper expectation.
Regards,
Joe
Hi Angelo,
Attached are the following draft software files:
F2807x_TempSensorConv.c : The support functions for the temp sensor. This file should be placed in .. \F2807x_common\source.
adc_soc_epwm_tempsensor_cpu01.c : An example that samples the temp sensor and then calls the support functions to interpret the results. Note that the project that you create for this code should link in the above F2807x_TempSensorConv.c file.
F2807x GlobalPrototypes.h: An updated header file with the temp sensor support functions included. This should be placed in .. \F2807x_common\sinclude.
These are provided as-is; official versions will eventually be released in ControlSUITE.
//########################################################################### // FILE: adc_soc_epwm_tempsensor_cpu01.c // TITLE: Sample temperature sensor and convert to temperature for F2807x. // //! \addtogroup cpu01_example_list //! <h1> ADC temperature sensor conversion (adc_soc_epwm_tempsensor)</h1> //! //! This example sets up the ePWM to periodically trigger the ADC. The //! ADC converts the internal connection to the temperature sensor, //! which is then interpreted as a temperature by calling the //! GetTemperatureC function. //! //! After the program runs, the memory will contain:\n //! - \b sensorSample \b: The raw reading from the temperature sensor. \n //! - \b sensorTemp \b: The interpretation of the sensor sample as a //! temperature in degrees Celsius. //! //########################################################################### // $TI Release: F2807x Support Library vXXX $ // $Release Date: XXX CDT 2015 $ // $Copyright: Copyright (C) 2013-2015 Texas Instruments Incorporated - // http://www.ti.com/ ALL RIGHTS RESERVED $ //########################################################################### #include "F28x_Project.h" // Device Headerfile and Examples Include File void ConfigureADC(void); void ConfigureEPWM(void); void SetupADCEpwm(void); interrupt void adca1_isr(void); Uint16 sensorSample; int16 sensorTemp; void main(void) { // Step 1. Initialize System Control: // PLL, WatchDog, enable Peripheral Clocks // This example function is found in the F2807x_SysCtrl.c file. InitSysCtrl(); // Step 2. Initialize GPIO: // This example function is found in the F2807x_Gpio.c file and // illustrates how to set the GPIO to it's default state. InitGpio(); // Skipped for this example // Step 3. Clear all interrupts and initialize PIE vector table: // Disable CPU interrupts DINT; // Initialize the PIE control registers to their default state. // The default state is all PIE interrupts disabled and flags // are cleared. // This function is found in the F2807x_PieCtrl.c file. InitPieCtrl(); // Disable CPU interrupts and clear all CPU interrupt flags: IER = 0x0000; IFR = 0x0000; // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // This will populate the entire table, even if the interrupt // is not used in this example. This is useful for debug purposes. // The shell ISR routines are found in F2807x_DefaultIsr.c. // This function is found in F2807x_PieVect.c. InitPieVectTable(); //Map ISR functions EALLOW; PieVectTable.ADCA1_INT = &adca1_isr; //function for ADCA interrupt 1 EDIS; //Configure the ADC and power it up ConfigureADC(); //Initialize the temperature sensor //Note: The argument needs to change if using a VREFHI voltage other than 3.0V InitTempSensor(3.0); //Configure the ePWM ConfigureEPWM(); //Setup the ADC for ePWM triggered conversions on temperature sensor SetupADCEpwm(); //Enable global Interrupts and higher priority real-time debug events: IER |= M_INT1; //Enable group 1 interrupts EINT; // Enable Global interrupt INTM ERTM; // Enable Global realtime interrupt DBGM //enable PIE interrupt PieCtrlRegs.PIEIER1.bit.INTx1 = 1; //sync ePWM EALLOW; CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1; //start ePWM EPwm1Regs.ETSEL.bit.SOCAEN = 1; //enable SOCA EPwm1Regs.TBCTL.bit.CTRMODE = 0; //unfreeze, and enter up count mode //take conversions indefinitely in loop while(1); } //Write ADC configurations and power up the ADC for both ADC A and ADC B void ConfigureADC(void) { EALLOW; //write configurations AdcaRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4 AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE); //Set pulse positions to late AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1; //power up the ADC AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1; //delay for 1ms to allow ADC time to power up DELAY_US(1000); EDIS; } void ConfigureEPWM(void) { EALLOW; // Assumes ePWM clock is already enabled EPwm1Regs.ETSEL.bit.SOCAEN = 0; // Disable SOC on A group EPwm1Regs.ETSEL.bit.SOCASEL = 4; // Select SOC on up-count EPwm1Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event EPwm1Regs.CMPA.bit.CMPA = 0x0800; // Set compare A value to 2048 counts EPwm1Regs.TBPRD = 0x1000; // Set period to 4096 counts EPwm1Regs.TBCTL.bit.CTRMODE = 3; // freeze counter EDIS; } void SetupADCEpwm(void) { Uint16 acqps; acqps = 83; //temperature sensor needs at least 700ns acquisition time //Select the channels to convert and end of conversion flag EALLOW; AdcaRegs.ADCSOC0CTL.bit.CHSEL = 13; //SOC0 will convert internal connection A13 AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5; //trigger on ePWM1 SOCA/C AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //end of SOC0 will set INT1 flag AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1; //enable INT1 flag AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared } interrupt void adca1_isr(void) { sensorSample = AdcaResultRegs.ADCRESULT0; sensorTemp = GetTemperatureC(sensorSample); AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; }
//########################################################################### // FILE: F2807x_TempSensorConv.c // TITLE: F2807x Temperature Sensor Conversion Functions //########################################################################### // $TI Release: F2807x Support Library vXXX $ // $Release Date: XXX $ // $Copyright: Copyright (C) 2013-2015 Texas Instruments Incorporated - // http://www.ti.com/ ALL RIGHTS RESERVED $ //########################################################################### #include "F2807x_device.h" // F2807x Headerfile Include File #include "F2807x_Examples.h" // F2807x Examples Include File // Useful definitions #define FP_SCALE 32768 //Scale factor for Q15 fixed point numbers (2^15) #define FP_ROUND FP_SCALE/2 //Added to Q15 numbers before converting to integer to round the number // Amount to add to Q15 fixed point numbers to shift from Celsius to Kelvin // (Converting guarantees number is positive, which makes rounding more efficient) #define KELVIN 273 #define KELVIN_OFF FP_SCALE*KELVIN // The following pointers to function calls are: //Slope of temperature sensor (deg. C / ADC code). Stored in fixed point Q15 format. #define getTempSlope() (*(int (*)(void))0x7036E)() //ADC code corresponding to temperature sensor output at 0 deg. C #define getTempOffset() (*(int (*)(void))0x70372)() int32 tempSensor_tempSlope; Uint16 tempSensor_tempOffset; float32 tempSensor_scaleFactor; //Initialize the temperature sensor by powering up the sensor, loading //the calibration values from OTP to RAM, and recording the intended //VREFHI voltage. //note: This function doesn't support VREFLO != 0.0V, but this could //be implemented if desired. void InitTempSensor(float32 vrefhi_voltage) { EALLOW; //power up the the temperature sensor AnalogSubsysRegs.TSNSCTL.bit.ENABLE = 1; //delay to allow the sensor to power up DELAY_US(1000); EDIS; //need to remember VREFHI voltage so that sensor readings can be scaled //to match 2.5V values used for calibration data. tempSensor_scaleFactor = vrefhi_voltage; //check the device revision if(DevCfgRegs.REVID >= 3) { //for production devices (Rev. C), pull the slope and offset from OTP tempSensor_tempSlope = (int32)getTempSlope(); tempSensor_tempOffset = getTempOffset(); } else { //for pre-production devices, use these static values for slope and offset tempSensor_tempSlope = 5196; tempSensor_tempOffset = 1788; } } //This function uses the reference data stored in OTP to convert the raw temperature //sensor reading into degrees C int16 GetTemperatureC(int16 sensorSample) { sensorSample = (int16)((tempSensor_scaleFactor/2.5)*(sensorSample)); return ((sensorSample - tempSensor_tempOffset)*tempSensor_tempSlope + FP_ROUND + KELVIN_OFF)/FP_SCALE - KELVIN; } //This function uses the reference data stored in OTP to convert the raw temperature //sensor reading into degrees K int16 GetTemperatureK(int16 sensorSample) { sensorSample = (int16)((2.5/tempSensor_scaleFactor)*(sensorSample)); return ((sensorSample - tempSensor_tempOffset)*tempSensor_tempSlope + FP_ROUND + KELVIN_OFF)/FP_SCALE; }
Devin,
I finally had a chance to try this out on one of our TMX320F28075 parts and it seems to be working fine.
Thanks,
Agnelo