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:

  1. ADC_Result: The raw ADC reading for the battery input voltage.
  2. ADC_Resolution: The maximum possible value of the ADC reading (4095 for a 12-bit ADC).
  3. Maximum_Battery_Voltage: The maximum battery voltage (750 volts).

Given Specifications

  1. Battery voltage readings range from 0 to 750 volts.
  2. The maximum ADC voltage for the TMS320F28069 microcontroller is 3.294 volts.
  3. 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:

  1. ADC_Result = 2048 (Mid-scale value)
  2. ADC_Result = 1024 (One-fourth of full-scale value)
  3. 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

  1. Battery voltage readings range from 0 to 750 volts.
  2. The maximum ADC voltage for the TMS320F28069 microcontroller is 3.294 volts.
  3. The ADC has a resolution of 12 bits, which means it can represent values from 0 to 4095.
  4. 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

}

By Devilal

Leave a Reply

Your email address will not be published. Required fields are marked *