STM32_引脚初始化与时钟基础
为什么每用一个GPIO引脚,都要初始化一次时钟?
TM32 微控制器采用了 时钟门控(Clock Gating)机制,这是现代微控制器的一种功耗管理策略。时钟门控机制的核心思想是,只有在外设需要运行时,才使能相应外设的时钟,而在不使用时关闭时钟,以减少功耗和节省电源。
每次需要初始化一次,后续设置的时候,要使用GPIO_Pin_x来set和reset
GPIO_Pin_x有多个的时候,只需要一个GPIO_InitTypeDef,每次可以覆盖设置,调用GPIO_Init()即可
GPIO_InitTypeDef GPIO_InitStructure;
//初始化时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//GPIO引脚初始化
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
//把初始化的值重新在检查赋值一次,与硬件对应上
//为什么是GPIOA,原理图中标记了
GPIO_Init(GPIOA, &GPIO_InitStructure);
时钟设置
void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
{
/* Check the parameters */
assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph));
assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
//RCC->APB2ENR寄存器对应的RCC_APB2Periph位被置位1,选择响应的时钟
RCC->APB2ENR |= RCC_APB2Periph;
}
else
{
//RCC->APB2ENR寄存器对应的RCC_APB2Periph位被置位0,其余为不变,关闭响应的时钟
RCC->APB2ENR &= ~RCC_APB2Periph;
}
}
GPIO引脚的参数选择
typedef struct
{
uint16_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured.
This parameter can be any value of @ref GPIO_pins_define */
GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins.
This parameter can be a value of @ref GPIOSpeed_TypeDef */
GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins.
This parameter can be a value of @ref GPIOMode_TypeDef */
}GPIO_InitTypeDef;
//速度可选项
typedef enum
{
GPIO_Speed_10MHz = 1,
GPIO_Speed_2MHz,
GPIO_Speed_50MHz
}GPIOSpeed_TypeDef;
//模式可选项
typedef enum
{ GPIO_Mode_AIN = 0x0,
GPIO_Mode_IN_FLOATING = 0x04,
GPIO_Mode_IPD = 0x28,
GPIO_Mode_IPU = 0x48,
GPIO_Mode_Out_OD = 0x14,
GPIO_Mode_Out_PP = 0x10,
GPIO_Mode_AF_OD = 0x1C,
GPIO_Mode_AF_PP = 0x18
}GPIOMode_TypeDef;
每个外设(如 GPIO、USART、SPI、ADC 等)都有自己的时钟源。
#define RCC_APB2Periph_AFIO ((uint32_t)0x00000001)
//ABCDEFG 其实是代表不同的 GPIO 端口组,而每个端口组下面可以包含多个 GPIO 引脚(Pin)
//GPIOA代表一个时钟组,00000004代表位掩码 用于给寄存器RCC->APB2ENR确定是那一组的时钟使能
//在原理图中都会标注引脚属于哪一个GPIO组
//RCC->APB2ENR |= RCC_APB2Periph_GPIOA;
#define RCC_APB2Periph_GPIOA ((uint32_t)0x00000004)
#define RCC_APB2Periph_GPIOB ((uint32_t)0x00000008)
#define RCC_APB2Periph_GPIOC ((uint32_t)0x00000010)
#define RCC_APB2Periph_GPIOD ((uint32_t)0x00000020)
#define RCC_APB2Periph_GPIOE ((uint32_t)0x00000040)
#define RCC_APB2Periph_GPIOF ((uint32_t)0x00000080)
#define RCC_APB2Periph_GPIOG ((uint32_t)0x00000100)
#define RCC_APB2Periph_ADC1 ((uint32_t)0x00000200)
#define RCC_APB2Periph_ADC2 ((uint32_t)0x00000400)
#define RCC_APB2Periph_TIM1 ((uint32_t)0x00000800)
#define RCC_APB2Periph_SPI1 ((uint32_t)0x00001000)
#define RCC_APB2Periph_TIM8 ((uint32_t)0x00002000)
#define RCC_APB2Periph_USART1 ((uint32_t)0x00004000)
#define RCC_APB2Periph_ADC3 ((uint32_t)0x00008000)
#define RCC_APB2Periph_TIM15 ((uint32_t)0x00010000)
#define RCC_APB2Periph_TIM16 ((uint32_t)0x00020000)
#define RCC_APB2Periph_TIM17 ((uint32_t)0x00040000)
#define RCC_APB2Periph_TIM9 ((uint32_t)0x00080000)
#define RCC_APB2Periph_TIM10 ((uint32_t)0x00100000)
#define RCC_APB2Periph_TIM11 ((uint32_t)0x00200000)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)