Hamed724
Hamed724

Reputation: 1

Xc8 bit access for do a task

In xc8 mplab i have a variable for example temp=0b10100100 (8 bits) i want to write  a code do task 1 and task 2 according to bits of temp Consecutively for  example first bit of temp is 1 so task 1 should be done and after that second bit of temp is 0 so task 2 should be done  and so on to end of bits of temp Thanks in advance

Upvotes: 0

Views: 1043

Answers (1)

Kozmotronik
Kozmotronik

Reputation: 2520

As far as I understand your issue, I have three approaches to your issue.

  1. Read or write the bit fields in C language manner.
  2. Define bit fields using structs.
  3. Use function pointers within a loop to execute tasks.

Read Or Write Bit Fields In C Manner

Using the bitwise operators in C, any bit in an integer variable can be manipulated.

#include <stdio.h>

#define BIT_READ(var, bitno)    (var & (1 << bitno))
#define BIT_RESET(var, bitno)   (var &= ~(1 << bitno))
#define BIT_SET(var, bitno)     (var |= 1 << bitno)

void Task1() {
    printf("Task1\n");
}

void Task2() {
    printf("Task2\n");
}

void Task3() {
    printf("Task3\n");
}

void Task4() {
    printf("Task4\n");
}

void Task5() {
    printf("Task5\n");
}

void Task6() {
    printf("Task6\n");
}

void Task7() {
    printf("Task7\n");
}

void Task8() {
    printf("Task8\n");
}

void main(void) {

    unsigned char temp;
    BIT_SET(temp, 0);
    if(BIT_READ(temp, 0)) {
        Task1();
        BIT_RESET(temp, 0);
    }
    
    BIT_SET(temp, 6);
    if(BIT_READ(temp, 6)) {
        Task7();
        BIT_RESET(temp, 6);
    }
    // You will see that only Task1 and Task7 will execute
}

Define Bit Fields Using Structs.

XC8 compiler supports bit fields that defined as structure.

#include <stdio.h>

union {
    struct {
        unsigned bit0   : 1;
        unsigned bit1   : 1;
        unsigned bit2   : 1;
        unsigned bit3   : 1;
        unsigned bit4   : 1;
        unsigned bit5   : 1;
        unsigned bit6   : 1;
        unsigned bit7   : 1;
    };
    unsigned char reg; // For register access
} temp;


void Task1() {
    printf("Task1\n");
}

void Task2() {
    printf("Task2\n");
}

void Task3() {
    printf("Task3\n");
}

void Task4() {
    printf("Task4\n");
}

void Task5() {
    printf("Task5\n");
}

void Task6() {
    printf("Task6\n");
}

void Task7() {
    printf("Task7\n");
}

void Task8() {
    printf("Task8\n");
}

void main(void) {
    temp.reg = 0b00101101;
    
    if(temp.bit0) {
        temp.bit0 = 0;
        // Do task1
        Task1();
    }
    if(temp.bit1) {
        temp.bit1 = 0;
        // Do task2
        Task2();
    }
    if(temp.bit2) {
        temp.bit2 = 0;
        // Do task3
        Task3();
    }
    if(temp.bit3) {
        temp.bit3 = 0;
        // Do task4
        Task4();
    }
    if(temp.bit4) {
        temp.bit4 = 0;
        // Do task5
        Task5();
    }
    if(temp.bit5) {
        temp.bit5 = 0;
        // Do task6
        Task6();
    }
    if(temp.bit6) {
        temp.bit6 = 0;
        // Do task7
        Task7();
    }
    if(temp.bit7) {
        temp.bit7 = 0;
        // Do task8
        Task8();
    }
    // In this case the tasks 1, 3, 4 and 6 will be executed.
}

Use Function Pointers Within a Loop

This approach is efficient for code size but not for execution speed.

#include <stdio.h>

void Task1() {
    printf("Task1\n");
}

void Task2() {
    printf("Task2\n");
}

void Task3() {
    printf("Task3\n");
}

void Task4() {
    printf("Task4\n");
}

void Task5() {
    printf("Task5\n");
}

void Task6() {
    printf("Task6\n");
}

void Task7() {
    printf("Task7\n");
}

void Task8() {
    printf("Task8\n");
}

typedef void (*Task)(void);
Task tasks[] = {
    Task1,
    Task2,
    Task3,
    Task4,
    Task5,
    Task6,
    Task7,
    Task8
};

void main(void) {
    unsigned char temp;
    temp = 0b11001010;
    
    // Or alternatively using function pointer:
    unsigned char mask = 1;
    for(char i = 0; i < sizeof(tasks); i++) {
        if((temp.reg & mask)) {
            // Check the temp's bits from 0 to 7 and call the related task 
            // accordingly. Better check bounds in order to prevent PC 
            // overflow, hence device reset.
            if(i >= sizeof(tasks)) break;
            temp.reg &= ~mask; // Clear the bit so that the task does not 
                               // execute repeatedly
            if(temp.reg & mask) {
                printf("bit %d not cleared\n", i);
            }
            else {
                printf("bit %d cleared\n", i);
            }
            tasks[i](); // Execute the related task
        }
        mask <<= 1; // Mask the next bit toward 7th bit.
    }
}

Upvotes: 1

Related Questions