打印

关于外部中断的奇怪问题,非常奇怪

[复制链接]
3452|21
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
关于外部中断的 ,我把程序烧写到片子上后,中断的确没有反应,可我设置了下硬件仿真,如下图所示,片子自动复位,并且外部中断起作用了。我拔下JLINK之后,程序运行还是正常。难道设置硬件仿真那么重要吗??

SRAM.png (33.47 KB )

SRAM.png
沙发
Harvard| | 2012-7-18 22:45 | 只看该作者
不知道要说明什么

使用特权

评论回复
板凳
wangruixu1121|  楼主 | 2012-7-18 22:51 | 只看该作者
2# Harvard
中断程序烧写进片子之后,中断无反应,但是经过硬件仿真设置之后,中断就正常了

使用特权

评论回复
地板
wangruixu1121|  楼主 | 2012-7-18 22:53 | 只看该作者
程序如下所示:
/*---------INCLUDE------------*/
#include "stm32f10x.h"
#include <stdio.h>

/*--------LED相关定义------------*/
#define  RCC_LED            RCC_APB2Periph_GPIOE
#define  LED_PORT           GPIOE
#define  DS1                GPIO_Pin_3
#define  DS2                GPIO_Pin_4
#define  DS3                GPIO_Pin_5
#define  DS4                GPIO_Pin_6
#define  LED_ALL                        DS1|DS2|DS3|DS4
/*--------KEY相关定义------------*/
#define  RCC_KEY            RCC_APB2Periph_GPIOE
#define  KEY_PORT           GPIOE

#define  KEY1               GPIO_Pin_8
#define  KEY1_EXTI_LINE        EXTI_Line8
#define  KEY1_PORT_SOURCE               GPIO_PortSourceGPIOE
#define  KEY1_Pin_SOURCE                GPIO_PinSource8
#define  KEY1_IRQn                      EXTI9_5_IRQn

#define  KEY2               GPIO_Pin_9
#define  KEY2_EXTI_LINE        EXTI_Line9
#define  KEY2_PORT_SOURCE               GPIO_PortSourceGPIOE
#define  KEY2_Pin_SOURCE                GPIO_PinSource9
#define  KEY2_IRQn                      EXTI9_5_IRQn

#define  KEY3               GPIO_Pin_10
#define  KEY3_EXTI_LINE        EXTI_Line10
#define  KEY3_PORT_SOURCE               GPIO_PortSourceGPIOE
#define  KEY3_Pin_SOURCE                GPIO_PinSource10
#define  KEY3_IRQn                      EXTI15_10_IRQn
/*-----------Private variables-----------*/
GPIO_InitTypeDef   GPIO_InitStructure;
EXTI_InitTypeDef   EXTI_InitStructure;
NVIC_InitTypeDef   NVIC_InitStructure;
/*-------------定时器相关定义-----------*/
static u8    fac_us=0;
static u16   fac_ms=0;
/*-----------函数声明-------------*/
void  delay_init(u8 SYSCLK);
void  delay_ms(u16 nms);
void delay_us(u32 nus);
void Turn_on_LED_ALL(void);
void Turn_off_LED_ALL(void);
void Led_Turn_on_1(void);
void Led_Turn_on_2(void);
void Led_Turn_on_3(void);
void Led_Turn_on_4(void);
/*---------------初始化函数----------------*/
void LED_Init(void)        //初始化LED
{
  RCC_APB2PeriphClockCmd(RCC_LED,ENABLE);
  GPIO_InitStructure.GPIO_Pin = DS1|DS2|DS3|DS4;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(LED_PORT,&GPIO_InitStructure);
}

void KEY_Init(void)
{
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE);
  GPIO_InitStructure.GPIO_Pin = KEY1|KEY2|KEY3;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(KEY_PORT, &GPIO_InitStructure);
}

void KEY_EXTI_Init(void)
{
  EXTI_ClearITPendingBit(EXTI_Line8);
  EXTI_ClearITPendingBit(EXTI_Line9);
  EXTI_ClearITPendingBit(EXTI_Line10);
  GPIO_EXTILineConfig(KEY1_PORT_SOURCE, KEY1_Pin_SOURCE);
  EXTI_InitStructure.EXTI_Line = KEY1_EXTI_LINE;
     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;  
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
     EXTI_Init(&EXTI_InitStructure);

GPIO_EXTILineConfig(KEY2_PORT_SOURCE, KEY2_Pin_SOURCE);
  EXTI_InitStructure.EXTI_Line = KEY2_EXTI_LINE;
     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;  
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
     EXTI_Init(&EXTI_InitStructure);

GPIO_EXTILineConfig(KEY3_PORT_SOURCE, KEY3_Pin_SOURCE);
  EXTI_InitStructure.EXTI_Line = KEY3_EXTI_LINE;
     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;  
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
     EXTI_Init(&EXTI_InitStructure);
}

