使用字符数组作为长整数数组

时间:2010-01-14 19:46:35

标签: c arrays avr unions avr-gcc

在我的AVR上,我有一个字符数组,它以{R,G,B,x,R,G,B,x,...}的形式保存颜色强度信息(x是未使用的字节)。有没有简单的方法可以将long int(32位)写入char myArray[4*LIGHTS],这样我可以轻松编写0x00BBGGRR编号?

我的类型转换是粗糙的,我不知道如何写它。我猜测只是创建一个指向long int类型的指针,并将其设置为等于myArray,但后来我不知道如何随意告诉它将group x设置为myColor。

uint8_t myLights[4*LIGHTS];
uint32_t *myRGBGroups = myLights; // ?

*myRGBGroups = WHITE; // sets the first 4 bytes to WHITE
                      // ...but how to set the 10th group?

编辑:我不确定类型转换是否是正确的术语,因为我认为如果它只是将32位数字截断为8位?

7 个答案:

答案 0 :(得分:5)

typedef union {
    struct {
         uint8_t    red;
         uint8_t    green;
         uint8_t    blue;
         uint8_t    alpha;
    }          rgba;
    uint32_t   single;
} Color;

Color    colors[LIGHTS];

colors[0].single = WHITE;
colors[0].rgba.red -= 5;

注意:在little-endian系统中,4字节值的低位字节将是alpha值;而它将是大端系统的红色值。

答案 1 :(得分:2)

您的代码完全有效。您可以将myRGBGroups用作常规数组,因此要访问第10个像素,您可以使用

myRGBGroups[9]

答案 2 :(得分:1)

考虑使用C union,其中union的第一个字段是int32,第二个字段是4 * chars的向量。但是,不确定这是否是最好的方式。

答案 3 :(得分:1)

您需要在AVR上考虑uint32_t的{​​{3}},以确保以正确的顺序存储组件(以便稍后通过myLights阵列解除引用)我会这样做的。一个快速的谷歌似乎表明AVR将数据存储在内存中的小端,但其他寄存器的字节顺序各不相同。

无论如何,假设你已经这样做了,你可以使用数组索引取消引用myRGBGroups(其中每个索引将引用一个4字节的块)。因此,要设置第10组,您只需myRGBGroups[ 9 ] = COLOR

答案 4 :(得分:0)

如果可以在myRGBgroup上使用算术,例如myRGBgroups ++将给出下一组,类似地你可以使用加号,减号等运算符。这些运算符使用类型大小而不是单字节操作

myRGBgroups[10] // access group as int
((uint8_t*)(myRGBgroups + 10)) // access group as uint8 array

答案 5 :(得分:0)

结构和uint32_t的联合比制作尺寸为4 * LIGHTS的uint8_t好得多。另一种相当常见的方法是使用宏或内联函数来执行创建正确uint32_t所需的按位运算:

#define MAKE_RGBA32(r,g,b,a) (uint32_t)(((r)<<24)|((g)<<16)|((b)<<8)|(a))
uint32_t colors[NUM_COLORS];
colors[i] = MAKE_RGBA32(255,255,255,255);

根据您的字节顺序,可能需要以不同的顺序将值放入int中。这种技术很常见,因为对于像RGBA5551或RGB565这样的较旧的16bpp颜色格式,按位运算方式考虑颜色比以字节为单位更有意义。

答案 6 :(得分:0)

您可以使用结构赋值执行类似的操作 - 这可以解决字节序问题:

typedef struct Color {
    unsigned char r, g, b, a;
} Color;

const Color WHITE   = {0xff, 0xff, 0xff, 0};
const Color RED     = {0xff, 0, 0, 0};
const Color GREEN   = {0, 0xff, 0, 0};

Color colors[] = {WHITE, RED};
Color c;

colors[1] = GREEN;
c = colors[1];

但是,标准中未定义比较,您无法使用c == GREEN,并且您无法在分配中使用{}快捷方式(仅初始化),因此c = {0, 0, 0, 0}将失败。< / p>

另外请记住,如果它是8位AVR(而不是AVR32说),那么你很可能不会从这两种技术中看到任何性能优势。