将所有MSP430端口用作一个端口会更方便。 我想可能会把寄存器溢出到下一个内存地址,但是它不起作用(或者说我做得不对)。
要访问 PORT2 的 BIT0 ,我尝试了类似的东西:
P1OUT |= 0x80000000000;
因为在内存中 P2OUT (0x0029)是 P1OUT (0x0021)后的8个地址, 那些是中间的8位寄存器。所以8x8 = 64。
我知道我可以使用这样的偏移量访问 P2OUT :
*(char *)(0x0021 + 0x0008) |= BIT0;
我想自己定义一个从1到13的GPIO列表,并打开和关闭它们,而不检查GPIO11是否在 PORT2 或 PORT1 ,我想要一个命令来完成所有这些。
是可能的吗?
答案 0 :(得分:3)
P1OUT |= 0x80000000000;
这不起作用,因为
您没有正确计算位数:
P1OUT |= 0x10000000000000000;
P1OUT
是一个8位寄存器,因此编译器会抛弃除最低8位之外的所有位。您必须使用足够大的数据类型(并且您要设置的位是内存中的第65位,因此您需要一个大于64位的类型):
*(uint128_t*)&P1OUT |= 0x10000000000000000;
你可以通过另一层间接获得你想要的东西:
volatile uint8_t * const ports[] = { &P1OUT, &P2OUT, &P3OUT };
static inline void setGPIO(unsigned int number)
{
*ports[number / 8] |= 1 << (number % 8);
}
答案 1 :(得分:1)
不,剩余数据不会从一个存储器地址溢出到下一个存储器地址。如果将数据写入8位地址,则会截断额外(最重要)位。
有几种方法可以解决这个问题。您可以为每个端口位设置一组函数,例如
write_GPIO_11(int bitval) { // pass 0 or 1
if (bitval)
P2OUT |= 0x08;
else
P2OUT &= 0xF7;
}
或者有单独的函数set_GPIO_11
和clear_GPIO_11
,这对inline
函数更有效,更好。
您也可以使用宏
#define GP11_ON (P2OUT |= 0x08)
...
GP11_ON;
然而,既然你谈到从一个端口溢出到下一个端口,我想知道你是否也想用一条指令写入所有13位(这必须是16位值)。这不能通过单次写入完成,但您可以进行单个函数调用,也可以是inline
。
write_GPIO_bits(unsigned int bitvals) {
P1OUT = bitvals;
P2OUT = bitvals >> 8;
}
等等。
答案 2 :(得分:0)
我使用以下方法:
“hardware_config.h”:
#define CONCAT_(a, b) a##b
#define BITSET(p, m) (CONCAT(p, OUT) |= m)
#define LEDGN_PORT P1
#define LEDGN_MASK 0x01
辅助函数最好位于不同的头文件中。
用法:
BITSET(LEDGN_PORT, LEDGN_MASK);
这不会增加程序代码的开销。