微控制器中寄存器的寻址引脚
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。
我正在研究 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。