uint8_t

时间:2018-07-20 21:25:54

标签: c

我正在尝试在“ c”(用于嵌入式应用程序)中创建一个表,其中每一行都是8位序列,例如:

11010011
01010011
10000000

然后,我需要具有设置/清除/读取任何行中任何位的功能。最有效的方法是什么?

对于位操作,我想使用:

uint8_t msk = 0x01;
row3 |= msk;

但是要做到这一点,我认为我需要将row3(以及每行)定义为uint8_t,并将其也转换为十六进制,这又引出了我的第二个问题:

如何在uint8_t中存储8位二进制序列?我已经看到了完成类似任务的不同方法,例如讨论过的here,但没有一种方法适合我。你能帮助我吗? 谢谢。

3 个答案:

答案 0 :(得分:0)

C没有用于输入二进制文字的语法,因此您应将它们键入为八进制或十六进制,例如

uint8_t row1 = 0xd3;
uint8_t row2 = 0x53;
uint8_t row3 = 0x80;

有关如何操作特定位的信息,请参见How do you set, clear, and toggle a single bit?

row3 |= mask;

将设置mask中设置的位。

答案 1 :(得分:0)

如果我理解正确,则需要一个十六进制数字列表,并且您希望操作列表中任何元素的位。我将通过创建一个无符号整数数组来实现它,该数组的大小由表中需要的元素数定义。

    #include <stdio.h>
    #include <stdint.h>
    #define LIST_SIZE 3

    //accepts the array and sets bit_pos bit of the list idx
    int set_bit(uint8_t* hex_list, int list_idx, int bit_pos){
        hex_list[list_idx] = hex_list[list_idx] | 0x01<<bit_pos; //left shift by the bit position you want to set
    }

    int clear_bit(uint8_t* hex_list, int list_idx, int bit_pos){
        hex_list[list_idx] = hex_list[list_idx] & ~(0x01<<bit_pos); //left shifts and does logical inversion to get the bit to clear
    }

    int main(void) {
        uint8_t hex_list[LIST_SIZE] = {0x00, 0x01, 0x02};
        set_bit(hex_list, 0, 1); // will make 0th element 0x00-> 0x02 by seting bit position 1
        clear_bit(hex_list, 1,0); //will make 1st element 0x01-> 0x00 by clearing bit position 0

        set_bit(hex_list, 2, 0); // will make 2nd element 0x02->0x03 by setting bit at position 1
        clear_bit(hex_list, 2 , 0);// will make 2nd element 0x03 ->0x02 by clearing bit at position 0

        //print the result and verify
        for(int i = 0; i<LIST_SIZE; ++i){
            // modified array will be {0x02, 0x00, 0x02}
            printf("elem%d = %x \n", i, hex_list[i]); 
        }
        return 0;
    }

一个uint8_t表示一个8位无符号整数,其值可以在0(二进制表示= 00000000)到255(二进制表示= 11111111)之间变化。

答案 2 :(得分:0)

要在C中表示二进制位模式,通常使用十六进制表示法。十六进制的用途是单个十六进制数字与4个二进制数字完全重合,因此根据经验,您可以在16个十六进制数字和头部中的相应二进制值之间快速转换,对于较长的整数,只需转换每个整数即可数字依次-一次4位。快速地用二进制表示长整数变得不切实际。

因此您的表可能表示为:

uint8_t row[] = { 0xd3, // 11010011
                  0x53, // 01010011
                  0x80  // 10000000
                } ;

然后按以下方式设置/清除位:

row[2] |= mask ;  // Set mask bits
row[0] &= mask ;  // Clear mask bits

要创建指定编号位的掩码而不对十六进制值进行硬编码,可以使用以下表达式:

uint8_t mask = 1<<7 | 1<<5 | 1<<0 ;  // 10100001 mask bits 0, 5 & 7

有时候需要“可视”二进制表示形式-例如,对于字符位图,当用二进制表示时,字符A更容易可视化:

00000000  
00011000  
00100100  
01000010  
01111110  
01000010  
01000010  
00000000  

通过为每个二进制值穷举定义一个宏,可以在保持“可视化”的同时有效地编码此类表;例如:

#define B_00000000 0x00 
#define B_00000001 0x01 
#define B_00000010 0x02 
#define B_00000011 0x03 
#define B_00000100 0x04 
...
#define B_11111110 0xfe 
#define B_11111111 0xff

请注意,要创建上述宏,最好编写一个代码生成器-即生成代码的程序,然后将这些宏放在头文件中。

鉴于此类宏,您可以将表表示为:

uint8_t row[] = { B_11010011
                  B_01010011
                  B_10000000
                } ;

或A的字符位图:

uint8_t charA[] = { B_00000000,  
                    B_00011000,  
                    B_00100100,  
                    B_01000010,  
                    B_01111110,  
                    B_01000010,  
                    B_01000010,  
                    B_00000000 } ;

如果在运行时串行接收到这些位,则可以使用顺序掩码和移位来构建相应的uint8_t

uint8_t getByte()
{
    uint8_t mask = 0x80 ;
    uint8_y byte = 0 ;

    while( mask != 0 )
    {
        uint8_t bit = getBit() ;
        byte |= bit ? mask : 0 ;
        mask >>= 1 ;
    }

    return byte ;
}

您需要定义getBit()函数的作用;例如,它可以读取文件,字符串或键盘输入,但必须返回零或非零或分别返回二进制数字01。如果首先接收到LSB的数据,则掩码从0x01开始,而改用<<移位。