文章目录

  • 一、外部中断
  • 硬件: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) ,是没有传参的。

android嵌入式开发板断电时应用程序如何销毁服务 嵌入式开发 中断_c语言


我们右键进来这个函数声明,发现只需要配置这个函数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)

android嵌入式开发板断电时应用程序如何销毁服务 嵌入式开发 中断_arm_02


所以中断简要说就两个步骤,初始化和中断服务函数,往下看几个例程加深印象,建议自己也拿个开发板写来玩一玩,其中还得考虑到中断服务函数内要清除中断标志位。

硬件:STM32F407

标准库编辑代码

不管怎么说,做嵌入式得看的懂原理图,从原理图中知道要怎么配置。

android嵌入式开发板断电时应用程序如何销毁服务 嵌入式开发 中断_stm32_03


当用标准库初始化配置得时候不会配置或者不想自己配置,打开**《库函数手册》**,要这个库函数手册评论区说一下,我直接发给你吧,直接复制黏贴代码进自己得工程。

android嵌入式开发板断电时应用程序如何销毁服务 嵌入式开发 中断_arm_04


android嵌入式开发板断电时应用程序如何销毁服务 嵌入式开发 中断_c语言_05

android嵌入式开发板断电时应用程序如何销毁服务 嵌入式开发 中断_stm32_06

标准库示例代码:

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生成的中断服务函数屏蔽掉,自己再写一个。

android嵌入式开发板断电时应用程序如何销毁服务 嵌入式开发 中断_c语言_07

android嵌入式开发板断电时应用程序如何销毁服务 嵌入式开发 中断_stm32_08

硬件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;
	}
}

总结

中断其实代码配置还是异曲同工,最开始学习还是要自己多写代码,多跳转去看看函数原型,看看标准库里的寄存器啥的,看看是怎么实现的,慢慢就知道怎么配置,怎么用中断了。错的请指正,反正一起探讨,我也是个菜鸟,正在努力成为“栈溢出”工程师!!。