GPIOx(x=A,B,C,D,E,H)引脚配置需要几个方面: (配例的工程函数是可以到官网上下载使用手册的)
1,首先肯定是要将相应的引脚口挂在到的AHB/APB的时钟使能,即配置RCC_AHBENR寄存器。
GPIOC的使能位在BIT2 则 #DEFINE GPIOCEN (Unit32_t)0x0x00000004
RCC的起始地址为0x4002 3800
#define PERIPH_BASE ((uint32_t)0x40000000)
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)
#define RCC_BASE (AHBPERIPH_BASE + 0x3800)
再定义RCC寄存器结构体
typedef struct
{
__IO uint32_t CR;
__IO uint32_t ICSCR;
__IO uint32_t CFGR;
__IO uint32_t CIR;
__IO uint32_t AHBRSTR;
__IO uint32_t APB2RSTR;
__IO uint32_t APB1RSTR;
__IO uint32_t AHBENR;
__IO uint32_t APB2ENR;
__IO uint32_t APB1ENR;
__IO uint32_t AHBLPENR;
__IO uint32_t APB2LPENR;
__IO uint32_t APB1LPENR;
__IO uint32_t CSR;
} RCC_TypeDef;
#define RCC ((RCC_TypeDef *) RCC_BASE)
此处真的是很精妙,既把RCC定义成了一结构体,也阐明了它引用的地址。直接可以使用
void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState)
{
assert_param(IS_RCC_AHB_PERIPH(RCC_AHBPeriph));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE) {
RCC->AHBENR |= RCC_AHBPeriph;
}
else {
RCC->AHBENR &= ~RCC_AHBPeriph;
}
}
函数调用:RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
其中:#define RCC_AHBPeriph_GPIOC RCC_AHBENR_GPIOCEN
#DEFINE GPIOCEN (Unit32_t)0x0x00000004
RCC->AHBENR|=RCC_AHBPeriph 等价于 RCC->AHBENR=RCC->AHBENR|0x0x00000004,使得RCC_AHBENR寄存器中GPIOC的使能位置1;
但个人也有疑问:结构体中寄存器变量的位置如何确定?
隔天小哥自己阅读代码结构发现不同外设结构体的设置都是不同的,参照芯片手册后发现一个有趣的现象。
推测结构体内部成员的地址值是向上增长的,相应的寄存器成员变量地址也就确定了。
以下是结构体对照:
typedef struct # typedef struct
{ # {
__IO uint32_t KR; # __IO uint16_t CR1;
__IO uint32_t PR; # uint16_t RESERVED0;
__IO uint32_t RLR; # __IO uint16_t CR2;
__IO uint32_t SR; # uint16_t RESERVED1;
} IWDG_TypeDef; # __IO uint16_t SR;
~~~~~~~~~~~~ # uint16_t RESERVED2;
~~~~~~~~~~~~ # __IO uint16_t DR;
~~~~~~~~~~~~ # uint16_t RESERVED3;
~~~~~~~~~~~~ # __IO uint16_t CRCPR;
~~~~~~~~~~~~ # uint16_t RESERVED4;
~~~~~~~~~~~~ # __IO uint16_t RXCRCR;
~~~~~~~~~~~~ uint16_t RESERVED5;
~~~~~~~~~~~~ __IO uint16_t TXCRCR;
~~~~~~~~~~~~ uint16_t RESERVED6;
~~~~~~~~~~~~ } SPI_TypeDef;
波浪线仅为对齐好看使用
IWDG寄存器占据四字节的定义为 __IO uint32_t 类型
SPI 寄存器占据两字节的定义为 __IO uint16_t 类型,中间空出的则用 uint16_t RESERVED填充,可以证实以上的猜测。
上一篇:STM32通用定时器的几个重要寄存器
下一篇:STM32学习札记--ADC的有关函数个人见解
推荐阅读最新更新时间:2024-03-16 16:16
设计资源 培训 开发板 精华推荐
- AMD推出第二代Versal Premium系列产品:首款PCIe 6.0和CXL 3.1的SoC FPGA
- 红帽宣布达成收购Neural Magic的最终协议
- 5G网速比4G快但感知差!邬贺铨:6G标准制定应重视用户需求
- SEMI报告:2024年第三季度全球硅晶圆出货量增长6%
- OpenAI呼吁建立“北美人工智能联盟” 好与中国竞争
- 传OpenAI即将推出新款智能体 能为用户自动执行任务
- 尼得科智动率先推出两轮车用电动离合器ECU
- ASML在2024 年投资者日会议上就市场机遇提供最新看法
- AMD将裁员4%,以在人工智能芯片领域争取更强的市场地位
- Arm:以高效计算平台为核心,内外协力共筑可持续未来