Athul
Athul

Reputation: 449

Pre processor: #if comparing two values

I was working on setting up a UART for ATmega168 micro controller. My first code didn't work. While checking on that I came across an header file used in a working program. It uses preprocessor directives.

It was quite confusing for me, so I decided to run it in a c compiler and check outputs.

#include <stdio.h>

#define F_CPU 1000000UL

#ifndef BAUD                          /* if not defined in Makefile... */
#define BAUD  9600                     /* set a safe default baud rate */
#endif

#define BAUD_TOL 2
#define UBRR_VALUE (((F_CPU) + 8UL * (BAUD)) / (16UL * (BAUD)) -1UL)

#if 100 * (F_CPU) > (16 * ((UBRR_VALUE) + 1)) * (100 * (BAUD) + (BAUD) * (BAUD_TOL))
#define USE_2X 1
#define TEST 1

#elif 100 * (F_CPU) < (16 * ((UBRR_VALUE) + 1)) * (100 * (BAUD) - (BAUD) * (BAUD_TOL))
#define USE_2X 1
#define TEST 11

#else
#define USE_2X 0
#define TEST 111

#endif


int main(void) {

    printf("UBRR_VALUE: %ld\n", UBRR_VALUE);
    printf("USE_2X: %d\n", USE_2X);
    printf("%ld\n", (16 * ((UBRR_VALUE) + 1)) * (100 * (BAUD) - (BAUD) * (BAUD_TOL)));
    printf("F_CPU * 100 = %ld\n", (100*F_CPU));
    printf("TEST = %d\n", TEST);
    return 0;
}

Output:

UBRR_VALUE: 6
USE_2X: 1
105369600
F_CPU * 100 = 100000000
TEST = 11

since 100 * F_CPU is less than (16 * ((UBRR_VALUE) + 1)) * (100 * (BAUD) - (BAUD) * (BAUD_TOL)), TEST is assigned a value of 11.

But it I change the F_CPU to 16000000UL:

UBRR_VALUE: 103
USE_2X: 0
1565491200
F_CPU * 100 = 1600000000
TEST = 111

Here's also 100 * F_CPU is less than (16 * ((UBRR_VALUE) + 1)) * (100 * (BAUD) - (BAUD) * (BAUD_TOL)).

But how come TEST is 111?

Edit: *Here's 100 * F_CPU is greater than (16 * ((UBRR_VALUE) + 1)) * (100 * (BAUD) - (BAUD) * (BAUD_TOL))

Upvotes: 2

Views: 148

Answers (1)

Javeed Shariff
Javeed Shariff

Reputation: 52

The macros are expanded as explained below:

For the second case F_CPU to 16000000UL (Larger value)

100 * (F_CPU) > (16 * ((UBRR_VALUE) + 1)) * (100 * (BAUD) + (BAUD) * (BAUD_TOL)) 

evaluates to 0x5f5e1000 > 0x611e8000 which is false

100 * (F_CPU) < (16 * ((UBRR_VALUE) + 1)) * (100 * (BAUD) - (BAUD) * (BAUD_TOL))

evaluates to 0x5f5e1000 < 0x5d4f8000 which is also false.

Hence the below macros are applicable:

#define USE_2X 0
#define TEST 111

Upvotes: 2

Related Questions