OpenEdv-开源电子网

 找回密码
 立即注册
正点原子新作:阿波罗STM32F429&探索者STM32F4开发板&飞音1(FY1) HiFi USB声卡面市啦,赶快来下载资料哦。

查看: 79|回复: 11

关于外部中断的寄存器配置

[复制链接]

  离线 

1

主题

10

帖子

0

精华

新手上路

Rank: 1

积分
27
金钱
27
注册时间
2017-1-11
在线时间
3 小时
发表于 6 天前 | 显示全部楼层 |阅读模式
3金钱
大神好,我用的板子是原子的stm32f103rc,软件是MDK5, 我在用库函数配置外部中断的时候后下载到板子里,可以进入中断;但是用寄存器配置外部中断的时候,发现进入不到中断。我的配置过程如下:(基本上都是基于资料的例程稍作修改)
一、正常进入中断的库函数代码:

1. 打开示例程序库函数版本,实验4外部中断实验
2.屏蔽掉delay_init,因为目前还不需要systick.
3.屏蔽延时函数,因为systick没配置,所以也屏蔽相关函数,去不去抖的先放一边。
主程序如下:
[C] 纯文本查看 复制代码
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "key.h"
#include "usart.h"
#include "exti.h" 
 int main(void)
 {	
 
	//delay_init();	    	 //延时函数初始化	
	NVIC_Configuration();// 设置中断优先级分组  
	//uart_init(9600);	 //串口初始化为9600
	LED_Init();		  	 //初始化与LED连接的硬件接口 
 	EXTIX_Init();		//外部中断初始化
  LED0=0;				//点亮LED
	while(1);
	/*{	    
		printf("OK\n");	
		delay_ms(1000);	  
	}*/
}


中断服务例程如下:
[C] 纯文本查看 复制代码
 void EXTI9_5_IRQHandler(void)
{			
	//delay_ms(10);   //消抖			 
	if(KEY0==0)	{
		LED0=!LED0;
	}
 	 EXTI_ClearITPendingBit(EXTI_Line5);    //清除LINE5上的中断标志位  
}




二、不能进入中断的寄存器版代码:
1. 打开示例程序寄存器版本,实验4外部中断实验
2.屏蔽掉Stm32_Clock_Init函数
3.屏蔽掉delay_init(), uart_init(),以及和systick相关的代码。
主程序代码如下:
[C] 纯文本查看 复制代码
#include "sys.h"
#include "usart.h"		
#include "delay.h"	
#include "led.h"  
#include "exti.h" 
//ALIENTEK Mini STM32开发板范例代码4
//外部中断实验   
//技术支持:[url]www.openedv.com[/url]
//广州市星翼电子科技有限公司

int main(void)
{			
	//Stm32_Clock_Init(9);//系统时钟设置
	//delay_init(72);	    //延时初始化
	//uart_init(72,9600); //串口初始化 
	LED_Init();		  	//初始化与LED连接的硬件接口
	EXTI_Init();		//外部中断初始化
	LED0=0;				//点亮LED
	while(1);
	/*{	    
		printf("OK\r\n");	
		delay_ms(1000);	  
	} */
}


中断处理函数如下:
[C] 纯文本查看 复制代码
//外部中断15~10服务程序
void EXTI15_10_IRQHandler(void)
{			
	//delay_ms(10);   //消抖			 
    if(KEY1==0)		//按键1
	{
		LED0=0;
		LED1 = 1;
	}
 	EXTI->PR=1<<15; //清除LINE15上的中断标志位  
}


通过软件仿真查看寄存器配置都一样,请教大神为什么寄存器版进入不了外部中断。


最佳答案

