C语言位操作求助:如何将读取的GPIO位存入无符号整数?
Hey there! Let's walk through fixing your code and understanding how to properly collect GPIO bits into an unsigned int—bit operations can feel tricky at first, but once you break down the pieces it makes sense.
First, Let's Spot the Issues in Your Current Code
Your code has a few key problems that are keeping it from working correctly:
- Loop runs only 31 times:
i < 31means you'll miss the 32nd bit (since we start counting at 0). You needi < 32to cover all bits in anunsigned int. - Reading the same pin every time: You're always reading
GPIO_PIN_9instead of iterating through different pins for each bit position. - Incorrect bit operation: Using
collect_bits &= ...will clear most bits instead of accumulating them. Also,collect_bitsisn't initialized, so it starts with a random value—big no-no! - No shifting: You aren't positioning each read pin's state into the correct bit position of
collect_bits.
Fixed Code with Explanations
Here's a corrected version that properly collects 32 GPIO bits (adjust the loop if your MCU uses 16-bit ports instead of 32):
#include "stm32fxxx_hal.h" // Adjust to your MCU's HAL header unsigned int collect_bits = 0; // Always initialize variables to avoid undefined behavior for (int i = 0; i < 32; i++) { // Generate the pin mask for the i-th pin (GPIO_PIN_0 << i gives GPIO_PIN_i) uint16_t pin_mask = (GPIO_PIN_0 << i); // Read the state of the current GPIO pin GPIO_PinState pin_state = HAL_GPIO_ReadPin(GPIOC, pin_mask); // If the pin is high, set the corresponding bit in collect_bits if (pin_state == GPIO_PIN_SET) { // Use 1U (unsigned 1) to avoid sign extension issues when shifting collect_bits |= (1U << i); } // If the pin is low, we do nothing—collect_bits already has 0 in that position }
Key Details to Understand
- Initialization:
collect_bits = 0starts us with a clean slate, so we can build up the bit pattern from scratch without random garbage values. - Pin Mask Generation:
GPIO_PIN_0 << icreates the correct mask for each pin. For example, wheni=9, this becomesGPIO_PIN_9—now we cycle through all pins instead of just one. - Bit Positioning:
1U << ishifts an unsigned 1 to the i-th bit position. Using1Uinstead of a plain1prevents problems with signed integer overflow when shifting into higher bits. - Bitwise OR (
|=): This operation sets the i-th bit ofcollect_bitsto 1 without changing any other bits. It's perfect for accumulating each pin's state one by one.
Quick Hardware Context Note
Most MCUs (like STM32) have 16-bit GPIO ports, not 32. If that's your case, change the loop condition to i < 16 to avoid reading invalid, non-existent pins. If you want to map the first pin to the highest bit of collect_bits instead of the lowest, replace (1U << i) with (1U << (31 - i)).
内容的提问来源于stack exchange,提问作者kooda

