Pantech.AI

Embedded C: A Beginner’s Guide to Programming Microcontrollers

Introduction

Embedded C is a specialized version of the C programming language designed for programming embedded systems, such as microcontrollers and processors. Unlike standard C, which runs on computers with operating systems, Embedded C is used to develop firmware that interacts directly with hardware components. Why Use Embedded C?

Why Use Embedded C?

Embedded C is widely used because it provides:
✅ Portability – Can run on different microcontrollers.
✅ Efficiency – Generates optimized machine code for embedded hardware.
✅ Direct Hardware Access – Uses registers and memory-mapped I/O.
✅ Real-time Performance – Suitable for real-time applications like automotive, industrial automation, and medical devices.

Features of Embedded C

🔹 Use of Registers & Memory Addresses – Accessing hardware-specific features like GPIO, timers, and interrupts.
🔹 Bitwise Operations – Manipulating individual bits of registers for optimized performance.
🔹 Low-Level Control – Directly controlling microcontroller peripherals.
🔹 Optimized Code Execution – Minimal overhead to ensure fast and efficient processing.

Difference Between C and Embedded C

Basic Structure of an Embedded C Program

An Embedded C program typically consists of:

1️⃣ Header File Inclusion – Includes microcontroller-specific header files.
2️⃣ Global Variables & Macros – Defines constants and memory locations.
3️⃣ Main Function – Initializes and controls peripherals.
4️⃣ Functions & Interrupt Service Routines (ISR) – Handles interrupts and events.

Data Types and Variables in C

In C, data types define the type of data a variable can store, and variables are names given to memory locations to hold data.

1️⃣ Data Types in C

🟢 Primary Data Types (Basic Data Types)

📌 Example:

int age = 25;
float height = 5.9;
char grade = 'A';
double pi = 3.1415926535;

🟡 Derived Data Types (Advanced Types)

Arrays → Collection of elements of the same type.

int arr[5] = {1, 2, 3, 4, 5};

Pointers → Stores address of another variable

int a = 10;
int *ptr = &a;  // Pointer to integer a

Structures → Groups different data types.

struct Student {
    char name[20];
    int age;
    float marks;
};

🟠 User-Defined Data Types

typedef → Gives a new name to an existing data type.

typedef unsigned int uint;
uint x = 10;

enum → Defines named integer constants.

enum Color { RED, GREEN, BLUE };

2️⃣ Variables in C

A variable is a name given to a memory location that holds a value.

📌 Rules for Naming Variables:
✅ Must start with a letter or underscore (_var).
✅ Can contain letters, digits, and underscores (count_1).
✅ Cannot use C keywords (int, float, return, if).
✅ Case-sensitive (Age and age are different).

📌 Declaring and Initializing Variables:

int num = 10;       // Integer variable
float price = 99.99; // Float variable
char ch = 'A';      // Character variable

🔹 Types of Variable Storage Classes

  • Local Variables → Declared inside a function, available only in that function.
  • Global Variables → Declared outside functions, available throughout the program.
  • Static Variables → Retains value even after function exits.
  • Extern Variables → Defined in another file, can be accessed globally.

📌 Example of Local & Global Variables:

#include <stdio.h>

int globalVar = 100;  // Global variable

void function() {
    int localVar = 50;  // Local variable
    printf("Local: %d, Global: %d\n", localVar, globalVar);
}

int main() {
    function();
    printf("Global in main: %d\n", globalVar);
    return 0;
}

Pointers in C/C++ Explained: Types, Uses, and Examples

Introduction to Pointers

A pointer is a variable that stores the memory address of another variable. Pointers are powerful because they allow direct memory manipulation, which improves efficiency and enables dynamic memory allocation.

Basic Syntax of a Pointer

int a = 10;   
int *ptr = &a;  // Pointer storing the address of variable 'a'
printf("%d", *ptr); // Output: 10

Here, ptr stores the memory address of a, and *ptr (dereferencing) gives the value of a.

Declaring and Initializing Pointers

int x = 5;
int *p = &x;  // p holds the address of x

Pointer Operators

  • & (Address-of operator): Returns the address of a variable.
  • (Dereference operator): Accesses the value stored at an address.

Pointer Arithmetic

Pointers support basic arithmetic operations:

int arr[3] = {10, 20, 30};
int *ptr = arr;  // Points to the first element

printf("%d", *(ptr + 1)); // Output: 20 (Moves to the next element)
  • ptr + 1 moves to the next integer in memory.
  • *(ptr + i) is the same as arr[i].

Types of Pointers

Null Pointer (Points to nothing)

int *ptr = NULL;

Void Pointer (Generic pointer)

void *ptr;
int a = 5;
ptr = &a;  // Can store any type of variable's address

Wild Pointer (Uninitialized pointer, should be avoided)

int *ptr;  // Dangerous! May point to an unknown location

Dangling Pointer (Points to a freed memory location)

int *ptr = (int*)malloc(sizeof(int));
free(ptr); // ptr now becomes a dangling pointer

Solution: Set ptr = NULL after free(ptr);

Pointers and Functions

Passing Pointers to Functions

void changeValue(int *p) {
    *p = 100;  // Changing value at memory location
}

int main() {
    int a = 10;
    changeValue(&a);
    printf("%d", a); // Output: 100
}

Why use pointers?

Functions in C pass arguments by value. Using pointers allows modification of the original variable.

Dynamic Memory Allocation in C

C provides malloc(), calloc(), realloc(), and free() for dynamic memory allocation.

Allocating Memory Using malloc()

int *ptr = (int*) malloc(sizeof(int));
*ptr = 20;
printf("%d", *ptr); // Output: 20
free(ptr);  // Always free allocated memory

Using calloc() for Array Allocation

int *arr = (int*) calloc(5, sizeof(int));  // Allocates memory for 5 integers
free(arr);  

Resizing Memory Using realloc()

arr = (int*) realloc(arr, 10 * sizeof(int)); // Resizes the allocated memory

Pointers to Structures and Classes

Pointer to Structure

struct Student {
    char name[20];
    int age;
};

struct Student s1 = {"John", 20};
struct Student *ptr = &s1;

printf("%s %d", ptr->name, ptr->age);  // Output: John 20

Here, ptr->name is equivalent to (*ptr).name.

Applications of Embedded C

📌 Automotive Systems – ABS, Engine Control Units (ECU), Airbags
📌 Consumer Electronics – Smartwatches, Microwaves, Washing Machines
📌 Medical Devices – Heart Monitors, Pacemakers
📌 IoT & Robotics – Smart Sensors, Autonomous Robots

Leave a Comment

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