查看完整内容[请看2#楼]

因为你屏蔽了delay_init,导致delay工作不正常,在中断服务函数里面,有用到delay,直接就卡死。
回复

使用道具 举报

  离线 

430

主题

8万

帖子

30

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
98247
金钱
98247
注册时间
2010-12-1
在线时间
499 小时
发表于 6 天前 | 显示全部楼层
因为你屏蔽了delay_init,导致delay工作不正常,在中断服务函数里面,有用到delay,直接就卡死。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
微信公众平台:正点原子
回复

使用道具 举报

  离线 

1

主题

10

帖子

0

精华

新手上路

Rank: 1

积分
27
金钱
27
注册时间
2017-1-11
在线时间
3 小时
 楼主| 发表于 5 天前 | 显示全部楼层
顶一下,大神们救救我啊,不能让新手寒心啊!
回复

使用道具 举报

  离线 

8

主题

68

帖子

0

精华

初级会员

Rank: 2

积分
126
金钱
126
注册时间
2016-12-12
在线时间
35 小时
发表于 5 天前 | 显示全部楼层
NVIC_Configuration();// 设置中断优先级分组  

    EXTIX_Init();       //外部中断初始化

这两个函数的实现是什么样的?
回复

使用道具 举报

  离线 

1

主题

10

帖子

0

精华

新手上路

Rank: 1

积分
27
金钱
27
注册时间
2017-1-11
在线时间
3 小时
 楼主| 发表于 5 天前 | 显示全部楼层
不死鸟 发表于 2017-1-12 10:35
NVIC_Configuration();// 设置中断优先级分组  

    EXTIX_Init();       //外部中断初始化

库函数的实现是如下:
[C] 纯文本查看 复制代码
void NVIC_Configuration(void)
{

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	//设置NVIC中断分组2:2位抢占优先级,2位响应优先级

}
//外部中断初始化函数
void EXTIX_Init(void)
{
 
 	  EXTI_InitTypeDef EXTI_InitStructure;
 	  NVIC_InitTypeDef NVIC_InitStructure;

  	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//外部中断,需要使能AFIO时钟

	  KEY_Init();//初始化按键对应io模式

    //GPIOC.5 中断线以及中断初始化配置
  	GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);

  	EXTI_InitStructure.EXTI_Line=EXTI_Line5;
  	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
  	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发
  	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  	EXTI_Init(&EXTI_InitStructure);	 	//根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

    //GPIOA.15	  中断线以及中断初始化配置
  	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource15);

  	EXTI_InitStructure.EXTI_Line=EXTI_Line15;
  	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
  	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  	EXTI_Init(&EXTI_InitStructure);	  	//根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

    //GPIOA.0	  中断线以及中断初始化配置
  	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_Rising;
  	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  	EXTI_Init(&EXTI_InitStructure);		//根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器


 
  	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;			//使能按键所在的外部中断通道
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	//抢占优先级2 
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;					//子优先级1
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								//使能外部中断通道
  	NVIC_Init(&NVIC_InitStructure);  	  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
		
		NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;			//使能按键所在的外部中断通道
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	//抢占优先级2, 
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;					//子优先级1
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								//使能外部中断通道
  	NVIC_Init(&NVIC_InitStructure); 
 
 
   	NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;			//使能按键所在的外部中断通道
  	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;	//抢占优先级2, 
  	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;					//子优先级1
  	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;								//使能外部中断通道
  	NVIC_Init(&NVIC_InitStructure); 
 
}


寄存器的函数实现是:
[C] 纯文本查看 复制代码
//外部中断初始化程序
//初始化PA0,PC5,PA15为中断输入.
void EXTI_Init(void)
{
	KEY_Init();
	Ex_NVIC_Config(GPIO_A,0,RTIR); 		//上升沿触发
	Ex_NVIC_Config(GPIO_C,5,FTIR);		//下降沿触发
	Ex_NVIC_Config(GPIO_A,15,FTIR);		//下降沿触发

	MY_NVIC_Init(2,2,EXTI0_IRQn,2);    	//抢占2,子优先级2,组2
	MY_NVIC_Init(2,1,EXTI9_5_IRQn,2);  	//抢占2,子优先级1,组2
	MY_NVIC_Init(2,0,EXTI15_10_IRQn,2);	//抢占2,子优先级0,组2	   
}

//外部中断配置函数
//只针对GPIOA~G;不包括PVD,RTC和USB唤醒这三个
//参数:
//GPIOx:0~6,代表GPIOA~G
//BITx:需要使能的位;
//TRIM:触发模式,1,下升沿;2,上降沿;3,任意电平触发
//该函数一次只能配置1个IO口,多个IO口,需多次调用
//该函数会自动开启对应中断,以及屏蔽线   	    
void Ex_NVIC_Config(u8 GPIOx,u8 BITx,u8 TRIM) 
{
	u8 EXTADDR;
	u8 EXTOFFSET;
	EXTADDR=BITx/4;//得到中断寄存器组的编号
	EXTOFFSET=(BITx%4)*4; 
	RCC->APB2ENR|=0x01;//使能io复用时钟			 
	AFIO->EXTICR[EXTADDR]&=~(0x000F<<EXTOFFSET);//清除原来设置!!!
	AFIO->EXTICR[EXTADDR]|=GPIOx<<EXTOFFSET;//EXTI.BITx映射到GPIOx.BITx 
	//自动设置
	EXTI->IMR|=1<<BITx;//  开启line BITx上的中断
	//EXTI->EMR|=1<<BITx;//不屏蔽line BITx上的事件 (如果不屏蔽这句,在硬件上是可以的,但是在软件仿真的时候无法进入中断!)
 	if(TRIM&0x01)EXTI->FTSR|=1<<BITx;//line BITx上事件下降沿触发
	if(TRIM&0x02)EXTI->RTSR|=1<<BITx;//line BITx上事件上升降沿触发
} 	  

