文章目录
- 一、外部中断
- 硬件:STM32F091RCT6
- HAL库代码思路:
- 硬件:STM32F407
- 标准库示例代码:
- proj1_外部中断_按键1
- proj2_4个按键
- proj3_按键中断_切换系统时钟源
- proj4_中断优先级
- 二、内部中断
- 硬件STM32F407串口中断
- 总结
提示:以下是本篇文章正文内容,下面案例可供参考
一、外部中断
硬件:STM32F091RCT6
(两种开发方式: 寄存器开发/库函数开发,大部分写的代码用寄存器来写,很大得提高效率)
ST公司有三种库版本:标准库、HAL库、LL库。NUCLEO-F091RC这里例程采用HAL库进行编辑。
按键外部中断代码,采用引脚控制高低电平,按一下检测是否这个引脚,翻转led灯电平。
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
/*Configure GPIO pin : PC13 */
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pin : PA5 */
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI4_15_IRQn, 2, 0);//配置中断优先级,包括抢占优先级和响应优先级
HAL_NVIC_EnableIRQ(EXTI4_15_IRQn);//打开中断使能
}
/* USER CODE BEGIN 2 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == GPIO_PIN_13)
{
/* Toggle LED2 */
HAL_GPIO_TogglePin( GPIOA, GPIO_PIN_5);
}
}
/* USER CODE END 2 */
int main(void)
{
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
while()
{
}
}
HAL库代码思路:
1、初始化——》void MX_GPIO_Init(void)
打开时钟使能
初始化GPIO引脚
配置中断优先级,包括抢占优先级和响应优先级
打开中断使能
2、配置中断服务函数
正常情况是还需要写个中断函数,如下图所示。在使用stm32cube生成的stm32f0xx_it.c是已经给你配置好中断函数void EXTI4_15_IRQHandler(void),记住中断函数是不知道什么时候发生的,格式void 函数名(void) ,是没有传参的。
我们右键进来这个函数声明,发现只需要配置这个函数HAL_GPIO_EXTI_Callback(GPIO_Pin);就能达到配置好中断服务函数。然后就可以用了。
/**
* @brief Handle EXTI interrupt request.
* @param GPIO_Pin Specifies the port pin connected to corresponding EXTI line.
* @retval None
*/
void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
/* EXTI line interrupt detected */
if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u)
{
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
HAL_GPIO_EXTI_Callback(GPIO_Pin);
}
}
void HAL_GPIO_EXTI_Callback(GPIO_Pin)
所以中断简要说就两个步骤,初始化和中断服务函数,往下看几个例程加深印象,建议自己也拿个开发板写来玩一玩,其中还得考虑到中断服务函数内要清除中断标志位。
硬件:STM32F407
标准库编辑代码
不管怎么说,做嵌入式得看的懂原理图,从原理图中知道要怎么配置。
当用标准库初始化配置得时候不会配置或者不想自己配置,打开**《库函数手册》**,要这个库函数手册评论区说一下,我直接发给你吧,直接复制黏贴代码进自己得工程。
标准库示例代码:
proj1_外部中断_按键1
#include <stm32f4xx.h>
#define PFout(n) *(volatile uint32_t *)(0x42000000 + (GPIOF_BASE + 0x14 - 0x40000000)*32 + n*4)
#define PEout(n) *(volatile uint32_t *)(0x42000000 + (GPIOE_BASE + 0x14 - 0x40000000)*32 + n*4)
#define PAin(n) *(volatile uint32_t *)(0x42000000 + (GPIOA_BASE + 0x10 - 0x40000000)*32 + n*4)
#define PEin(n) *(volatile uint32_t *)(0x42000000 + (GPIOE_BASE + 0x10 - 0x40000000)*32 + n*4)
#define BEEP PFout(8)
#define LED1 PFout(9)
#define LED2 PFout(10)
#define LED3 PEout(13)
#define LED4 PEout(14)
#define KEY1 PAin(0)
#define KEY2 PEin(2)
#define KEY3 PEin(3)
#define KEY4 PEin(4)
static GPIO_InitTypeDef GPIO_InitStructure;
static EXTI_InitTypeDef EXTI_InitStructure;
static NVIC_InitTypeDef NVIC_InitStructure;
// 粗延时(软件延时,不精确)
void sleep(void)
{
volatile int i = 0x200000;
while(i--);
}
// 初始化4个LED
void LED_Init(void)
{
// PF9 PF10 PE13 PE14
/* 1.打开外设时钟(根据需求再开启,节省功耗) */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF|RCC_AHB1Periph_GPIOE, ENABLE);
/* 2.配置GPIO */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // GPIO引脚编号
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; // 模式:输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 类型:推挽
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // 输出速率:跟功耗相关
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; // 无上下拉
GPIO_Init(GPIOF, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14; // GPIO引脚编号
GPIO_Init(GPIOE, &GPIO_InitStructure);
// 3.给LED一个初始化电平(全灭)
GPIO_SetBits(GPIOF, GPIO_Pin_9 | GPIO_Pin_10);
GPIO_SetBits(GPIOE, GPIO_Pin_13 | GPIO_Pin_14);
}
// 初始化蜂鸣器
void BEEP_Init(void)
{
// PF8
/* 1.打开外设时钟(根据需求再开启,节省功耗) */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
/* 2.配置GPIO */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; // GPIO引脚编号
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; // 模式:输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 类型:推挽
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // 输出速率:跟功耗相关
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; // 无上下拉
GPIO_Init(GPIOF, &GPIO_InitStructure);
// 3.给蜂鸣器一个初始化电平(不响)
GPIO_ResetBits(GPIOF, GPIO_Pin_8);
}
// 初始化按键(外部中断)
void KEY_EXTI_Init(void)
{
/* 1.打开外设时钟(根据需求再开启,节省功耗) */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/* 使能系统配置控制器 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
/* 2.配置GPIO */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // GPIO引脚编号
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; // 模式:输入模式
//GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 类型:推挽(输入模式无效)
//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // 输出速率:跟功耗相关(输入模式无效)
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; // 无上下拉
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 3.连接外部中断线 */
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
/* 4.配置外部中断线 */
EXTI_InitStructure.EXTI_Line = EXTI_Line0; // 外部中断线0
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; // 中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* 5.配置NVIC中断优先级 */
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; // 子优先级(响应优先级)
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
int main()
{
LED_Init(); // 初始化4个LED
BEEP_Init(); // 初始化蜂鸣器
KEY_EXTI_Init(); // 初始化按键(外部中断)
while(1)
{
}
}
// 中断服务函数(触发条件:按键PA0按下(产生下降沿))
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0) != RESET)
{
LED1 = ~LED1;
/* 清除标志位(便于下次产生中断) */
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
proj2_4个按键
#include <stm32f4xx.h>
#define PFout(n) *(volatile uint32_t *)(0x42000000 + (GPIOF_BASE + 0x14 - 0x40000000)*32 + n*4)
#define PEout(n) *(volatile uint32_t *)(0x42000000 + (GPIOE_BASE + 0x14 - 0x40000000)*32 + n*4)
#define PAin(n) *(volatile uint32_t *)(0x42000000 + (GPIOA_BASE + 0x10 - 0x40000000)*32 + n*4)
#define PEin(n) *(volatile uint32_t *)(0x42000000 + (GPIOE_BASE + 0x10 - 0x40000000)*32 + n*4)
#define BEEP PFout(8)
#define LED1 PFout(9)
#define LED2 PFout(10)
#define LED3 PEout(13)
#define LED4 PEout(14)
#define KEY1 PAin(0)
#define KEY2 PEin(2)
#define KEY3 PEin(3)
#define KEY4 PEin(4)
static GPIO_InitTypeDef GPIO_InitStructure;
static EXTI_InitTypeDef EXTI_InitStructure;
static NVIC_InitTypeDef NVIC_InitStructure;
// 粗延时(软件延时,不精确)
void sleep(void)
{
volatile int i = 0x200000;
while(i--);
}
// 初始化4个LED
void LED_Init(void)
{
// PF9 PF10 PE13 PE14
/* 1.打开外设时钟(根据需求再开启,节省功耗) */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF|RCC_AHB1Periph_GPIOE, ENABLE);
/* 2.配置GPIO */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // GPIO引脚编号
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; // 模式:输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 类型:推挽
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // 输出速率:跟功耗相关
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; // 无上下拉
GPIO_Init(GPIOF, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14; // GPIO引脚编号
GPIO_Init(GPIOE, &GPIO_InitStructure);
// 3.给LED一个初始化电平(全灭)
GPIO_SetBits(GPIOF, GPIO_Pin_9 | GPIO_Pin_10);
GPIO_SetBits(GPIOE, GPIO_Pin_13 | GPIO_Pin_14);
}
// 初始化蜂鸣器
void BEEP_Init(void)
{
// PF8
/* 1.打开外设时钟(根据需求再开启,节省功耗) */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
/* 2.配置GPIO */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; // GPIO引脚编号
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; // 模式:输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 类型:推挽
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // 输出速率:跟功耗相关
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; // 无上下拉
GPIO_Init(GPIOF, &GPIO_InitStructure);
// 3.给蜂鸣器一个初始化电平(不响)
GPIO_ResetBits(GPIOF, GPIO_Pin_8);
}
// 初始化按键(外部中断)
void KEY_EXTI_Init(void)
{
/* 1.打开外设时钟(根据需求再开启,节省功耗) */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOE, ENABLE);
/* 使能系统配置控制器 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
/* 2.配置4个按键的GPIO */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // GPIO引脚编号
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; // 模式:输入模式
//GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 类型:推挽(输入模式无效)
//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // 输出速率:跟功耗相关(输入模式无效)
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; // 无上下拉
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4; // GPIO引脚编号
GPIO_Init(GPIOE, &GPIO_InitStructure);
/* 3.连接外部中断线 */
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource2);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource3);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource4);
/* 4.配置外部中断线 */
EXTI_InitStructure.EXTI_Line = EXTI_Line0|EXTI_Line2|EXTI_Line3|EXTI_Line4; // 外部中断线
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; // 中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* 5.配置NVIC中断优先级 */
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; // 子优先级(响应优先级)
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; // 子优先级(响应优先级)
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; // 子优先级(响应优先级)
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; // 子优先级(响应优先级)
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
int main()
{
LED_Init(); // 初始化4个LED
BEEP_Init(); // 初始化蜂鸣器
KEY_EXTI_Init(); // 初始化按键(外部中断)
while(1)
{
}
}
// 中断服务函数(触发条件:按键1按下(PA0产生下降沿))
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0) != RESET)
{
LED1 = ~LED1;
/* 清除标志位(便于下次产生中断) */
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
// 中断服务函数(触发条件:按键2按下(PE2产生下降沿))
void EXTI2_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line2) != RESET)
{
LED2 = ~LED2;
/* 清除标志位(便于下次产生中断) */
EXTI_ClearITPendingBit(EXTI_Line2);
}
}
// 中断服务函数(触发条件:按键3按下(PE3产生下降沿))
void EXTI3_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line3) != RESET)
{
LED3 = ~LED3;
/* 清除标志位(便于下次产生中断) */
EXTI_ClearITPendingBit(EXTI_Line3);
}
}
// 中断服务函数(触发条件:按键4按下(PE4产生下降沿))
void EXTI4_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line4) != RESET)
{
LED4 = ~LED4;
/* 清除标志位(便于下次产生中断) */
EXTI_ClearITPendingBit(EXTI_Line4);
}
}
proj3_按键中断_切换系统时钟源
#include <stm32f4xx.h>
#define PFout(n) *(volatile uint32_t *)(0x42000000 + (GPIOF_BASE + 0x14 - 0x40000000)*32 + n*4)
#define PEout(n) *(volatile uint32_t *)(0x42000000 + (GPIOE_BASE + 0x14 - 0x40000000)*32 + n*4)
#define PAin(n) *(volatile uint32_t *)(0x42000000 + (GPIOA_BASE + 0x10 - 0x40000000)*32 + n*4)
#define PEin(n) *(volatile uint32_t *)(0x42000000 + (GPIOE_BASE + 0x10 - 0x40000000)*32 + n*4)
#define BEEP PFout(8)
#define LED1 PFout(9)
#define LED2 PFout(10)
#define LED3 PEout(13)
#define LED4 PEout(14)
#define KEY1 PAin(0)
#define KEY2 PEin(2)
#define KEY3 PEin(3)
#define KEY4 PEin(4)
static GPIO_InitTypeDef GPIO_InitStructure;
static EXTI_InitTypeDef EXTI_InitStructure;
static NVIC_InitTypeDef NVIC_InitStructure;
// 粗延时(软件延时,不精确)
void sleep(void)
{
volatile int i = 0x200000;
while(i--);
}
// 初始化4个LED
void LED_Init(void)
{
// PF9 PF10 PE13 PE14
/* 1.打开外设时钟(根据需求再开启,节省功耗) */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF|RCC_AHB1Periph_GPIOE, ENABLE);
/* 2.配置GPIO */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // GPIO引脚编号
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; // 模式:输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 类型:推挽
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // 输出速率:跟功耗相关
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; // 无上下拉
GPIO_Init(GPIOF, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14; // GPIO引脚编号
GPIO_Init(GPIOE, &GPIO_InitStructure);
// 3.给LED一个初始化电平(全灭)
GPIO_SetBits(GPIOF, GPIO_Pin_9 | GPIO_Pin_10);
GPIO_SetBits(GPIOE, GPIO_Pin_13 | GPIO_Pin_14);
}
// 初始化蜂鸣器
void BEEP_Init(void)
{
// PF8
/* 1.打开外设时钟(根据需求再开启,节省功耗) */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
/* 2.配置GPIO */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; // GPIO引脚编号
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; // 模式:输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 类型:推挽
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // 输出速率:跟功耗相关
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; // 无上下拉
GPIO_Init(GPIOF, &GPIO_InitStructure);
// 3.给蜂鸣器一个初始化电平(不响)
GPIO_ResetBits(GPIOF, GPIO_Pin_8);
}
// 初始化按键(外部中断)
void KEY_EXTI_Init(void)
{
/* 1.打开外设时钟(根据需求再开启,节省功耗) */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOE, ENABLE);
/* 使能系统配置控制器 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
/* 2.配置4个按键的GPIO */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // GPIO引脚编号
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; // 模式:输入模式
//GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 类型:推挽(输入模式无效)
//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // 输出速率:跟功耗相关(输入模式无效)
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; // 无上下拉
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4; // GPIO引脚编号
GPIO_Init(GPIOE, &GPIO_InitStructure);
/* 3.连接外部中断线 */
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource2);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource3);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource4);
/* 4.配置外部中断线 */
EXTI_InitStructure.EXTI_Line = EXTI_Line0|EXTI_Line2|EXTI_Line3|EXTI_Line4; // 外部中断线
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; // 中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* 5.配置NVIC中断优先级 */
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; // 子优先级(响应优先级)
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; // 子优先级(响应优先级)
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; // 子优先级(响应优先级)
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; // 子优先级(响应优先级)
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
int main()
{
LED_Init(); // 初始化4个LED
BEEP_Init(); // 初始化蜂鸣器
KEY_EXTI_Init(); // 初始化按键(外部中断)
while(1)
{
// 流水灯状态
LED1 = ~LED1;
sleep();
LED2 = ~LED2;
sleep();
LED3 = ~LED3;
sleep();
LED4 = ~LED4;
sleep();
}
}
// 中断服务函数(触发条件:按键1按下(PA0产生下降沿))
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0) != RESET)
{
/* 按键1:选择PLL(168MHz) */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= RCC_CFGR_SW_PLL;
/* 清除标志位(便于下次产生中断) */
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
// 中断服务函数(触发条件:按键2按下(PE2产生下降沿))
void EXTI2_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line2) != RESET)
{
/* 按键2:选择HSI(16MHz) */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= RCC_CFGR_SW_HSI;
/* 清除标志位(便于下次产生中断) */
EXTI_ClearITPendingBit(EXTI_Line2);
}
}
// 中断服务函数(触发条件:按键3按下(PE3产生下降沿))
void EXTI3_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line3) != RESET)
{
/* 按键3:选择HSE(8MHz) */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= RCC_CFGR_SW_HSE;
/* 清除标志位(便于下次产生中断) */
EXTI_ClearITPendingBit(EXTI_Line3);
}
}
// 中断服务函数(触发条件:按键4按下(PE4产生下降沿))
void EXTI4_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line4) != RESET)
{
LED4 = ~LED4;
/* 清除标志位(便于下次产生中断) */
EXTI_ClearITPendingBit(EXTI_Line4);
}
}
proj4_中断优先级
#include <stm32f4xx.h>
#define PFout(n) *(volatile uint32_t *)(0x42000000 + (GPIOF_BASE + 0x14 - 0x40000000)*32 + n*4)
#define PEout(n) *(volatile uint32_t *)(0x42000000 + (GPIOE_BASE + 0x14 - 0x40000000)*32 + n*4)
#define PAin(n) *(volatile uint32_t *)(0x42000000 + (GPIOA_BASE + 0x10 - 0x40000000)*32 + n*4)
#define PEin(n) *(volatile uint32_t *)(0x42000000 + (GPIOE_BASE + 0x10 - 0x40000000)*32 + n*4)
#define BEEP PFout(8)
#define LED1 PFout(9)
#define LED2 PFout(10)
#define LED3 PEout(13)
#define LED4 PEout(14)
#define KEY1 PAin(0)
#define KEY2 PEin(2)
#define KEY3 PEin(3)
#define KEY4 PEin(4)
static GPIO_InitTypeDef GPIO_InitStructure;
static EXTI_InitTypeDef EXTI_InitStructure;
static NVIC_InitTypeDef NVIC_InitStructure;
// 粗延时(软件延时,不精确)
void sleep(void)
{
volatile int i = 0x4000000;
while(i--);
}
// 初始化4个LED
void LED_Init(void)
{
// PF9 PF10 PE13 PE14
/* 1.打开外设时钟(根据需求再开启,节省功耗) */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF|RCC_AHB1Periph_GPIOE, ENABLE);
/* 2.配置GPIO */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // GPIO引脚编号
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; // 模式:输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 类型:推挽
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // 输出速率:跟功耗相关
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; // 无上下拉
GPIO_Init(GPIOF, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14; // GPIO引脚编号
GPIO_Init(GPIOE, &GPIO_InitStructure);
// 3.给LED一个初始化电平(全灭)
GPIO_SetBits(GPIOF, GPIO_Pin_9 | GPIO_Pin_10);
GPIO_SetBits(GPIOE, GPIO_Pin_13 | GPIO_Pin_14);
}
// 初始化蜂鸣器
void BEEP_Init(void)
{
// PF8
/* 1.打开外设时钟(根据需求再开启,节省功耗) */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
/* 2.配置GPIO */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; // GPIO引脚编号
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; // 模式:输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 类型:推挽
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // 输出速率:跟功耗相关
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; // 无上下拉
GPIO_Init(GPIOF, &GPIO_InitStructure);
// 3.给蜂鸣器一个初始化电平(不响)
GPIO_ResetBits(GPIOF, GPIO_Pin_8);
}
// 初始化按键(外部中断)
void KEY_EXTI_Init(void)
{
/* 1.打开外设时钟(根据需求再开启,节省功耗) */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOE, ENABLE);
/* 使能系统配置控制器 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
/* 2.配置4个按键的GPIO */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // GPIO引脚编号
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; // 模式:输入模式
//GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; // 类型:推挽(输入模式无效)
//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; // 输出速率:跟功耗相关(输入模式无效)
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; // 无上下拉
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4; // GPIO引脚编号
GPIO_Init(GPIOE, &GPIO_InitStructure);
/* 3.连接外部中断线 */
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource2);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource3);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource4);
/* 4.配置外部中断线 */
EXTI_InitStructure.EXTI_Line = EXTI_Line0|EXTI_Line2|EXTI_Line3|EXTI_Line4; // 外部中断线
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; // 中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* 5.配置NVIC中断优先级(数值越大,优先级越低) */
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; // 子优先级(响应优先级)
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; // 子优先级(响应优先级)
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; // 子优先级(响应优先级)
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F; // 子优先级(响应优先级)
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
int main()
{
// 中断优先级2组:4级抢占优先级,支持4级响应优先级
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
LED_Init(); // 初始化4个LED
BEEP_Init(); // 初始化蜂鸣器
KEY_EXTI_Init(); // 初始化按键(外部中断)
while(1)
{
}
}
// 中断服务函数(触发条件:按键1按下(PA0产生下降沿))
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0) != RESET)
{
LED1 = 0;
sleep();
LED1 = 1;
/* 清除标志位(便于下次产生中断) */
EXTI_ClearITPendingBit(EXTI_Line0);
}
}
// 中断服务函数(触发条件:按键2按下(PE2产生下降沿))
void EXTI2_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line2) != RESET)
{
LED2 = 0;
sleep();
LED2 = 1;
/* 清除标志位(便于下次产生中断) */
EXTI_ClearITPendingBit(EXTI_Line2);
}
}
// 中断服务函数(触发条件:按键3按下(PE3产生下降沿))
void EXTI3_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line3) != RESET)
{
/* 按键3:选择HSE(8MHz) */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= RCC_CFGR_SW_HSE;
/* 清除标志位(便于下次产生中断) */
EXTI_ClearITPendingBit(EXTI_Line3);
}
}
// 中断服务函数(触发条件:按键4按下(PE4产生下降沿))
void EXTI4_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line4) != RESET)
{
LED4 = 0;
sleep();
LED4 = 1;
/* 清除标志位(便于下次产生中断) */
EXTI_ClearITPendingBit(EXTI_Line4);
}
}
二、内部中断
内部中断配置和外部中断差不多,标志性外设串口USART。
不懂原理的在看看嵌入式开发中断全解(1) 硬件:STM32F092RCT6 stm32cube 生成的HAL库开发。
#include "usart.h"
/* USER CODE BEGIN 0 */
/*printf*/
uint8_t rdata = 0;
int fputc(int ch,FILE *f)
{
uint32_t temp = ch;
HAL_UART_Transmit(&huart2,(uint8_t *)&temp,1,0xFFFF); //huart1是串口的句柄
HAL_Delay(2);
return ch;
}
/* USER CODE END 0 */
UART_HandleTypeDef huart2;
/* USART2 init function */
void MX_USART2_UART_Init(void)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
}
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(uartHandle->Instance==USART2)
{
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF1_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART2 interrupt Init */
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
/* USER CODE BEGIN USART2_MspInit 1 */
__HAL_UART_ENABLE_IT(&huart2, UART_IT_RXNE);
/* USER CODE END USART2_MspInit 1 */
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{
if(uartHandle->Instance==USART2)
{
/* USER CODE BEGIN USART2_MspDeInit 0 */
/* USER CODE END USART2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART2_CLK_DISABLE();
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
/* USART2 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART2_IRQn);
/* USER CODE BEGIN USART2_MspDeInit 1 */
/* USER CODE END USART2_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
//正在接收
if(__HAL_UART_GET_FLAG(&huart2, UART_FLAG_RXNE) != RESET)
{
//NET_UART_RECV(READ_REG(huart1.Instance->RDR));
my_uart2_callback(huart2.Instance->RDR);
__HAL_UART_CLEAR_FLAG(&huart2,UART_FLAG_RXNE);
}
//溢出-如果发生溢出需要先读SR,再读DR寄存器 则可清除不断入中断的问题
if(__HAL_UART_GET_FLAG(&huart2,UART_FLAG_ORE)== SET)
{
__HAL_UART_CLEAR_FLAG(&huart2,UART_FLAG_ORE); //读SR
//READ_REG(huart1.Instance->RDR); //读DR
}
//手动关闭自带的串口中断处理
#if 0
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
#endif
/* USER CODE END USART1_IRQn 1 */
}
void my_uart2_callback(uint8_t rdata)
{
//发送
HAL_UART_Transmit(&huart2,&rdata,1,1);//发送
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_USART2_UART_Init();
while(1)
{
printf("hello\r\n");
printf("bozhu shi dashuaibi\r\n");
HAL_UART_Transmit(&huart2,"bozhu shi dashuaibi",strlen("bozhu shi dashuaibi"),1);//和打印函数一样
HAL_Delay(500);
}
}
先在只要打开串口,用这个HAL_UART_Transmit来发送给串口,或者printf打印。这里是采取中断接受的方式,只要一接受就发送到串口显示。
void USART2_IRQHandler(void),主要是直接读取他的数据寄存器,有数据就直接调用void my_uart2_callback(uint8_t rdata),把数据发送到串口。
注意:HAL库配置的中断服务函数有时候调用不了,我会自己把stm32cube生成的中断服务函数屏蔽掉,自己再写一个。
硬件STM32F407串口中断
代码如下(示例):
main.c
#include <stm32f4xx.h>
#include "led.h"
#include "beep.h"
#include "key.h"
#include "delay.h"
#include "tim.h"
#include "usart.h"
int main()
{
// 中断优先级2组:4级抢占优先级,支持4级响应优先级
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
LED_Init(); // 初始化4个LED
BEEP_Init(); // 初始化蜂鸣器
KEY_EXTI_Init(); // 初始化按键(外部中断)
USART1_Config(115200); // 串口1配置
while(1)
{
usart1_send_str("hello\r\n");
delay_ms(1000);
}
}
usart.c
#include "usart.h"
stat
ic USART_InitTypeDef USART_InitStructure;
static NVIC_InitTypeDef NVIC_InitStructure;
static GPIO_InitTypeDef GPIO_InitStructure;
// 串口1配置(TX:PA9 RX:PA10)
void USART1_Config(uint32_t baud)
{
/* 1.打开时钟 */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
/* 2.连接复用功能引脚 */
GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
/* 3.配置GPIO */
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 4.配置串口(与通信对方必须一致)
USART_InitStructure.USART_BaudRate = baud; // 波特率:由传参决定
USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 数据位:8位
USART_InitStructure.USART_StopBits = USART_StopBits_1; // 停止位:1位
USART_InitStructure.USART_Parity = USART_Parity_No; // 无奇偶校验
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 无硬件流控
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 收发模式
USART_Init(USART1, &USART_InitStructure);
/* 5.配置中断 */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* 6.使能串口 */
USART_Cmd(USART1, ENABLE);
/* 7.使能接收中断 */
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
}
// 发送字符串
void usart1_send_str(char *s)
{
while(*s != '\0')
{
// 发送字符,并等待发送完毕
USART_SendData(USART1, *s++);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}
}
// 串口1中断服务函数(触发条件:串口1接收到数据)
void USART1_IRQHandler(void)
{
uint8_t data;
/* 接收到新数据 */
if(USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
{
data = USART_ReceiveData(USART1);
// 回发数据
USART_SendData(USART1, data);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
if(data == '1') // '1'的ASCii码值为 49
BEEP = 1;
else if(data == '0')// '0'的ASCii码值为 48
BEEP = 0;
}
}
总结
中断其实代码配置还是异曲同工,最开始学习还是要自己多写代码,多跳转去看看函数原型,看看标准库里的寄存器啥的,看看是怎么实现的,慢慢就知道怎么配置,怎么用中断了。错的请指正,反正一起探讨,我也是个菜鸟,正在努力成为“栈溢出”工程师!!。