void NVIC_Config(void)
{
  /* Set the Vector Table base address at 0x08000000 */
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0000);
  
  /* Configure the Priority Group to 2 bits */
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  
  
  /* Enable the EXTI Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = KEY1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  
  NVIC_InitStructure.NVIC_IRQChannel = KEY2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  
  NVIC_InitStructure.NVIC_IRQChannel = KEY3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}
/*------------主函数---------------*/
int main(void)
{
  LED_Init();
  delay_init(72);
  Turn_off_LED_ALL();/*关闭所有的LED指示灯*/
  delay_ms(500);
  Led_Turn_on_1();
  delay_ms(500);
  Turn_off_LED_ALL();
  delay_ms(500);
  Led_Turn_on_1();
  delay_ms(500);
  Turn_off_LED_ALL();
  delay_ms(500);
  Led_Turn_on_1();
  delay_ms(500);
  Turn_off_LED_ALL();
  delay_ms(500);

KEY_Init();
  KEY_EXTI_Init();
  NVIC_Config();
  while(1)    //等待中断
  {
  }
}
/*--------------函数配置--------------*/
void Turn_on_LED_ALL(void)    //打开所有灯
{
  GPIO_SetBits(LED_PORT,LED_ALL);
}

void Turn_off_LED_ALL(void)   //关闭所有灯
{
  GPIO_ResetBits(LED_PORT,LED_ALL);  
}

void Led_Turn_on_1(void)    //打开灯1
{
  /* Turn On LED1 */
     GPIO_SetBits(LED_PORT, DS1);
}

void Led_Turn_on_2(void)    //打开灯2
{
  /* Turn On LED2 */
     GPIO_SetBits(LED_PORT, DS2);
}

void Led_Turn_on_3(void)    //打开灯3
{
  /* Turn On LED3 */
     GPIO_SetBits(LED_PORT, DS3);
}

void Led_Turn_on_4(void)     //打开灯4
{
  /* Turn On LED3 */
     GPIO_SetBits(LED_PORT, DS4);
}
/*-------------延时函数----------------*/
void delay_init(u8 SYSCLK)
{
  SysTick->CTRL&=0xfffffffb;//bit2清空,选择外部时钟  HCLK/8
  fac_us=SYSCLK/8;      
fac_ms=(u16)fac_us*1000;
}
//延迟毫秒函数
void delay_ms(u16 nms)
{         
u32 temp;     
SysTick->LOAD=(u32)nms*fac_ms;//时间加载(SysTick->LOAD为24bit)
  SysTick->VAL =0x00;           //清空计数器
  SysTick->CTRL=0x01 ;          //开始倒数  
do
  {
   temp=SysTick->CTRL;
  }
  while(temp&0x01&&!(temp&(1<<16)));//等待时间到达   
SysTick->CTRL=0x00;       //关闭计数器
  SysTick->VAL =0X00;       //清空计数器        
}
//延迟微秒函数
void delay_us(u32 nus)
{  
  u32 temp;      
SysTick->LOAD=nus*fac_us; //时间加载      
SysTick->VAL=0x00;        //清空计数器
  SysTick->CTRL=0x01 ;      //开始倒数   
do
  {
   temp=SysTick->CTRL;
  }
  while(temp&0x01&&!(temp&(1<<16)));//等待时间到达   
SysTick->CTRL=0x00;       //关闭计数器
  SysTick->VAL =0X00;       //清空计数器  
}



关于中断响应函数


void EXTI9_5_IRQHandler(void)     //KEY1 KEY2
{
   if(EXTI_GetITStatus(EXTI_Line8) != RESET)
   {
    GPIO_SetBits(GPIOE, GPIO_Pin_4);        

    EXTI_ClearITPendingBit(EXTI_Line8);      
  }
   else
   if(EXTI_GetITStatus(EXTI_Line9) != RESET)
   {
     GPIO_SetBits(GPIOE, GPIO_Pin_5);         

    EXTI_ClearITPendingBit(EXTI_Line9);        
  }
}

void EXTI15_10_IRQHandler(void)      //KEY3
{
   if(EXTI_GetITStatus(EXTI_Line10) != RESET)
   {
     GPIO_SetBits(GPIOE, GPIO_Pin_6);      

    EXTI_ClearITPendingBit(EXTI_Line10);      
  }
}

