2.13) Simple C Programs: Arithmetic Operation in AVR

posted by Hamid Sayyed • November 11, 2025 0 Comments

Arithmetic operations are the heart of every program, whether we are writing simple logic or controlling complex embedded systems. In AVR microcontrollers, arithmetic operations are performed by the Arithmetic Logic Unit (ALU), which handles addition, subtraction, multiplication, and division. Understanding how arithmetic works in AVR C programming is crucial for students who want to perform real-world tasks such as measuring sensor data, controlling motors, or computing time delays. Every embedded application ultimately depends on arithmetic — from a blinking LED timer to signal processing or analog-to-digital conversion. AVR provides both **8-bit and 16-bit arithmetic** operations, and through C programming, these are handled efficiently by the compiler. In this post, we’ll study all major arithmetic operations — addition, subtraction, multiplication, division, and modulus — along with example programs and their hardware meaning. We will also understand how AVR internally manages these calculations through its registers and how to use them effectively in embedded applications.

1. What Are Arithmetic Operations?

Arithmetic operations are mathematical actions performed on numerical data. In C programming for AVR, they include:

  • Addition (+) — combines two numbers.
  • Subtraction (-) — finds the difference between numbers.
  • Multiplication (*) — repeats addition to produce a product.
  • Division (/) — divides one number by another.
  • Modulus (%) — gives the remainder after division.

These operations are carried out by the ALU, and results are stored back in registers or variables. The compiler automatically selects the required AVR assembly instruction (ADD, SUB, MUL, etc.) based on your C code.

OperatorMeaningExample
+Additiona + b
-Subtractiona - b
*Multiplicationa * b
/Divisiona / b
%Modulusa % b

2. Simple Arithmetic Program in AVR

Let’s start with a basic program demonstrating all arithmetic operations. This helps you see how results are calculated and how data is stored in variables.

#include <avr/io.h>

int main(void)
{
    uint8_t a = 20, b = 6;
    uint8_t sum, diff, mul, div, mod;

    sum = a + b;
    diff = a - b;
    mul = a * b;
    div = a / b;
    mod = a % b;

    while(1);
}

In this example, the variables sum, diff, mul, div, and mod store the results of various arithmetic operations. Although this seems simple, it teaches an important concept — that AVR C automatically handles register allocation for 8-bit values. If any result exceeds 255 (the limit of an 8-bit value), it wraps around due to overflow.

Note: Overflow and underflow are common in 8-bit microcontrollers. To avoid them, always use the correct data type such as uint16_t or int16_t for larger results.

3. Understanding Addition and Subtraction

Addition and subtraction are the most commonly used operations in microcontroller programs. Whether you’re adding ADC readings, controlling PWM values, or incrementing a counter, these operations occur continuously. AVR executes these with the ADD and SUB instructions.

#include <avr/io.h>

int main(void)
{
    uint8_t x = 100;
    uint8_t y = 50;
    uint8_t z;

    z = x + y;   // Result: 150
    z = x - y;   // Result: 50

    while(1);
}

Here, the ALU performs binary addition or subtraction using registers. If an overflow occurs (for example, x=200 and y=100), the carry flag in the status register (SREG) is set.

4. Multiplication and Division Operations

AVR supports hardware multiplication for 8-bit data. The result of multiplication is 16-bit, stored in two registers (R1:R0). Division, however, is done by software since AVR doesn’t have a dedicated divide instruction.

#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
    uint8_t a = 12, b = 5;
    uint16_t product;
    uint8_t quotient;

    product = a * b;   // 12 × 5 = 60
    quotient = a / b;  // 12 ÷ 5 = 2

    while(1);
}
Tip: Use uint16_t for multiplication results since 8×8 multiplication produces a 16-bit output. For accurate division with fractional values, use floating-point variables like float or double.

5. Modulus Operation

The modulus operator (%) gives the remainder after division. It is very useful in timing, digital clock designs, and repetitive loops.

uint8_t seconds = 125;
uint8_t minutes;

minutes = seconds / 60;         // 2 minutes
seconds = seconds % 60;         // 5 seconds remaining

Here, after 125 seconds, we find 2 minutes and 5 seconds remaining — a typical operation when converting timer counts or calculating display values.

6. Mixed Arithmetic and Type Casting

When you perform arithmetic between different data types (for example, 8-bit and 16-bit), the compiler promotes smaller types to the larger one automatically. However, it’s good practice to use type casting explicitly.

uint8_t small = 100;
uint16_t large = 500;
uint16_t result;

result = large + (uint16_t)small;
This ensures correct result width and avoids overflow. Without casting, addition of mixed types can sometimes produce unexpected behavior.

7. Arithmetic in I/O Operations

Arithmetic is also used while controlling hardware. For example, adjusting LED brightness or calculating motor speed through PWM.

#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
    DDRB = 0xFF;
    uint8_t value = 0;

    while(1)
    {
        value = (value + 10) % 255;   // Increase brightness pattern
        PORTB = value;                // Send to output port
        _delay_ms(100);
    }
}

Here, the arithmetic addition and modulus operators generate a repeating LED pattern. Such arithmetic control is commonly used in waveform generation and real-time control loops.

8. Summary Table

OperationSymbolAssembly InstructionExample
Addition+ADDsum = a + b;
Subtraction-SUBdiff = a - b;
Multiplication*MULprod = a * b;
Division/Softwarediv = a / b;
Modulus%Softwarerem = a % b;

Conclusion

Arithmetic operations form the backbone of embedded programming. Every real-time task — whether reading ADC values, controlling PWM, or timing — relies on arithmetic calculations. AVR’s efficient ALU and C compiler support make it easy to perform such operations quickly and accurately. By practicing arithmetic programs on hardware, students can understand how the microcontroller actually processes mathematical instructions at machine level. A strong understanding of these operations helps in mastering complex topics like interrupts, timers, and signal control in future learning.

Comments

Post a Comment

Subscribe to Post Comments [Atom]