Overview

Today in this tutorial we are going to interface the 74HC4051 multiplexer/demultiplexer interface with TMS320F28379D. First, I’ll talk about the multiplexing part.

Components to be Used:

  • Launchxl-f28379d
  • CD74HC4051
  • Potentiometer
  • Joystick
  • Breadboard
  • Jumper Wires

Circuit Diagram

About ADC Multiplexer CD74HC4067

Have you ever had enough contacts to read a set of analog sensors? Don’t worry, you’re not alone, it happens to the best of us and you can do something about it. An analog/digital multiplexer, like the CD74HC4067 (down multiplexer), can help increase the number of contacts you have, and it’s incredibly easy to connect to your TMS320F28379D or another microcontroller.

CD74HC4067 is a 16 channel analog multiplexer/demultiplexer. It’s available in a layout board-ready DIP package, or if you’re as board-dependent as I am, robu.in offers an SSOP version. This allows you to use 4 digital contacts to control the transfer from one contact to 16 others. Actually, it can be used in any direction, as well as with serial or other digital interfaces. In this tutorial, we are only going to read the values ​​of 16 potentiometers, because buying 16 analog sensors for this would be superfluous.

Such a multiplexer actually simply acts as a 16 to 1 switch. 4 digital contacts are used to set HIGH or LOW in binary (0-15) to determine which contact the “SIG” is connected to. So transferring all 4 LOW contacts changes CD74HC4067 to channel 0 (so SIG and C0 will connect), transferring all HIGH switches to 15 (so SIG and C15 will connect). It’s a simple binary code, but by any chance, you’re one of the 99.8% of people in the world who don’t know binary, here’s a simple table on the right.

Features

  1. “On” resistance: 70 Ohms @ 4.5V
  2. 6ns break-before-make @ 4.5V

Pinout CD74HC4067

How does it work

The working of a mux is pretty simple, and it remains the same for other multiplexers too.

  • Enable contact (E) is the active low contact.
  • This means that the device will turn on whenever the contact level is low.
  • Now, as shown above, the selected contact combination must be bypassed to connect the corresponding input contact (C) to the output (Seg).
  • To show the work, I am going to connect 3 ADC sensors to the input contacts (C0 to C2) and read the value of the sensor from the output contact (Sec).

GPIO Connection

As you can see, the 3 selection pins are connected to GPIO_0, GPIO_1, GPIO_2 and GPIO_3, and the power output is connected to GND. I also renamed them accordingly.

Top and bottom layer

Final Code Mode_1

/*
 * main.c
 *
 *  Created on: 08-Mar-2022
 *      Author: Admin
 */


#include "stdio.h"
#include "string.h"
#include "stdlib.h"

#include "F28x_Project.h"
#include "F2837xD_device.h"
#include "F2837xD_Examples.h"

#include "device.h"
#include "driverlib.h"

#define EX_ADC_RESOLUTION       12
#define S0_pin 0
#define S1_pin 1
#define S2_pin 2
#define S3_pin 3

void GPIO_Init();
void ConfigADC(uint32_t ADC_BASE);
void initADC_SOC(void);




const int selectpins[] = {S0_pin, S1_pin, S2_pin,S3_pin};
uint16_t values[3] = {0,0,0};

void selectmuxpin(int pin);

int k;

void main(void)
{
    Device_init();
    Device_initGPIO();
    Interrupt_initModule();
    Interrupt_initVectorTable();
    ConfigADC(ADCA_BASE);
    initADC_SOC();
    GPIO_Init();



    while(1)
    {




// method 1

        for(k=0;k<4;k++)
              {
                  selectmuxpin(k);


               //   read the value at the SIG pin
                    ADC_forceSOC(ADCA_BASE, ADC_SOC_NUMBER0);
                                                  // Wait for ADCA to complete, then acknowledge flag
                    while(ADC_getInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1) == false)
                    {

                    }
                    ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);

                    values[k] = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER0);

              }





    }

}


void selectmuxpin(int pin)
{
    int i;
    for(i=0; i<4; i++)
    {
        if(pin &(1<<i))
        {
            GPIO_WritePin(selectpins[i], 1);


        }
        else
        {
            GPIO_WritePin(selectpins[i], 0);
        }
    }
}



