- 首先前面写了配置所需要的一些必要内核与文件,下面写一下一些比较繁琐的东西(容易在我脑子里面流失的东西)
基础初始化
首先在配置32的过程中我们避免不了第IO口的配置,在进行配置的过程中我们首先需要对其外设时钟进行配置。
外设时钟在32最小系统开发板上分为两个外设,分别为APB1和APB2其中GPIOA和GPIOB都存在于APB2上面
以GPIOA为例:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //APB2外设上GPIOA使其ENABLE。
GPIO_InitTypeDef GPIO_InitStructure;//每一个外设都会有一个初始化,包括中断、定时器等
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
八种输出方式
特征 |
可读取引脚电平,若引脚悬空,则电平不确定 |
可读取引脚电平,内部连接上拉电阻,悬空时默认高电平 |
可读取引脚电平,内部连接下拉电阻,悬空时默认低电平 |
GPIO无效,引脚直接接入内部ADC |
可输出引脚电平,高电平为高阻态,低电平接VSS |
可输出引脚电平,高电平接VDD,低电平接VSS |
由片上外设控制,高电平为高阻态,低电平接VSS |
由片上外设控制,高电平接VDD,低电平接VSS |
- 1. GPIO_MODE_AIN 模拟输入
- 2. GPIO_MODE_IN_FLOATING 浮空输入
- 3. GPIO_MODE_IPD 下拉输入
- 4. GPIO_MODE_IPU 上拉输入
- 5. GPIO-MODE_OUT_OD 开漏输出
- 6. GPIO_MODE_OUT_PP 推挽输出
- 7. GPIO_MODE_AF_OD 复用开漏输出
- 8. GOIO_MODE_AF_PP 复用推挽输出
模式名称 | 性质 |
浮空输入 | 数字输入 |
上拉输入 | 数字输入 |
下拉输入 | 数字输入 |
模拟输入 | 模拟输入 |
开漏输出 | 数字输出 |
推挽输出 | 数字输出 |
复用开漏输出 | 数字输出 |
复用推挽输出 | 数字输出 |
具体可见以下博客:
https://blog.csdn.net/helaisun/article/details/90738803
中断配置
中断系统
配置中断流程
- 选择并初始化外部中断引脚。首先需要确定使用的GPIO引脚,并使用GPIO_Init()函数将其配置为输入模式(GPIO_Mode_IN_FLOATING或GPIO_Mode_IPU/IPD等)。然后使用EXTI_Init()函数配置外部中断线路(EXTI_LineX),将其连接到相应的GPIO引脚。
-
• EXTI 可以监测指定 GPIO 口的电平信号,当其指定的 GPIO 口产生电平变化时, EXTI 将立即向 NVIC 发出中断申请,经过 NVIC 裁决后即可中断 CPU 主程序,使 CPU 执行 EXTI 对应的中断程序• 支持的触发方式:上升沿 / 下降沿 / 双边沿 / 软件触发• 支持的 GPIO 口:所有 GPIO 口,但相同的 Pin 不能同时触发中断
EXTI_InitTypeDef EXTI_InitStructure;
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
EXTI_InitStructure.EXTI_Line = EXTI_Line0; //中断线
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断方式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //中断使能
EXTI_Init(&EXTI_InitStructure);
NVIC配置
- 配置NVIC中断控制器。使用NVIC_InitTypeDef结构体初始化NVIC,设置优先级和分组方式。然后使用NVIC_EnableIRQ()使能中断向量,并将中断线路连接到中断处理函数。
中断优先级的设置对于处理多个中断同时发生时的优先级调度非常重要。较高的抢占优先级将具有更高的优先级,并且可以打断较低优先级的中断处理程序。而在相同的抢占优先级下,较低的子优先级将被优先处理。
分组方式 | 抢占优先级 | 响应优先级 |
分组0 | 0位,取值为0 | 4位,取值为0~15 |
分组1 | 1位,取值为0~1 | 3位,取值为0~7 |
分组2 | 2位,取值为0~3 | 2位,取值为0~3 |
分组3 | 3位,取值为0~7 | 1位,取值为0~1 |
分组4 | 4位,取值为0~15 | 0位,取值为0 |
代码演示:
-
NVIC_InitTypeDef NVIC_InitStruct; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); // 设置中断优先级分组为4 bits抢占优先级和0 bits子优先级 NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn; // 中断通道为USART1 NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; // 抢占优先级为0 NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; // 子优先级为0 NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStruct);
- 实现中断处理函数。针对配置的中断线路,编写对应的中断处理函数。在函数开头调用NVIC_ClearPendingIRQ()函数清除中断挂起标志。可以使用特殊的语法定义中断处理函数,在函数名称前加__irq关键字,例如void EXTI0_IRQHandler(void)。
- 总结NVIC可以简单理解为分配中断通道,分配中断通道的中断优先级,并使中断使能
下面做一个完整的中断实例演示:
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
// 使能GPIOA时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
// 配置PA0为输入模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置外部中断线0对应的GPIO引脚为PA0
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
// 配置外部中断线0
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; // 上升沿和下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
// 配置中断向量
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
中断函数:
void EXTI0_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line0) != RESET)
{
// 执行中断处理操作
// 清除中断标志位
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
在主函数中,首先使用NVIC_Init
函数配置中断向量,并设置中断优先级。然后在主循环中执行其他任务。当外部中断线0被触发时,中断函数EXTI0_IRQHandler
将被自动调用。(使用不同的中断线其中断函数不同)。