SystemInit()函数中设置的系统时钟大小:
SYSCLK(系统时钟) =72MHz
AHB 总线时钟(使用 SYSCLK)=72MHz
APB1 总线时钟(PCLK1)=36MHz
APB2 总线时钟(PCLK2) =72MHz
PLL 时钟 =72MHz
复用端口初始化步骤:
- GPIO 端口时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
- 复用的外设时钟使能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
- 端口模式配置
在 IO 复用位内置外设功能引脚的时候,必须设置 GPIO 端口的模式
//USART1_TX PA.9 复用推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);
//USART1_RX PA.10 浮空输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);
使用复用功能最少使能2个时钟:
- GPIO时钟使能
- 复用的外设时钟使能
同时初始化GPIO以及复用外设功能
重映射使能时钟:
- GPIO时钟使能
- 复用的外设时钟使能
- 使能AFIO功能时钟
重映射详细步骤:
- 使能GPIOB时钟:
RCC_APB2PeriphClockCmd(RCC)APB2Periph_GPIOB, ENABLE);
- 使能串口1时钟:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
- 使能AFIO时钟:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
- 开启重映射:
GPIO_PinRemapComfig(GPIO_Remap_USART1, ENABLE);
使用USART3的部分重映射,调用的函数方法为:
GPIO_PinRemapConfig(GPIO_PartialRemap_USART3, ENABLE);
与内嵌向量中断控制器相关的寄存器:
- ISER[8]:中断使能寄存器组;
ISER[0]: bit0~bit31
ISER[1]: bit32~bit59
使能中断设置相应ISER位为1
- ICER[8]:中断除能寄存器组;
清除中断位
- ISPR[8]:中断挂起控制寄存器组;
挂起正在执行的中断,执行同级或更高级别的中断
- ICPR[8]:中断解挂控制寄存器组;
- IABR[8]:中断激活标志位寄存器组;
只读寄存器,从而知当前在执行的中断
- IP[240]:中断优先级控制的寄存器组;
与中断分组相关
240个8bit的寄存器组成
每个可屏蔽中断占用8bit,共表示240个
STM32只用前60个
每个可屏蔽中断只用高4bit
抢占优先级
子优先级
各占用几位根据SCB->AIRCR中的中断分组设置而定
STM32中断分组:
组 | AIRCR[10:8] | bit[7:4] | 分配结果 |
---|---|---|---|
0 | 111 | 0:4 | 0位抢占优先级,4位响应优先级 |
1 | 110 | 1:3 | 1位抢占优先级,3位响应优先级 |
2 | 101 | 2:2 | 2位抢占优先级,2位响应优先级 |
3 | 100 | 3:1 | 3位抢占优先级,1位响应优先级 |
4 | 011 | 4:0 | 4位抢占优先级,0位响应优先级 |
该分组的设置是由SCB->AIRCR寄存器的bit10~8来定义的。
抢占优先级的级别高于响应优先级,数值越小所代表的优先级就越高。
注意:
- 如果两个中断的抢占优先级和响应优先级都是一样的话,则中断先发生先执行。
- 高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。
- 抢占优先级相同的中断,高优先级的响应优先级不可以打断低响应优先级的中断。
设置整个系统的中断优先级分组:
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //优先级分组值为2
设置抢占优先级和响应优先级:
使能串口1中断,同时设置抢占优先级为1,子优先级为2
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_TRQChannel = USART1_IRQn; //串口1中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级为1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子优先级为2
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据上面指定的参数初始化NVIC寄存器
NVIC_InitTypeDef 结构体中间有三个成员变量:
NVIC_IRQChannel:定义初始化的是哪个中断
NVIC_IRQChannelPreemptionPriority:定义这个中断的抢占优先级别。
NVIC_IRQChannelSubPriority:定义这个中断的子优先级别。
NVIC_IRQChannelCmd:该中断是否使能。
中断优先级设置步骤:
- 系统运行开始的时候设置中断分组。确定组号,即确定抢占优先级和子优先级的分配位数。调用函数为 NVIC_PriorityGroupConfig();
- 设置所用到的中断的中断优先级别。对每个中断调用函数为NVIC_Init();
GPIO初始化函数:
GIPO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
GPIO初始化多个IO口的方式:
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5| GPIO_Pin_6| GPIO_Pin_7; //指定端口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //端口模式:推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化