2

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

我的类型转换很粗糙,我不知道该怎么写。我猜只是创建一个指向 long int 类型的指针并将其设置为等于 myArray,但是我不知道如何任意告诉它将组 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 位?

4

7 回答 7

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 值;而它将是大端系统上的红色值。

于 2010-01-14T19:57:48.043 回答
2

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

myRGBGroups[9]
于 2010-01-14T20:01:55.947 回答
1

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

于 2010-01-14T19:51:13.377 回答
1

如果要执行此操作,您需要考虑 AVR 上的字节顺序uint32_t以确保组件以正确的顺序存储(以便以后通过myLights数组取消引用)。快速的 Google 似乎表明 AVR 将数据存储在内存小端中,但其他寄存器的字节序不同。

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

于 2010-01-14T19:53:29.533 回答
0

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

myRGBgroups[10] // access group as int
((uint8_t*)(myRGBgroups + 10)) // access group as uint8 array
于 2010-01-14T19:55:07.583 回答
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 颜色格式,以位运算而非字节为单位来考虑颜色更有意义。

于 2010-01-14T21:11:03.807 回答
0

您可以使用 struct assignment 执行类似的操作 - 这可以解决字节序问题:

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}会失败。

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

于 2010-02-21T10:35:45.660 回答