//设置NVIC分组
//NVIC_Group:NVIC分组 0~4 总共5组 		   
void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group)	 
{ 
	u32 temp,temp1;	  
	temp1=(~NVIC_Group)&0x07;//取后三位
	temp1<<=8;
	temp=SCB->AIRCR;  //读取先前的设置
	temp&=0X0000F8FF; //清空先前分组
	temp|=0X05FA0000; //写入钥匙
	temp|=temp1;	   
	SCB->AIRCR=temp;  //设置分组	    	  				   
}
//设置NVIC 
//NVIC_PreemptionPriority:抢占优先级
//NVIC_SubPriority       :响应优先级
//NVIC_Channel           :中断编号
//NVIC_Group             :中断分组 0~4
//注意优先级不能超过设定的组的范围!否则会有意想不到的错误
//组划分:
//组0:0位抢占优先级,4位响应优先级
//组1:1位抢占优先级,3位响应优先级
//组2:2位抢占优先级,2位响应优先级
//组3:3位抢占优先级,1位响应优先级
//组4:4位抢占优先级,0位响应优先级
//NVIC_SubPriority和NVIC_PreemptionPriority的原则是,数值越小,越优先	   
void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group)	 
{ 
	u32 temp;	
	MY_NVIC_PriorityGroupConfig(NVIC_Group);//设置分组
	temp=NVIC_PreemptionPriority<<(4-NVIC_Group);	  
	temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);
	temp&=0xf;//取低四位  
	NVIC->ISER[NVIC_Channel/32]|=(1<<NVIC_Channel%32);//使能中断位(要清除的话,相反操作就OK) 
	NVIC->IP[NVIC_Channel]|=temp<<4;//设置响应优先级和抢断优先级   	    	  				   
} 


求大神指点
回复

使用道具 举报

  离线 

1

主题

10

帖子

0

精华

新手上路

Rank: 1

积分
27
金钱
27
注册时间
2017-1-11
在线时间
3 小时
 楼主| 发表于 5 天前 | 显示全部楼层
顶起来啊大神们帮帮忙
回复

使用道具 举报

  离线 

1

主题

10

帖子

0

精华

新手上路

Rank: 1

积分
27
金钱
27
注册时间
2017-1-11
在线时间
3 小时
 楼主| 发表于 3 天前 | 显示全部楼层
我中断函数里把所有delay相关的都屏蔽啊
回复

使用道具 举报

  离线 

1

主题

10

帖子

0

精华

新手上路

Rank: 1

积分
27
金钱
27
注册时间
2017-1-11
在线时间
3 小时
 楼主| 发表于 昨天 09:16 | 显示全部楼层
正点原子 发表于 2017-1-11 23:43
因为你屏蔽了delay_init,导致delay工作不正常,在中断服务函数里面,有用到delay,直接就卡死。

原子哥,我的问题没解决呢啊,为啥设置为已解决啊。“我中断函数里把所有delay相关的都屏蔽了”
回复

使用道具 举报

  离线 

101

主题

6628

帖子

12

精华

资深版主

Rank: 8Rank: 8

积分
9385
金钱
9385
注册时间
2013-9-10
在线时间
162 小时
发表于 昨天 17:19 | 显示全部楼层
确定所以延时函数都注释掉了?
回复

使用道具 举报

  离线 

1

主题

10

帖子

0

精华

新手上路

Rank: 1

积分
27
金钱
27
注册时间
2017-1-11
在线时间
3 小时
 楼主| 发表于 昨天 20:04 | 显示全部楼层
八度空间 发表于 2017-1-16 17:19
确定所以延时函数都注释掉了?

确定,我花了半小时写的这个帖子,尽可能的把涉及到的代码都粘上去了。楼下发个附件,您可以确认下。
回复

使用道具 举报

  离线 

1

主题

10

帖子

0

精华

新手上路

Rank: 1

积分
27
金钱
27
注册时间
2017-1-11
在线时间
3 小时
 楼主| 发表于 昨天 20:13 | 显示全部楼层
代码见附件,您确认下
回复

使用道具 举报

  离线 

1

主题

10

帖子

0

精华

新手上路

Rank: 1

积分
27
金钱
27
注册时间
2017-1-11
在线时间
3 小时
 楼主| 发表于 昨天 20:14 | 显示全部楼层
不好意思,楼上没上传成功,再传一次

ALIENTEK MiniSTM32 实验4 外部中断实验.rar

771.4 KB, 下载次数: 2

回复

使用道具 举报


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


QQ|联系我们|手机版|官方淘宝店|新浪微博|微信公众平台|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2017-1-17 08:45

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表