Overview
Welcome to another informative post from Mevihub.com! This article will delve into battery voltage measurement using the TMS320F28069 microcontroller. We’ll walk you through the provided code step by step and explain the process of calculating battery voltage using a detailed formula. So, let’s get started!
Introduction
A key component of many electronic systems, especially those that use batteries for power, is battery voltage measuring. We can precisely measure battery voltage thanks to the analog-to-digital converter (ADC) on the TMS320F28069 microcontroller. The included code provides a thorough formula for calculating the voltage and an example of how to interact with the ADC to measure battery voltage.
Battery Voltage Calculation Formula
The formula at the centre of the voltage measurement procedure is adjusted to the parameters provided:
Battery Voltage Calculation Formula with offset
Battery Voltage (in volts) = ((ADC_Result – Offset_Count) * Multiplication_factor) / (ADC_Resolution – Offset_Count).
Battery Voltage Calculation Formula without offset
Battery Voltage (in volts) = (ADC_Result / ADC_Resolution) * Maximum_Battery_Voltage
Practical Examples without offset
Here’s a breakdown of the formula components:
- ADC_Result: The raw ADC reading for the battery input voltage.
- ADC_Resolution: The maximum possible value of the ADC reading (4095 for a 12-bit ADC).
- Maximum_Battery_Voltage: The maximum battery voltage (750 volts).
Given Specifications
- Battery voltage readings range from 0 to 750 volts.
- The maximum ADC voltage for the TMS320F28069 microcontroller is 3.294 volts.
- The ADC has a resolution of 12 bits, which means it can represent values from 0 to 4095.
There’s no offset voltage to consider in this setup.
Formula
Battery Voltage (in volts) = (ADC_Result / ADC_Resolution) * Maximum_Battery_Voltage
- Here, Multiplication_factor is 750 volts.
Let’s calculate the battery voltage for three different ADC results:
- ADC_Result = 2048 (Mid-scale value)
- ADC_Result = 1024 (One-fourth of full-scale value)
- ADC_Result = 3072 (Three-fourths of full-scale value)
Example 1: ADC_Result = 2048 (Mid-Scale)
Battery Voltage (in volts) = ((2048 - 0) * 750) / (4095 - 0)
= (2048 * 750) / 4095
≈ 375.61 volts
Consequently, the estimated battery voltage is 375.61 volts for an ADC_Result of 2048.
Example 2: ADC_Result = 1024 (One-Fourth of Full-Scale)
Battery Voltage (in volts) = ((1024 - 0) * 750) / (4095 - 0)
= (1024 * 750) / 4095
≈ 187.81 volts
The estimated battery voltage for an ADC_Result of 1024 is 187.81 volts.
Practical Examples of offset
Formula with Offset
Battery Voltage (in volts) = ((ADC_Result – Offset_Count) * Multiplication_factor) / (ADC_Resolution – Offset_Count).
Given Specifications
- Battery voltage readings range from 0 to 750 volts.
- The maximum ADC voltage for the TMS320F28069 microcontroller is 3.294 volts.
- The ADC has a resolution of 12 bits, which means it can represent values from 0 to 4095.
- An offset voltage of 0.2 volts is present.
Here, Multiplication_factor is 750 volts.
Calculating the Offset_Count
We must translate the offset voltage (0.2 volts) into the appropriate ADC count in order to get the Offset_Count:
Offset_Count = (Offset_Voltage / ADC_Maximum_Voltage) * ADC_Resolution
Offset_Count = (0.2 / 3.294) * 4095
Offset_Count ≈ 248.76 (rounded to the nearest integer, which is 249)
As a result, the offset count is around 249.
Calculate the Multiplication factor for 750v
The formula for the Multiplication factor
Multiplication Factor = (Max_Voltage_Input * Reference_Voltage)/Actival_Voltage
Multiplication Factor = (750v*3.3v)/3.294v
Multiplication Factor = 2474/3.294
Multiplication Factor = 751.36v
Example 1: ADC_Result = 2048 (Mid-Scale)
Battery Voltage (in volts) = ((2048 - 249) * 751) / (4095 - 249)
= (1799 * 751) / 3846
≈ 351.28 volts
For an ADC_Result of 2048 and an offset voltage of 0.2 volts, the estimated battery voltage is roughly 351.28 volts.
Example 2: ADC_Result = 1024 (One-Fourth of Full-Scale)
Battery Voltage (in volts) = ((1024 - 249) * 751) / (4095 - 249)
= (775 * 751) / 3846
≈ 151.33 volts
Final Code
/*
* ADC_Main_v2.c
*
* Created on:
* Author: Mevihub.com
*/
#include "DSP28x_Project.h"
#include <string.h>
#define Btry_Ip_Voltage 0
#define Output_Voltage 1
#define Output_Crnt 2
void InitADC(void);
void InitAdcAIO(void);
void ADC_Inint(void);
void AdcSocConfig(void);
void ADC_Handler(void);
__interrupt void adc_isr (void);
/* ========================================================
----------Battery Parameters Union Structure ----------
======================================================== */
union battery{
unsigned int uiData[4];
struct{
unsigned int uiBtry_Ip_Volt; // Battery Voltage 450 - 750V 2 Bytes
unsigned int uiOutPut_Volt; // Output Voltage 24V
unsigned int uiOutPut_Crnt; // Output Current 170A
unsigned int uiTermistor; // HeatSink Temperature
}reg;
};
union battery Battery;
union Adc{
unsigned int uiData[7];
unsigned char ucData[7];
struct{
unsigned int ADC_Result[6];
unsigned int ADC_Flag :1;
unsigned int Space_Flag :15;
}reg;
};
union Adc ADC;
union config{
struct{
unsigned int uiBtry_Ip_Volt_Mult;
unsigned int uiOutput_Volt_Mult;
unsigned int uiOutput_Crnt_Mult;
unsigned int uiBtry_Ip_Volt_Lmt;
unsigned int uiOutPut_Volt_Lmt;
unsigned int uiOutPut_Crnt_Lmt;
}reg;
};
union config Config;
// Input Voltage
unsigned int uiIpVolt[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
unsigned long ulIpVolt_Sum = 0;
unsigned int uiIpVolt_ADC = 0;
unsigned int uiIpVolt_ADC_Cnt = 0;
float ADC_Scaling_Factor;
void main(void)
{
InitSysCtrl();
InitPieCtrl();
InitPieVectTable();
InitGpio();
Config.reg.uiBtry_Ip_Volt_Mult = 750;
Config.reg.uiOutput_Crnt_Mult = 170;
memset(&Battery, '\0', sizeof(Battery));
memset(&ADC, '\0', sizeof(ADC));
ADC_Scaling_Factor = 0;
InitAdc();
InitAdcAio();
ADC_Inint();
EALLOW;
PieVectTable.ADCINT1 = &adc_isr;
EDIS;
PieCtrlRegs.PIEIER1.bit.INTx1 = 1;
IER |= M_INT1;
EINT;
ERTM;
/*
*
Scaling Factor
Formula
Scaling Factor = Multiplication Factor / ADC_Resolution - OffsetVoltage
= 750 / 4095 - 0
= 750 / 4095
= 750 * [ 1/4095]
= 750 * 0.0002442;
*
*/
ADC_Scaling_Factor = Config.reg.uiBtry_Ip_Volt_Mult * 0.0002442;
AdcRegs.ADCSOCFRC1.all = 0x03;
while(1)
{
ADC_Handler();
}
}
void ADC_Handler(void)
{
if(ADC.reg.ADC_Flag == 1)
{
ulIpVolt_Sum = ulIpVolt_Sum - uiIpVolt[uiIpVolt_ADC_Cnt] + ADC.reg.ADC_Result[Btry_Ip_Voltage];
uiIpVolt[uiIpVolt_ADC_Cnt] = ADC.reg.ADC_Result[Btry_Ip_Voltage];
uiIpVolt_ADC = ulIpVolt_Sum >> 4; // Nothing but ulIpVolt_Sum /16
uiIpVolt_ADC_Cnt++;
if(uiIpVolt_ADC_Cnt >= 16) uiIpVolt_ADC_Cnt = 0;
/*
*
Formula for calculate Battery voltage and current
((Adc_Result - ADC_offset) * Multiplication_factor )/(ADC_Resolution - ADC_offset)
*
*/
Battery.reg.uiBtry_Ip_Volt = (unsigned int)uiIpVolt_ADC * ADC_Scaling_Factor; //MF * (1 / 4095) = 750 + 0.0002442 = 0.18315
AdcRegs.ADCSOCFRC1.all = 0x03; // Start ADC
ADC.reg.ADC_Flag = 0; // Clear ADC_Flag
}
}
void ADC_Inint(void)
{
EALLOW;
AdcRegs.ADCCTL1.bit.INTPULSEPOS = 1; //ADCINT1 trips after AdcResults latch
AdcRegs.INTSEL1N2.bit.INT1E = 1; //Enabled ADCINT1
AdcRegs.INTSEL1N2.bit.INT1CONT = 0; //Disable ADCINT1 Continuous mode
AdcRegs.INTSEL1N2.bit.INT1SEL = 1; //setup EOC15 to trigger ADCINT1 to fire
AdcRegs.ADCSOC0CTL.bit.CHSEL = 0; //set SOC0 channel select to ADCINA0
AdcRegs.ADCSOC1CTL.bit.CHSEL = 1; //set SOC1 channel select to ADCINA1
AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 0; //set SOC0 start trigger on SW
AdcRegs.ADCSOC1CTL.bit.TRIGSEL = 0; //set SOC1 start trigger on SW
AdcRegs.ADCINTSOCSEL1.bit.SOC0 = 1; //ADCINT1 will trigger SOC0
AdcRegs.ADCINTSOCSEL1.bit.SOC1 = 1; //ADCINT1 will trigger SOC1
AdcRegs.ADCSOC0CTL.bit.ACQPS = 6; //set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
AdcRegs.ADCSOC1CTL.bit.ACQPS = 6; //set SOC0 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1)
EDIS;
}
__interrupt void adc_isr (void)
{
ADC.reg.ADC_Result[Btry_Ip_Voltage] = AdcResult.ADCRESULT0; //Battery_Input_Voltage Upto 0v to 3.294v equal to 0 to 750V
ADC.reg.ADC_Result[Output_Voltage] = AdcResult.ADCRESULT1; // Output Voltage Up to 0V to 3.294V equal to 0 to 24V O/P
ADC.reg.ADC_Result[Output_Crnt] = AdcResult.ADCRESULT2; // Output Current Up to 0v to 3.29v equal to 0 to 170A
AdcRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //Clear ADCINT1 flag reinitialize for next SOC
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1; // Acknowledge interrupt to PIE
ADC.reg.ADC_Flag = 1; // Update the Interrupt ADC Flag
}