void GPIO_Init()
{
    EALLOW;    // Enable writing to the EALLOW protected areas
    GPIO_setPinConfig(S0_pin);
    GPIO_setDirectionMode(S0_pin, GPIO_DIR_MODE_OUT);
    GPIO_WritePin(S0_pin, 0); // 1 high 0 low
    GPIO_setPadConfig(S0_pin, GPIO_PIN_TYPE_STD);
    GPIO_setMasterCore(S0_pin, GPIO_CORE_CPU1);


    GPIO_setPinConfig(S1_pin);
    GPIO_setDirectionMode(S1_pin, GPIO_DIR_MODE_OUT);
    GPIO_WritePin(S1_pin, 0); // 1 high 0 low
    GPIO_setPadConfig(S1_pin, GPIO_PIN_TYPE_STD);
    GPIO_setMasterCore(S1_pin, GPIO_CORE_CPU1);


    GPIO_setPinConfig(S2_pin);
    GPIO_setDirectionMode(S2_pin, GPIO_DIR_MODE_OUT);
    GPIO_WritePin(S1_pin, 0); // 1 high 0 low
    GPIO_setPadConfig(S2_pin, GPIO_PIN_TYPE_STD);
    GPIO_setMasterCore(S2_pin, GPIO_CORE_CPU1);

    GPIO_setPinConfig(S3_pin);
    GPIO_setDirectionMode(S3_pin, GPIO_DIR_MODE_OUT);
    GPIO_WritePin(S3_pin, 0); // 1 high 0 low
    GPIO_setPadConfig(S3_pin, GPIO_PIN_TYPE_STD);
    GPIO_setMasterCore(S3_pin, GPIO_CORE_CPU1);
    EDIS;
}



void ConfigADC(uint32_t ADC_BASE)
{
    EALLOW;

    ADC_setPrescaler(ADCA_BASE, ADC_CLK_DIV_4_0);

#if(EX_ADC_RESOLUTION == 12)
    {
        ADC_setMode(ADC_BASE, ADC_RESOLUTION_12BIT, ADC_MODE_SINGLE_ENDED);
    }
#elif(EX_ADC_RESOLUTION == 16)
    {
      ADC_setMode(ADCA_BASE, ADC_RESOLUTION_16BIT, ADC_MODE_DIFFERENTIAL);
    }
#endif
    ADC_setInterruptPulseMode(ADC_BASE, ADC_PULSE_END_OF_CONV);
    ADC_enableConverter(ADC_BASE);
    DEVICE_DELAY_US(1000);
    EDIS;
}


void initADC_SOC(void)
{
#if(EX_ADC_RESOLUTION == 12)
    {
        ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_SW_ONLY, ADC_CH_ADCIN0, 15);
    }
#elif(EX_ADC_RESOLUTION == 16)
    {
        ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_SW_ONLY, ADC_CH_ADCIN0,64);
    }
#endif
    ADC_setInterruptSource(ADCA_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER0);
    ADC_enableInterrupt(ADCA_BASE, ADC_INT_NUMBER1);
    ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);

}



Final Code Method_2

/*
 * main.c
 *
 *  Created on: 08-Mar-2022
 *      Author: Devilal
 */


#include "stdio.h"
#include "string.h"
#include "stdlib.h"

#include "F28x_Project.h"
#include "F2837xD_device.h"
#include "F2837xD_Examples.h"

#include "device.h"
#include "driverlib.h"

#define EX_ADC_RESOLUTION       12
#define S0_pin 0
#define S1_pin 1
#define S2_pin 2
#define S3_pin 3

void GPIO_Init();
void ConfigADC(uint32_t ADC_BASE);
void initADC_SOC(void);




const int selectpins[] = {S0_pin, S1_pin, S2_pin,S3_pin};
uint16_t values[3] = {0,0,0};

void selectmuxpin(int pin);

int k;

