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

[复制链接]
4976|21
 楼主| wangruixu1121 发表于 2012-7-18 22:40 | 显示全部楼层 |阅读模式
关于外部中断的 ,我把程序烧写到片子上后,中断的确没有反应,可我设置了下硬件仿真,如下图所示,片子自动复位,并且外部中断起作用了。我拔下JLINK之后,程序运行还是正常。难道设置硬件仿真那么重要吗??
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);      
  }
}
chenhuizai210 发表于 2012-7-18 22:59 | 显示全部楼层
我记得看一个开发板例程的时候,在用到外部输入中断的时候,都是先禁用JTAG,当时也不知道是干什么的。现在看来,是有一定原因的啊。。
 楼主| wangruixu1121 发表于 2012-7-18 23:03 | 显示全部楼层
5# chenhuizai210
你用的原子的板子吧???
ccontrol 发表于 2012-7-18 23:08 | 显示全部楼层
我记得看一个开发板例程的时候,在用到外部输入中断的时候,都是先禁用JTAG,当时也不知道是干什么的。现在看来,是有一定原因的啊。。
chenhuizai210 发表于 2012-7-18 22:59

如果你的中断输入脚不和JTAG脚共用,禁用个屁啊。
 楼主| wangruixu1121 发表于 2012-7-18 23:23 | 显示全部楼层
自己顶一下
 楼主| wangruixu1121 发表于 2012-7-18 23:23 | 显示全部楼层
自己顶一下
 楼主| wangruixu1121 发表于 2012-7-19 10:56 | 显示全部楼层
没有遇到这种情况的吗?
 楼主| wangruixu1121 发表于 2012-7-19 11:20 | 显示全部楼层
硬件仿真难道是一把开启外部中断的钥匙?
香水城 发表于 2012-7-19 12:06 | 显示全部楼层
什么叫硬件仿真

LZ确定第一次烧录FLASH但是没有仿真的操作正确执行了吗?
 楼主| wangruixu1121 发表于 2012-7-19 12:21 | 显示全部楼层
14# 香水城
如下图所示 硬件仿真 仿真设置之前 确定外部中断没有执行
SRAM.png
香水城 发表于 2012-7-19 13:42 | 显示全部楼层
不明白,你标出来的不是默认设置吗?
 楼主| wangruixu1121 发表于 2012-7-19 14:28 | 显示全部楼层
16# 香水城
我标出来的是设置之后的
香水城 发表于 2012-7-19 15:31 | 显示全部楼层
不好意思,我不太用KEIL,但是不存在代码需要先仿真再能运行的情况

我觉得有两种可能

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

2, 你的代码有部分的变量初始化不正常。这样,在光烧录的情况下,代码不能正常运行,而在调试情况下,可能调试器正好帮你正确初始化了代码。
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);
同一个中断请求,怎么能有两个优先级呢?看看这里是不是问题所在。
 楼主| wangruixu1121 发表于 2012-7-19 17:20 | 显示全部楼层
18# 香水城
谢谢城主解惑
 楼主| wangruixu1121 发表于 2012-7-19 17:21 | 显示全部楼层
19# zh5202
这位仁兄说的有理,我再检查检查
 楼主| 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
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

76

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部