使用MSP430的所有端口作为一个大端口 - 是否可能?

时间:2015-05-22 16:51:21

标签: embedded msp430 memory-mapping

将所有MSP430端口用作一个端口会更方便。 我想可能会把寄存器溢出到下一个内存地址,但是它不起作用(或者说我做得不对)。

要访问 PORT2 BIT0 ,我尝试了类似的东西:

P1OUT |= 0x80000000000;

因为在内存中 P2OUT (0x0029)是 P1OUT (0x0021)后的8个地址, 那些是中间的8位寄存器。所以8x8 = 64。

我知道我可以使用这样的偏移量访问 P2OUT

*(char *)(0x0021 + 0x0008)  |=  BIT0;

我想自己定义一个从1到13的GPIO列表,并打开和关闭它们,而不检查GPIO11是否在 PORT2 PORT1 ,我想要一个命令来完成所有这些。

是可能的吗?

3 个答案:

答案 0 :(得分:3)

P1OUT |= 0x80000000000;

这不起作用,因为

  1. 您没有正确计算位数:

    P1OUT |= 0x10000000000000000;
    
  2. P1OUT是一个8位寄存器,因此编译器会抛弃除最低8位之外的所有位。您必须使用足够大的数据类型(并且您要设置的位是内存中的第65位,因此您需要一个大于64位的类型):

    *(uint128_t*)&P1OUT |= 0x10000000000000000;
    
  3. 没有128位类型。
  4. 你可以通过另一层间接获得你想要的东西:

    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_11clear_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);

这不会增加程序代码的开销。