我正在开发一个MCU,每个GPIO端口有16个引脚。我有一个中断路由,我需要看看引脚14,13和12的输入数据寄存器是高电平还是低电平。我创建了这个简单的测试场景,看看我是否可以在uint8_t
变量中读取和存储特定的引脚:
#include <stdio.h>
#include <stdint.h>
#define GPIO_PIN_0 ((uint16_t)0x0001) /* Pin 0 selected */
#define GPIO_PIN_1 ((uint16_t)0x0002) /* Pin 1 selected */
#define GPIO_PIN_2 ((uint16_t)0x0004) /* Pin 2 selected */
#define GPIO_PIN_3 ((uint16_t)0x0008) /* Pin 3 selected */
#define GPIO_PIN_4 ((uint16_t)0x0010) /* Pin 4 selected */
#define GPIO_PIN_5 ((uint16_t)0x0020) /* Pin 5 selected */
#define GPIO_PIN_6 ((uint16_t)0x0040) /* Pin 6 selected */
#define GPIO_PIN_7 ((uint16_t)0x0080) /* Pin 7 selected */
#define GPIO_PIN_8 ((uint16_t)0x0100) /* Pin 8 selected */
#define GPIO_PIN_9 ((uint16_t)0x0200) /* Pin 9 selected */
#define GPIO_PIN_10 ((uint16_t)0x0400) /* Pin 10 selected */
#define GPIO_PIN_11 ((uint16_t)0x0800) /* Pin 11 selected */
#define GPIO_PIN_12 ((uint16_t)0x1000) /* Pin 12 selected */
#define GPIO_PIN_13 ((uint16_t)0x2000) /* Pin 13 selected */
#define GPIO_PIN_14 ((uint16_t)0x4000) /* Pin 14 selected */
#define GPIO_PIN_15 ((uint16_t)0x8000) /* Pin 15 selected */
#define GPIO_PIN_All ((uint16_t)0xFFFF) /* All pins selected */
int main() {
uint32_t maskWithOR = GPIO_PIN_14 | GPIO_PIN_13 | GPIO_PIN_12;
uint32_t maskInBinary = 0b00000000000000000111000000000000;
uint32_t data[8] = {
//.................XXX............
0b10010000100011110000000011111111, //0 = 000
0b10010000100011110001000011111111, //1 = 001
0b10010000100011110010000011111111, //2 = 010
0b10010000100011110011000011111111, //3 = 011
0b10010000100011110100000011111111, //4 = 100
0b10010000100011110101000011111111, //5 = 101
0b10010000100011110110000011111111, //6 = 110
0b10010000100011110111000011111111, //7 = 111
};
printf("maskWithOR = 0x%x\r\n", maskWithOR);
printf("maskInBinary = 0x%x\r\n", maskInBinary);
printf("\r\nOR MASK:\r\n");
for(int i = 0; i < 8; i++) {
uint8_t result = data[i] & maskWithOR;
printf("result[%d] = %d\r\n", i, result);
}
printf("\r\nBINARY MASK:\r\n");
for(int i = 0; i < 8; i++) {
uint8_t result = data[i] & maskInBinary;
printf("result[%d] = %d\r\n", i, result);
}
return 0;
}
这是我测试程序的输出:
maskWithOR = 0x7000
maskInBinary = 0x7000
OR MASK:
result[0] = 0
result[1] = 0
result[2] = 0
result[3] = 0
result[4] = 0
result[5] = 0
result[6] = 0
result[7] = 0
BINARY MASK:
result[0] = 0
result[1] = 0
result[2] = 0
result[3] = 0
result[4] = 0
result[5] = 0
result[6] = 0
result[7] = 0
我做错了什么?
答案 0 :(得分:1)
您将32位操作的结果存储在8位变量中:
uint8_t result = data[i] & maskWithOR;
此操作的结果是该值被截断,使您保留原始结果的最后八位。由于您感兴趣的所有三个位都高于第12位,因此您获得的结果始终为零。
如果必须将结果拟合为8位,则将data[i] & maskWithOR
的值移位最低位的索引,即12位。
答案 1 :(得分:1)
您无法将AND
结果存储为8位整数...
您可以尝试强制布尔结果(1或0),如下所示:
uint8_t result = (data[i] & maskWithOR)>0;
在查看0到7之间的所需输出值之后,可以强制将32位无符号数位向右移位...向右移动12位,然后仅使用符合8位整数的位进行屏蔽以确保你得到一个8位的结果
uint8_t result = ((data[i] & maskWithOR)>>12) & 255;
虽然255掩码有点多余......你可以这样做,并可能侥幸逃脱......
uint8_t result = (data[i] & maskWithOR)>>12;
但是,正如@chux提到的AND
255
会uint32_t
安静或取消因将结果从uint8_t
缩小到{{1}}而引起的警告