使用特权

评论回复
5
chenhuizai210| | 2012-7-18 22:59 | 只看该作者
我记得看一个开发板例程的时候,在用到外部输入中断的时候,都是先禁用JTAG,当时也不知道是干什么的。现在看来,是有一定原因的啊。。

使用特权

评论回复
6
wangruixu1121|  楼主 | 2012-7-18 23:03 | 只看该作者
5# chenhuizai210
你用的原子的板子吧???

使用特权

评论回复
7
ccontrol| | 2012-7-18 23:08 | 只看该作者
我记得看一个开发板例程的时候,在用到外部输入中断的时候,都是先禁用JTAG,当时也不知道是干什么的。现在看来,是有一定原因的啊。。
chenhuizai210 发表于 2012-7-18 22:59

如果你的中断输入脚不和JTAG脚共用,禁用个屁啊。

使用特权

评论回复
8
wangruixu1121|  楼主 | 2012-7-18 23:23 | 只看该作者
自己顶一下

使用特权

评论回复
9
wangruixu1121|  楼主 | 2012-7-18 23:23 | 只看该作者
自己顶一下

使用特权

评论回复
10
wangruixu1121|  楼主 | 2012-7-19 10:56 | 只看该作者
没有遇到这种情况的吗?

使用特权

评论回复
11
wangruixu1121|  楼主 | 2012-7-19 11:20 | 只看该作者
硬件仿真难道是一把开启外部中断的钥匙?

使用特权

评论回复
12
香水城| | 2012-7-19 12:06 | 只看该作者
什么叫硬件仿真

LZ确定第一次烧录FLASH但是没有仿真的操作正确执行了吗?

使用特权

评论回复
13
wangruixu1121|  楼主 | 2012-7-19 12:21 | 只看该作者
14# 香水城
如下图所示 硬件仿真 仿真设置之前 确定外部中断没有执行

SRAM.png (33.47 KB )

SRAM.png

使用特权

评论回复
14
香水城| | 2012-7-19 13:42 | 只看该作者
不明白,你标出来的不是默认设置吗?

使用特权

评论回复
15
wangruixu1121|  楼主 | 2012-7-19 14:28 | 只看该作者
16# 香水城
我标出来的是设置之后的

使用特权

评论回复
16
香水城| | 2012-7-19 15:31 | 只看该作者
不好意思,我不太用KEIL,但是不存在代码需要先仿真再能运行的情况

我觉得有两种可能

1, 你的第一次烧写并没有成功,你的代码是仿真的时候才真正烧入的。KEIL的DOWNLOAD和DEBUG用的好像是2个配置下的FLASH烧写算法。

2, 你的代码有部分的变量初始化不正常。这样,在光烧录的情况下,代码不能正常运行,而在调试情况下,可能调试器正好帮你正确初始化了代码。

使用特权

评论回复
17
zh5202| | 2012-7-19 16:08 | 只看该作者
LZ,你的NVIC初始化函数中,有问题,你的宏定义:
#define  KEY1_IRQn                      EXTI9_5_IRQn
#define  KEY2_IRQn                      EXTI9_5_IRQn
而你的中断优先级配置为:
NVIC_InitStructure.NVIC_IRQChannel = KEY1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
  
  NVIC_InitStructure.NVIC_IRQChannel = KEY2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
同一个中断请求,怎么能有两个优先级呢?看看这里是不是问题所在。

使用特权

评论回复
18
wangruixu1121|  楼主 | 2012-7-19 17:20 | 只看该作者
18# 香水城
谢谢城主解惑

使用特权

评论回复
19
wangruixu1121|  楼主 | 2012-7-19 17:21 | 只看该作者
19# zh5202
这位仁兄说的有理,我再检查检查

使用特权

评论回复
20
wangruixu1121|  楼主 | 2012-7-19 17:37 | 只看该作者
我现在模模糊糊知道点所以然了,但还不能确定,还望各位不吝赐教。
因为我使用了外部中断,而外部中断都在中断向量表中,中断向量表的起始地址需要设置一下,也就是:
#ifdef  VECT_TAB_RAM  

    /* Set the Vector Table base location at 0x20000000 */

   NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);

#else  /* VECT_TAB_FLASH  */

    /* Set the Vector Table base location at 0x08000000 */

   NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);   

  #endif
也就是这个函数。经过DEBUG设置后,如下图所示,重新映射了下起始地址,所以才能运行中断程序。表达不够清楚,不好意思








  #endif

SRAM.png (45.79 KB )

SRAM.png

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

76

帖子

1

粉丝