Introduction

Welcome to Mevihub.com! In this tutorial, we will explore the world of embedded systems and delve into the importance of timer interrupts. Embedded systems are all around us, from our smartphones to our cars, and they rely heavily on precise timing to function properly. Timer interrupts play a crucial role in achieving this precision, allowing for multitasking and time-sensitive tasks.

Through this tutorial, you will learn how to use timer interrupts to control LED blinking on the TMS320F28335 microcontroller. We will provide a step-by-step guide to understanding the code and executing the program, using diagrams and visuals to make it easier to follow along. By the end of this tutorial, you will have a strong understanding of the significance of timer interrupts in embedded systems and the ability to apply this knowledge to your own projects.

REQUIRED COMPONENTS

Before diving into the tutorial, ensure you have the following components:

  1. TMS320F28335 Microcontroller Development Board
  2. LED (Light Emitting Diode)
  3. Connecting Wires
  4. Power Supply

Specification of the TMS320F28335

Feature/SpecificationDescription
ArchitectureC2000 32-bit Fixed-Point Digital Signal Processor (DSP)
CPU CoreTMS320C28x Core (32-bit RISC)
Clock FrequencyUp to 150 MHz
Flash Memory512 KB
RAM68 KB (RAM1: 40 KB, RAM2: 28 KB)
EEPROM10 KB
GPIOUp to 114 General-Purpose I/O pins
Timers– 12-Bit High-Resolution PWM (ePWM) Modules (12)
 – 32-Bit Enhanced Capture Time Base (eCAP) Modules (8)
 – 32-Bit Enhanced Quadrature Encoder Pulse (eQEP) Module
Analog-to-Digital Converter (ADC)– 12-bit, 16-channel SAR ADCs (2)
 – Conversion rate up to 12.5 MSPS per ADC
 – Individual ADC trigger and SOC
Digital-to-Analog Converter (DAC)– 12-bit, 2-channel DAC
Communication Interfaces– SCI (UART): Up to 2
 – SPI: Up to 2
 – I2C: Up to 2
 – McBSP (Multichannel Buffered Serial Port): Up to 2
CAN– Controller Area Network (CAN) Interface
 – Two CAN Modules (CAN-A and CAN-B)
PWM– Up to 16 PWM Outputs (ePWM)
Serial Communication– 2x SCI (UART) with LIN Support
Operating Temperature-40°C to +105°C
Supply Voltage1.71 V to 1.995 V (Core)
 1.14 V to 1.35 V (I/O)
Package OptionsLQFP, H-TQFP, BGA

Timer Interrupts

The use of timer interrupts is essential in embedded systems. They make it possible to precisely time and schedule time-sensitive processes, including sensor readings or motor control. Timer interrupts operate by sending out an interrupt signal at predetermined intervals, which causes the microcontroller to carry out a predetermined action.

Pulse-width modulation (PWM) is one example of a time-sensitive activity that may be effectively managed with timer interrupts. PWM is used to adjust the brightness of an LED. The microprocessor can precisely alter the duty cycle of the PWM signal via timed interrupts, producing slick and reliable changes in LED brightness.

HARDWARE SETUP

Setting up the hardware for LED blinking is straightforward. Follow these steps:

  1. Connect the LED’s cathode (shorter leg) to the Ground (GND).
  2. Connect the LED’s anode (longer leg) to a GPIO pin on the TMS320F28335 development board.

Here is an example code-led configuration

Now, let’s delve into the code implementation for LED blinking using Timer Interrupts. We’ll walk you through each step of the code and its significance.

STEP-BY-STEP EXECUTION PROCESS

  1. We begin by initializing the PIE Controller, System Control, and disabling Global and Peripheral Interrupts (DINT).
  2. The Timer0 Interrupt Service Routine (ISR), cpu_timer0_isr, is configured to be the target of the PIE Vector Table. This allows Timer0 to trigger the ISR when its interrupt occurs.
  3. The Init_GPio() function is used to initialize GPIO pins for LED blinking.
  4. Timer0 is set up with the desired duration of 500 milliseconds and initialized.
  5. The command CpuTimer0Regs.TCR.bit.TIE = 1 enables the Timer0 interrupt.
  6. We activate interrupts for CPU Group 1 and PIE Group 1 Timer0.
  7. Real-Time Debug Interrupt (ERTM) and Global Interrupt (EINT) are enabled.
  8. To handle Timer0 interrupts and keep the program running, we enter an indefinite loop (while(1)).
  9. Inside the Timer0 ISR (cpu_timer0_isr), we toggle the state of GPIO pin 31 (GPATOGGLE is used for GPIO31), and then we clear the Timer0 interrupt flag.
  10. The software continuously toggles the state of GPIO pin 31, resulting in the LED blinking at the set frequency of 500 milliseconds.

