17_外部中断实验

目录

外部中断概述

外部中断的一般配置步骤:

硬件连接图:

实验源码:

中途遇到问题printf打印中文乱码:


外部中断概述

STM32F1的每个IO口都可以作为外部中断输入。

STM32F1的中断控制器支持19个外部中断/事件请求:

线0~15:对应外部IO口的输入中断。

线16:连接到PVD输出。

线17:连接到RTC闹钟事件。

线18:连接到USB换醒事件。

每个外部中断线可以独立的配置触发方式(上升沿,下降沿或者双边沿触发),触发/屏蔽,专用的状态位。

STM32供IO使用的中断线只有16个,但是STM32F10x系列的IO口多达上百个,所以这里是用到了映射例如EXTI0能触发它的是GPIOA.0,GPIOB.0,GPIOC.0...等,EXTI1能触发它的是GPIOA.1,GPIOB.1,GPIOC....等。注意每一个时间只有一个IO口能映射到EXTIX里。

 IO口外部中断在中断向量表中之分配了7个中断向量,也就是只能使用7个中断服务函数图 缺了EXTI0

从表中可以看出,外部中断线5~9分配一个中断向量,共用一个服务函数外部中断线10~15分配一个中断向量,共用一个中断服务函数。 

中断函数列表:

EXTI0_IRQHandler

EXTI1_IRQHandler

EXTI2_IRQHandler

EXTI3_IRQHandler

EXTI4_IRQHandler

EXTI9_5_IRQHandler

EXTI15_10_IRQHandler

外部中断常用库函数

void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);

//设置IO口与中断线的映射关系

void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);

//初始中断线:触发方式等

void ITStatus EXTI_GetITStatus(uint32_ EXTI_Line);

//判断中断状态,是否发生

void EXTI_ClearITPendingBit(uint32_t EXTI_Line);

//清除中断线上的中断标志位

外部中断的一般配置步骤:

1.初始化IO口为输入

GPIO_Init();

2.开启IO口复用时钟

RCC_APB2PeriClockCmd(RCC_APB2Periph_AFIO,ENABLE);

3.设置IO口与中断线的映射关系

Void GPIO_EXTILineConfig();

4.初始化线上中断,设置触发条件等。

EXTI_Init();

5.配置中断分组(NVIC),并使能中断。

NVIC_Init();

6.编写中断服务函数。

EXTIx_IRQHandle();

7.清除中断标志位

EXTI_ClearITPendingBit();

硬件连接图:

实验源码:

实验用的是KEY0 因为一端是接地所以初始化为上拉输入(芯片内部接的是正极)