void main(void)
{
    Device_init();
    Device_initGPIO();
    Interrupt_initModule();
    Interrupt_initVectorTable();
    ConfigADC(ADCA_BASE);
    initADC_SOC();
    GPIO_Init();



    while(1)
    {
// methode 2 using switch case

        // to verify getting value is correc or not

        switch(k) {

                   case 0 :
                       selectmuxpin(k);
                      break; /* optional */

                   case 1  :
                       selectmuxpin(k);
                      break; /* optional */


                   case 2  :
                       selectmuxpin(k);
                      break; /* optional */


                   case 3  :
                       selectmuxpin(k);
                      break; /* optional */

                   default : /* Optional */
                       break;

                }





                  selectmuxpin(k);


               //   read the value at the SIG pin
                    ADC_forceSOC(ADCA_BASE, ADC_SOC_NUMBER0);
                                                  // Wait for ADCA to complete, then acknowledge flag
                    while(ADC_getInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1) == false)
                    {

                    }
                    ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);

                    values[k] = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER0);

        





    }

}


void selectmuxpin(int pin)
{
    int i;
    for(i=0; i<4; i++)
    {
        if(pin &(1<<i))
        {
            GPIO_WritePin(selectpins[i], 1);


        }
        else
        {
            GPIO_WritePin(selectpins[i], 0);
        }
    }
}



void GPIO_Init()
{
    EALLOW;    // Enable writing to the EALLOW protected areas
    GPIO_setPinConfig(S0_pin);
    GPIO_setDirectionMode(S0_pin, GPIO_DIR_MODE_OUT);
    GPIO_WritePin(S0_pin, 0); // 1 high 0 low
    GPIO_setPadConfig(S0_pin, GPIO_PIN_TYPE_STD);
    GPIO_setMasterCore(S0_pin, GPIO_CORE_CPU1);


    GPIO_setPinConfig(S1_pin);
    GPIO_setDirectionMode(S1_pin, GPIO_DIR_MODE_OUT);
    GPIO_WritePin(S1_pin, 0); // 1 high 0 low
    GPIO_setPadConfig(S1_pin, GPIO_PIN_TYPE_STD);
    GPIO_setMasterCore(S1_pin, GPIO_CORE_CPU1);


    GPIO_setPinConfig(S2_pin);
    GPIO_setDirectionMode(S2_pin, GPIO_DIR_MODE_OUT);
    GPIO_WritePin(S1_pin, 0); // 1 high 0 low
    GPIO_setPadConfig(S2_pin, GPIO_PIN_TYPE_STD);
    GPIO_setMasterCore(S2_pin, GPIO_CORE_CPU1);

    GPIO_setPinConfig(S3_pin);
    GPIO_setDirectionMode(S3_pin, GPIO_DIR_MODE_OUT);
    GPIO_WritePin(S3_pin, 0); // 1 high 0 low
    GPIO_setPadConfig(S3_pin, GPIO_PIN_TYPE_STD);
    GPIO_setMasterCore(S3_pin, GPIO_CORE_CPU1);
    EDIS;
}



void ConfigADC(uint32_t ADC_BASE)
{
    EALLOW;

    ADC_setPrescaler(ADCA_BASE, ADC_CLK_DIV_4_0);

#if(EX_ADC_RESOLUTION == 12)
    {
        ADC_setMode(ADC_BASE, ADC_RESOLUTION_12BIT, ADC_MODE_SINGLE_ENDED);
    }
#elif(EX_ADC_RESOLUTION == 16)
    {
      ADC_setMode(ADCA_BASE, ADC_RESOLUTION_16BIT, ADC_MODE_DIFFERENTIAL);
    }
#endif
    ADC_setInterruptPulseMode(ADC_BASE, ADC_PULSE_END_OF_CONV);
    ADC_enableConverter(ADC_BASE);
    DEVICE_DELAY_US(1000);
    EDIS;
}


void initADC_SOC(void)
{
#if(EX_ADC_RESOLUTION == 12)
    {
        ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_SW_ONLY, ADC_CH_ADCIN0, 15);
    }
#elif(EX_ADC_RESOLUTION == 16)
    {
        ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_SW_ONLY, ADC_CH_ADCIN0,64);
    }
#endif
    ADC_setInterruptSource(ADCA_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER0);
    ADC_enableInterrupt(ADCA_BASE, ADC_INT_NUMBER1);
    ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);

}



By Devilal

Leave a Reply

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