Introduction to Basic C Programming
Introduction to Basic C Programming
1. Edit (Creation) ✍️: The programmer uses a Text Editor (or an IDE) to write the C
source code, which is saved with a .c extension (e.g., program.c).
2. Preprocess: The source code is first processed by the Preprocessor, which handles
directives like #include (to insert content from header files) and #define (to substitute
macros).
3. Compile: The Compiler translates the preprocessed code into machine-readable
Object Code (often a .o or .obj file). This is where syntax errors are detected.
4. Link: The Linker takes the object code and combines it with necessary external code,
such as functions from the C Standard Library or other program modules, to create
a single, complete Executable File (e.g., [Link] or [Link]).
5. Load: The Loader (part of the operating system) places the executable file into the
computer's Primary Memory (RAM) for execution.
6. Execute (Run) : The CPU takes control and runs the program's instructions one by
one.
Introduction to C Programming:
The methodology relies on using only three fundamental control structures to dictate the
flow of execution, which helps eliminate confusing, non-linear jumps in code (like those
caused by excessive use of goto):
1. Sequence: Statements are executed in the order they appear, one after the next.
o Example: Reading an input, then calculating a value, then printing the result.
2. Selection (Decision): The program chooses which code block to execute based on a
condition.
o Implementation in C: if...else statements and the switch statement.
3. Repetition (Looping/Iteration): A block of code is executed repeatedly as long as a
specified condition remains true.
o Implementation in C: while, for, and do...while loops.
Example program:
#include <stdio.h>
int main() {
int x = 5;
printf("The number is: %d\n", x);
return 0;
}.
Loop statement:
#include <stdio.h>
int main() {
for (int i = 1; i <= 5; i++)
printf("%d ", i);
return 0;
}
Data Types:
define the size and type of data that a variable can hold. They tell the compiler
how much memory to allocate and how to interpret the stored bits.
Memory Example
Type Description
(Typical) Value
Single-precision floating-point
float 4 bytes 3.14159
numbers (decimals).
Double-precision floating-point
double 8 bytes 123.456789
numbers (more precise decimals).
Memory Example
Type Description
(Typical) Value
Integer:
#include <stdio.h>
int main() {
int sum = 5 + 3;
printf("The sum is: %d\n", sum);
return 0;
}
#include <stdio.h>
int main() {
float f=1.2f; double d=2.345; char c='Z';
printf("Float: %.1f, Double: %.3lf, Char: %c\n", f, d, c);
return 0;
}
Operators:
+, -, *, /, %
Arithmetic Used for mathematical calculations.
(Modulus)
== (Equal to), > Used for comparison; returns true (1) or false
Relational
(Greater than) (0).
C Program Control :
if...else: Executes one block of code if the condition is true and an alternative block if
it's false.
switch: Provides a way to choose one path from many possible options based on the
value of a single variable (usually an integer or character).
2. Repetition (Looping):
while: Tests the condition before each iteration. The loop may not run at all if the
condition is initially false.
do...while: Executes the loop body at least once before testing the condition at the
end of the iteration.
for: A compact loop designed for counter-controlled repetition, where initialization,
condition check, and increment/decrement are defined in a single line.
break: Immediately exits the innermost switch statement or loop (for, while, do-
while).
continue: Skips the remaining statements in the current iteration of a loop and moves
to the next iteration.
goto: Transfers control to a specific labeled statement. (Generally avoided as it makes
code difficult to read and maintain.)
1. C Functions :
Modularity: They break large programs into smaller, manageable, and logical units,
making the code easier to debug and maintain.
Reusability: A function can be called (executed) multiple times from different parts
of the program without needing to rewrite the code.
Structure: Every function has a return type (the type of data it sends back), a name,
and a list of parameters (inputs it accepts). Every C program must have one main
function: int main().
2. Introduction to Arrays:
Homogeneous: All elements in an array must be the same type (e.g., all int, all float).
Contiguous Storage: Array elements are stored sequentially in adjacent memory
locations.
Zero-Based Indexing: Elements are accessed using a position number called an
index or subscript, which always starts at 0. If an array has $N$ elements, the indices
range from $0$ to $N-1$.
o Example: scores[0] accesses the first element of the scores array.
Functions & Arrays: Arrays are often passed to functions to process collections of
data (e.g., calculating the average of an array of scores)
UNIT II EMBEDDED C
simulating OOP in C:
2. Abstraction (Interface):
Header Files (.h): The header file acts as the public interface, defining what the object
can do (function prototypes and struct name), while the source file (.c) defines how it
does it (the function implementations).
Opaque Data Types: Using a typedef for a structure pointer without defining the
struct's internals in the header file (an opaque pointer or handle) is the strongest form
of abstraction. The user can only hold a pointer to the object, not access its internal
members.
3. Inheritance (Subtyping):
struct Animal {
};
struct Dog {
};
4. Polymorphism (Method Overriding):
Function Pointer Table (V-Table): This is the most common way to achieve run-time
polymorphism.
o A special struct (the v-table or vtable) is created within the base object. It holds
function pointers for all the virtual methods (methods intended to be
overridden).
o struct Animal_VTable {
o void (*speak)(struct Animal *self); // Virtual method
o };
o struct Animal {
o const struct Animal_VTable *vptr;
The Data: The struct holds the attributes (data members) of the object.
The Method Convention: Unlike true OOP languages where methods are part of the
class, in C, methods are regular functions that accept a pointer to the object as their
first argument. This pointer is conventionally named self or this.
This technique is the best way to achieve strong abstraction and encapsulation
in C, similar to using a private class in C++.
Analogy: Think of an opaque pointer (MyObject *) as a key (handle) to a locked box (the
struct). Only the functions defined in the source file (MyObject_method) have the blueprint
to open and manipulate the contents of that box.
Inheritance (Subtyping):
1. Struct Nesting:
To make a struct Dog inherit from a struct Animal, you must include the Animal
struct as the very first member of the Dog struct.
struct Animal {
int age;
// ... other base fields
};
struct Dog {
struct Animal base; // <-- MUST be the first member
char breed[20];
};
2. Upcasting:
Because the base member starts at the exact same memory address as the Dog
structure itself, you can safely cast a pointer to a Dog into a pointer to an Animal. This allows
functions designed for the base type to operate on the derived type.
This is how a function like Animal_feed(struct Animal *a) can be called with a
struct Dog *d without error:
typedef struct {
void (*speak)(void *self); // Function pointer for the 'speak' method
void (*move)(void *self); // Function pointer for the 'move' method
} AnimalVTable;
struct Animal {
const AnimalVTable *vptr; // Pointer to the table of methods
}
1. Concrete Implementations: Each derived object (Dog, Cat) defines its own
specific static V-Table.
2. Constructor: The object's constructor must initialize the object's vptr to point to the
correct static V-Table for its type (e.g., Dog_vtable).
3. Dispatch: To call the method polymorphically, you access the appropriate function
pointer through the vptr at runtime.
// Polymorphic Call
void do_speak(struct Animal *a) {
// The program looks up the correct function address at runtime
// (a->vptr) and calls it.
a->vptr->speak(a);
}
The primary problem with these simple hardware delays, especially in modern or
complex systems, is their inaccuracy and inefficiency.
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
timeout_counter++;
3. Return status:
return is_ready_flag; // Returns true if flag was set, false if timed out
Loop Condition: The while loop continues only if both the event
condition is false (!is_ready_flag) AND the counter is below a maximum limit (max_count).
The 8051 microcontroller has several internal memory areas, and one of the
most important is the DATA memory space.
The DATA type specifically refers to the lower 128 bytes of on-chip RAM, ranging from
00H to 7FH.
1. Directly Addressable:
The DATA area can be accessed using direct addressing mode, which results in
faster execution.
2. Fastest Access Memory:
Since DATA memory is inside the CPU, all instructions accessing it take the
minimum number of machine cycles.
3. Divided into Sub-sections:
o 00H–1FH: Register banks (Bank0–Bank3)
o 20H–2FH: Bit-addressable RAM (16 bytes → 128 bits)
o 30H–7FH: General-purpose RAM (scratchpad area)
4. Used for Frequently Accessed Variables:
Small temporary variables, flags, and counters are usually stored here.
Example Instruction:
MOV A, 25H; Move content of DATA memory location 25H into Accumulator
MOV 30H, #55H ; Load immediate value into DATA RAM
Here, DJNZ takes 2 machine cycles, so you can calculate the delay as:
Delay = 255 × 2 µs = 510 µs
8051 has Timer 0 and Timer 1, 16-bit timers used for accurate delays.
Example:
The 8051 microcontroller contains four 8-bit parallel ports named Port 0,
Port 1, Port 2, and Port 3, used for performing input/output (I/O) operations. Each port
can be programmed to function as input or output using simple instructions in assembly or
embedded C.
Dual-function port
Used for general I/O or multiplexed address/data bus (AD0–AD7)
Requires external pull-ups for I/O
1. Latch (SFR)
2. Input buffer
3. Output driver
Logic operations are essential instructions in the 8051 microcontroller, used for
manipulating data bits, bytes, and for decision-making. These operations include AND, OR,
XOR, NOT, rotate, and Boolean (bit-level) operations. They help in controlling hardware,
setting flags, reading/writing bits, and performing arithmetic decisions.
1. AND Operation:
AND is used for bit clearing, masking, and isolating specific bits.
Instructions:
ANL A, Rn
ANL A, direct
ANL direct, A
ANL A, #data
Example:
ANL A, #0F0H ; Mask lower 4 bits
3. OR Operation:
OR is used for setting bits, combining data, and generating control signals.
Instructions:
ORL A, Rn
ORL A, direct
ORL A, #data
Example:
ORL A, #0FH ; Set lower 4 bits
4. XOR Operation:
Instructions:
XRL A, Rn
XRL A, direct
XRL A, #data
Example:
XRL A, #55H ; Toggle bits based on mask
Instruction:
CPL A
CPL bit (bit complement)
Example:
CPL A ; Invert all bits of A
CPL P1.2 ; Toggle P1.2 pin
The 8051 stores program code in on-chip ROM (4 KB/8 KB depending on the
version).
This memory is read-only during program execution.
Constant data such as lookup tables, strings, waveforms are stored here.
2. Why Access Code ROM?
8051 can only read code memory using the MOVC instruction internally, but in Embedded
C, the compiler handles this automatically.
void main() {
unsigned char x;
x = msg[0]; // fetches 'H' from code ROM
while(1);
}
void main() {
unsigned char i, value;
i = 2;
value = lookup[i]; // Reads 30 from code ROM
while(1);
}
void UART_Init() {
TMOD = 0x20; // Timer1 Mode2 (8-bit auto reload)
TH1 = 0xFD; // Baud rate 9600 for 11.0592 MHz
SCON = 0x50; // 8-bit UART, REN enabled
TR1 = 1; // Start Timer1
}
Send a byte (Serialize a byte):
void UART_Tx(unsigned char d) {
SBUF = d; // Load data to serial buffer
while(TI == 0); // Wait until transmit complete
TI = 0;
}
Send a string (Serializing multiple bytes):
void UART_SendString(char *s) {
while(*s) {
UART_Tx(*s++);
}
}
UNIT-IV 8051 SERIAL PORT AND INTERRUPT PROGRAMMING IN C
Serial communication is a method of transferring data one bit at a time over a single
data line.
Used when microcontroller needs to communicate with devices such as PC, GSM,
GPS, Bluetooth, sensors, or another microcontroller.
4. Basic Terms:
Connections:
To set UART in Mode 1 (8-bit UART) with 9600 baud, we configure Timer1.
void UART_Init() {
TMOD = 0x20; // Timer1 Mode 2 (8-bit auto reload)
TH1 = 0xFD; // Baud rate 9600 for 11.0592 MHz crystal
SCON = 0x50; // Mode 1, 8-bit UART, REN enabled
TR1 = 1; // Start Timer1
}
4. Transmitting Data:
void UART_Tx(unsigned char ch) {
SBUF = ch; // Load data into buffer
while(TI == 0); // Wait for transmit completion
TI = 0; // Clear flag
}
5. Receiving Data:
unsigned char UART_Rx() {
while(RI == 0); // Wait for data
RI = 0; // Clear flag
return SBUF; // Return received byte
}
6. Sending a String:
void UART_SendString(char *s) {
while(*s) {
UART_Tx(*s++);
}
}
Time Configuration in 8051:
What is Time Configuration?
Time configuration refers to setting up the 8051 timers (Timer0 and Timer1) to
generate delays, counters, and clock signals.
Timers are 16-bit and driven by the system clock.
3. Important Registers:
void Timer0_Delay() {
TMOD = 0x01; // Timer0 Mode 1 (16-bit)
TH0 = 0xFC; // Load initial value
TL0 = 0x66; // for approx 1ms delay
TR0 = 1; // Start timer
while (TF0 == 0); // Wait for overflow
TR0 = 0; // Stop timer
TF0 = 0; // Clear flag
}
8051 Interrupts:
What is an Interrupt?
An interrupt is a signal that temporarily halts the main program to execute a special
routine (Interrupt Service Routine – ISR).
After ISR execution, the main program resumes from where it was interrupted.
3. Interrupt Registers:
void main() {
EA = 1; // Enable global interrupts
EX0 = 1; // Enable external interrupt 0
while(1) {
// Main program loop
}
UNIT-V 8051 INTERFACING
2. Common ADCs:
CS → Chip select
RD → Read data
WR → Start conversion
INTR → Conversion complete
D0–D7 → Data to 8051 port
5. Embedded C Example:
6. Applications:
DAC (Digital-to-Analog Converter) converts digital values from 8051 into analog
voltage.
Used for analog output devices like speakers, voltage controllers, and waveform
generators.
6. Applications:
2. Types of Sensors:
Sensor Type Output Example
3. Interfacing Steps:
2. LCD Pins:
Pin Function
3. Interfacing Steps:
void main() {
LCD_Command(0x38); // 8-bit, 2 lines
LCD_Command(0x0C); // Display ON
LCD_Command(0x01); // Clear display
LCD_Data('H'); // Display character
}
5. Applications:
2. Pin Connections:
3. Interfacing Steps:
1 1 0 1 0
2 0 1 1 0
3 0 1 0 1
4 1 0 0 1
5. Embedded C Example:
#include <reg51.h>
void delay() {
unsigned int i, j;
for(i=0;i<100;i++)
for(j=0;j<100;j++);
}
void main() {
while(1) {
P1 = 0x09; delay(); // Step 1
P1 = 0x0C; delay(); // Step 2
P1 = 0x06; delay(); // Step 3
P1 = 0x03; delay(); // Step 4
}
}
6. Key Points:
7. Applications:
CNC machines
Robotics
Precise position control systems
Automated industrial equipment.