Yes, you simply define an array of your 32-bit integers. Then you manipulate a specific element of the array.
Given a bit ID from 0 through 255 inclusive (for example), that would be an array:
unsigned int bits[8];
In order to find which element to operate on:
unsigned int index = bitId >> 5; // turns 0..255 into 0..31
To get the masks for a given bit ID:
unsigned int masks[] = {
0x0001, 0x0002, 0x0004, 0x0008,
0x0001, 0x0020, 0x0040, 0x0080,
0x0100, 0x0200, 0x0400, 0x0800,
0x1000, 0x2000, 0x4000, 0x8000
};
unsigned int mask = masks[bitId & 0x1f];
If you have the uint32_t type available in your implementation, that's probably the safest way to go. Otherwise, there are known methods for using unsigned int using CHAR_BIT and sizeof to actually figure out at runtime how big to make the masks array and what values you should use for discovering the array index and bitmask index.
For example, this snippet from my code library shows how I did it for a character-based bitmask:
static unsigned char bitmask[CHAR_BIT];
void bitsetInit (void) {
unsigned char mask = 1;
int i = 0;
while (i < CHAR_BIT) {
bitmask[i++] = mask;
mask <<= 1;
}
}
and using:
bsp->bits[bitnum/CHAR_BIT] &= ~bitmask[bitnum%CHAR_BIT];
bsp->bits[bitnum/CHAR_BIT] |= bitmask[bitnum%CHAR_BIT];
for clearing and setting bits respectively.
If you wanted to use unsigned int instead of unsigned char you would simply calculate the number of bits for that:
unsigned int UINT_BIT = CHAR_BIT * sizeof (unsigned int);
and use it where I've used CHAR_BIT above (the mask array can be dynamically allocated at runtime if need be).