微控制器中寄存器的寻址引脚

Addressing pins of Register in microcontrollers

我正在研究 Keil 软件并使用 LM3S316 微控制器。通常我们以以下形式寻址微控制器中的寄存器:

#define GPIO_PORTC_DATA_R       (*((volatile uint32_t *)0x400063FC))

我的问题是如何访问寄存器的单个引脚,例如,如果我有这种方法:

char process_key(int a)
{  PC_0 = a ;}

如何获得PC_0以及如何定义它?

谢谢

鉴于说:

#define PIN0 (1u<<0)
#define PIN1 (1u<<1)
#define PIN2 (1u<<2)
// etc...

然后:

char process_key(int a)
{  
    if( a != 0 )
    {
        // Set bit
        GPIO_PORTC_DATA_R |= PIN0 ;
    }
    else
    {
        // Clear bit
        GPIO_PORTC_DATA_R &= ~PIN0 ;
    }
}

How do you set, clear, and toggle a single bit?

介绍了这种惯用技术的概括

然而,如果寄存器可能在不同的 thread/interrupt 上下文中被访问,那么 |= / &= 隐含的读-修改-写可能会出现问题,以及添加可能不需要的高架。 Cortex-M3/4 部件具有称为位带的功能,允许直接和原子地寻址各个位。给定:

volatile uint32_t* getBitBandAddress( volatile const void* address, int bit )
{
    __IO uint32_t* bit_address = 0;
    uint32_t addr = reinterpret_cast<uint32_t>(address);

    // This bit maniplation makes the function valid for RAM
    // and Peripheral bitband regions
    uint32_t word_band_base = addr & 0xf0000000u;
    uint32_t bit_band_base = word_band_base | 0x02000000u;
    uint32_t offset = addr - word_band_base;

    // Calculate bit band address
    bit_address = reinterpret_cast<__IO uint32_t*>(bit_band_base + (offset * 32u) + (static_cast<uint32_t>(bit) * 4u));

    return bit_address ;
} 

那么你可以拥有:

char process_key(int a)
{  
    static volatile uint32_t* PC0_BB_ADDR = getBitBandAddress( &GPIO_PORTC_DATA_R, 0 ) ;

    *PC0_BB_ADDR = a ;
}

您当然可以确定并硬编码位带地址;例如:

#define PC0 (*((volatile uint32_t *)0x420C7F88u))

然后:

char process_key(int a)
{  
    PC0 = a ;
}

可以找到位带地址计算的详细信息ARM Cortex-M Technical Reference Manual, and there is an on-line calculator here