/*!
	\brief		RCC配置
	\param[in]	none
	\param[out]	none
	\retval 	none
*/
void Rcc_config(void)
{	
	
	/*使能GPIOA时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	/*使能GPIOE时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE);

	/*使能复用外设时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	
	/*使能UART1时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

}






/*!
	\brief		GPIO初始化函数
	\param[in]	none
	\param[out]	none
	\retval 	none
*/
void Gpio_Init(void)
{	
	/*GPIO结构体*/
	GPIO_InitTypeDef GPIO_InitTypeDefstruct;
	
	/*KEY2结构体配置*/
	GPIO_InitTypeDefstruct.GPIO_Mode  = GPIO_Mode_IPU; 					   //上拉输入 没按下默认是高电平
	GPIO_InitTypeDefstruct.GPIO_Pin   = GPIO_Pin_4;  //引脚选择
	/*初始化GPIOE Pin2 3 4*/ 
	GPIO_Init(GPIOE,&GPIO_InitTypeDefstruct); 
	
	
	/*UART1发送引脚配置*/
	GPIO_InitTypeDefstruct.GPIO_Mode  = GPIO_Mode_AF_PP;//推挽复用输出
	GPIO_InitTypeDefstruct.GPIO_Pin   = GPIO_Pin_9;
	GPIO_InitTypeDefstruct.GPIO_Speed =	GPIO_Speed_10MHz;
	/*写入结构体到GPIOA*/
	GPIO_Init(GPIOA,&GPIO_InitTypeDefstruct);
	
	/*UART1接收引脚配置*/
	GPIO_InitTypeDefstruct.GPIO_Mode  = GPIO_Mode_IN_FLOATING;//浮空输入
	GPIO_InitTypeDefstruct.GPIO_Pin   = GPIO_Pin_10;
	GPIO_InitTypeDefstruct.GPIO_Speed =	GPIO_Speed_10MHz;
	/*写入结构体到GPIOA*/	
	GPIO_Init(GPIOA,&GPIO_InitTypeDefstruct);
	
		
}




/*!
	\brief		UART1初始化
	\param[in]	none
	\param[out]	none
	\retval 	none
*/

void Uart1_Init(u32 bound)
{
	/*UART结构体*/
	USART_InitTypeDef USART_InitTypeDefstruct;
	/*NVIC结构体*/
	NVIC_InitTypeDef NVIC_InitTypeDefstruct;
	
	/*UART结构体配置*/
	USART_InitTypeDefstruct.USART_BaudRate = bound; //波特率
	USART_InitTypeDefstruct.USART_HardwareFlowControl =USART_HardwareFlowControl_None; //不使用硬件流
	USART_InitTypeDefstruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//发送接收使能
	USART_InitTypeDefstruct.USART_Parity = USART_Parity_No; //不使用奇偶校验
	USART_InitTypeDefstruct.USART_StopBits = USART_StopBits_1; //1个停止位
	USART_InitTypeDefstruct.USART_WordLength = USART_WordLength_8b; //8个数据位
	/*写入USART1*/
	USART_Init(USART1,&USART_InitTypeDefstruct);
	
	/*使能串口1*/
	USART_Cmd(USART1,ENABLE);

	/*中断配置*/
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //UART1接收缓冲区非空中断,接收中断
	
	NVIC_InitTypeDefstruct.NVIC_IRQChannel=  USART1_IRQn; //USART1中断通道
	NVIC_InitTypeDefstruct.NVIC_IRQChannelCmd = ENABLE;  //使能USART1中断
	NVIC_InitTypeDefstruct.NVIC_IRQChannelPreemptionPriority = 2; //抢占优先级
	NVIC_InitTypeDefstruct.NVIC_IRQChannelSubPriority = 1;//子优先级
	
	/*写入NVIC中*/
	NVIC_Init(&NVIC_InitTypeDefstruct);
}





/*!
	\brief		UART1中断服务函数
	\param[in]	none
	\param[out]	none
	\retval 	none
*/

void USART1_IRQHandler(void)
{
	uint8_t Receive;
	/*接收数据*/
	Receive = USART_ReceiveData(USART1);

	printf("UART1中断,值为:%x\r\n",Receive);


}
	


/*!
	\brief		EXTI初始化
	\param[in]	none
	\param[out]	none
	\retval 	none
*/
void EXTIX_Init(void)
{	
	/*EXTI结构体*/
	EXTI_InitTypeDef EXTI_InitStuct;
	/*NVIC结构体*/
	NVIC_InitTypeDef NVIC_InitTypeDefstruct;
	/*映射IO口到EXTI线上*/
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);
	
	
	/*触发方式设置*/
	EXTI_InitStuct.EXTI_Line = EXTI_Line4;//EXTI4
	EXTI_InitStuct.EXTI_LineCmd = ENABLE; //使能
	EXTI_InitStuct.EXTI_Mode = EXTI_Mode_Interrupt;  //中断模式
	EXTI_InitStuct.EXTI_Trigger = EXTI_Trigger_Falling; //下降验触发 按键按下是低电平
	/*触发方式写入*/
	EXTI_Init(&EXTI_InitStuct);
	
	
	/*中断配置*/
	NVIC_InitTypeDefstruct.NVIC_IRQChannel=  EXTI4_IRQn; //EXTI4中断通道
	NVIC_InitTypeDefstruct.NVIC_IRQChannelCmd = ENABLE;  //使能EXTI4中断
	NVIC_InitTypeDefstruct.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级
	NVIC_InitTypeDefstruct.NVIC_IRQChannelSubPriority = 1;//子优先级
	
	/*写入NVIC中*/
	NVIC_Init(&NVIC_InitTypeDefstruct);

}





/*!
\brief		EXTI4中断服务函数
	\param[in]	none
	\param[out]	none
	\retval 	none
*/

void EXTI4_IRQHandler(void)
{
	/*消抖处理*/
	delay_ms(10);
	
	/*读取GPIOE.4电平低是按下*/
	if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4) == 0)
	{
		printf("外部中断触发,KEY0按下\r\n");//提示语句
		
	}

	/*清除EXTI4中断标志位*/
	EXTI_ClearITPendingBit(EXTI_Line4);
}





 int main(void)
 {	
     
	 /*配置系统中断分组为2位抢占2位响应*/
	 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	 /*Rcc初始化*/	 
	 Rcc_config();
	 /*GPIO初始化*/
	 Gpio_Init();
	 /*UART1初始化*/
	 Uart1_Init(9600);
	 /*EXTI初始化*/
	 EXTIX_Init();

	/*死循环*/ 
	 while(1){
		 
	 };
	
 }

 中途遇到问题printf打印中文乱码:

1.排除是否波特率太高

2.查看用到printf.c文件是否使用的是UTF-8编码,使用UTF-8编码会出现中文乱码解决办法如下博客

USART串口printf重定向中文乱码_洛尘~~的博客-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值