Step 1: Timer Initialization

The InitCpuTimers() function is essential for setting up the CPU timers on the TMS320F28335 microcontroller. It initializes all CpuTimers and sets the timer registers to their default values, making it a necessary step before configuring Timer0.

void InitCpuTimers(void)
{
    // Initialize Timer0 (CpuTimer0)
    // CpuTimer0 is a 32-bit timer used for general purpose in this example

    // Initialize Timer0 registers
    CpuTimer0Regs.TCR.bit.TSS = 1;     // Stop Timer0

    // Configure Timer0 control register (TCR)
    CpuTimer0Regs.TCR.bit.TRB = 1;     // Reload on TCR write (Not needed if all interrupts are enabled)
    CpuTimer0Regs.TCR.bit.SOFT = 0;    // Hardware interrupts only (No software trigger)
    CpuTimer0Regs.TCR.bit.FREE = 0;    // Timer Free Run Disabled (Stops on emulation suspend)
    CpuTimer0Regs.TCR.bit.TIE = 1;     // Timer Interrupt Enable (Enable Timer0 interrupt)
    CpuTimer0Regs.TCR.bit.TSS = 0;     // Start Timer0 (Timer0 is now counting)

    // Initialize Timer0 period
    CpuTimer0Regs.PRD.all = 74999;     // Set Timer0 period (74,999 CPU cycles for 500 ms)

    // Configure Timer0 interrupt
    PieCtrlRegs.PIEIER1.bit.INTx7 = 1; // Enable Timer0 interrupt in PIE Group 1
    IER |= M_INT1;                     // Enable CPU Group 1 interrupts (required for Timer0)
    EINT;                              // Enable Global interrupt INTM
    ERTM;                              // Enable Global realtime interrupt DBGM
}

Step 2: Timer Configuration

Next, we’ll explore the timer configuration process, which involves setting up Timer0 with specific parameters for our application.

In the code snippet, we use the ConfigCpuTimer() function to configure Timer0 (CpuTimer0) with three important parameters: Timer, Freq, and Period.

Example

Timer is a reference to a ConfigCpuTimer structure which contains timer settings. The CPU frequency in MHz determines the timer period, expressed in microseconds, which is the time interval between interrupt triggers.

    ConfigCpuTimer(&CpuTimer0, 150, 500000); // Freq "MHz" is Period 500mseconds

The Timer Period Formula

To better understand the Timer0 configuration, let’s delve into the timer period calculation formula:

(Timer Period in CPU cycles) = (CPU Clock Frequency * Desired Period in seconds) – 1

Example Calculation

Let’s walk through an example to calculate the Timer Period for Timer0 on the TMS320F28335.

1. CPU Clock Frequency (Freq) = 150 MHz

2. Desired Timer Period (Period) = 500,000 microseconds (500 milliseconds)

    ConfigCpuTimer(&CpuTimer0, 150, 500000); // Freq "MHz" is Period 500mseconds

Example to Configure the Timer

The calculated Timer Period is 74,999 CPU cycles.

Source Code

/*LED BLINKING USING CPU TIMER0 */

#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File

__interrupt void cpu_timer0_isr(void);
void Init_GPio(void);

void main(void)
{
    InitSysCtrl();
    DINT;
    InitPieCtrl();
    IER = 0x0000;
    IFR = 0x0000;
    InitPieVectTable();

    EALLOW;         // This is needed to write to EALLOW protected registers
    PieVectTable.TINT0 = &cpu_timer0_isr;
    EDIS;    // This is needed to disable write to EALLOW protected registers


    Init_GPio();
    InitCpuTimers();
    ConfigCpuTimer(&CpuTimer0, 150, 500000); // Freq "MHz" is Period 500mseconds
    //
    CpuTimer0Regs.TCR.bit.TIE = 1;
    CpuTimer0Regs.TCR.bit.TSS=0;



    IER |= M_INT1;
    PieCtrlRegs.PIECTRL.bit.ENPIE = 1;
    PieCtrlRegs.PIEIER1.bit.INTx7 = 1;


    EINT;           // Enable Global interrupt INTM
    ERTM;           // Enable Global realtime interrupt DBGM

    while(1)
    {

    }
}


void Init_GPio(void)
{
    EALLOW;
    GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 0;
    GpioCtrlRegs.GPBDIR.bit.GPIO32 = 1;

    GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 0;
    GpioCtrlRegs.GPADIR.bit.GPIO31 = 1;
    EDIS;
}
__interrupt void cpu_timer0_isr(void)
{

    GpioDataRegs.GPATOGGLE.bit.GPIO31 = 1;

    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}

By Devilal

Leave a Reply

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