OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9170|回复: 8

原子兄~~请教外部中断....help~~

[复制链接]

6

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
93
金钱
93
注册时间
2012-9-11
在线时间
6 小时
发表于 2012-9-27 23:39:16 | 显示全部楼层 |阅读模式
感觉看明白了外部IO中断,但是就是不能进中断服务程序...
我的设置步骤如下:    
    1、设置中断向量表位置 NVIC_SetVectorTable()
    2、开启AFIO时钟;
    3、开启IO口时钟,并配置为输入上拉;
    4、设置AFIO中EXTICR中的 EXTIx[3:0] ;即映射到GPIO口?
     5、开启中断屏蔽寄存器中的相关位 EXTI-〉IMR
    6、设置上升沿触发
    7、中断初始化
            7.1、使能中断位
             7.2、设置优先级分组,和优先级

我的程序如下:

void NVIC_SetVectorTable(uint32 NVIC_VectTab,uint32 Offset)
{
SCB->VTOR = NVIC_VectTab|(Offset & (uint32)0x1FFFFF80);//设置NVIC的向量表偏移寄存器
//用于标识向量表是在CODE区还是在RAM区
}

void NVIC_PriorityGroupConfig(uint8 NVIC_Group)
{
uint32 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的原则是,数值越小,越优先
//CHECK OK
//100329
void NVIC_Init(uint8 NVIC_PreemptionPriority,uint8 NVIC_SubPriority,uint8 NVIC_Channel,uint8 NVIC_Group)  
uint32 temp;
uint8 IPRADDR=NVIC_Channel/4;  //每组只能存4个,得到组地址 
uint8 IPROFFSET=NVIC_Channel%4;//在组内的偏移
IPROFFSET=IPROFFSET*8+4;    //得到偏移的确切位置
NVIC_PriorityGroupConfig(NVIC_Group);//设置分组
temp=NVIC_PreemptionPriority<<(4-NVIC_Group);  
temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);
temp&=0xf;//取低四位

if(NVIC_Channel<32)NVIC->ISER[0]|=1<<NVIC_Channel;//使能中断位(要清除的话,相反操作就OK)
else NVIC->ISER[1]|=1<<(NVIC_Channel-32);    
NVIC->IPR[IPRADDR]|=temp<<IPROFFSET;//设置响应优先级和抢断优先级           
}

//外部中断配置函数
//只针对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上事件上升降沿触发


//////////////////////////////////////////////////////////////////////////////


int main(void)
{
// uint8 Key_Value = 0x00;
RCC_DeInit();
SYSTEM_PerDiv_Initial();  //设置中断向量表
RCC->APB2ENR |= ( RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOD |RCC_APB2Periph_AFIO );
uart_init(36,115200);     //开启AFIO复用时钟
delay_init(72);
GPIO_Config();   //配置IO口
// AFIO->EXTICR[1] = 0x00000002;   //Key1 中断   PC4
// AFIO->EXTICR[2] = 0x00000100;   //Key2 中断   PB10
// AFIO->EXTICR[3] = 0x00000020;   //Key3 中断   PC13
// AFIO->EXTICR[0] = 0x00000000;   //Key4 中断 PA0
// EXTI-> IMR = (0x01<<0)|(0x01<<4)|(0x01<<10)|(0x01<<13); //中断屏蔽寄存器
// EXTI-> EMR = (0x01<<0)|(0x01<<4)|(0x01<<10)|(0x01<<13); //事件屏蔽寄存器
// EXTI-> RTSR = (0x01<<0)|(0x01<<4)|(0x01<<10)|(0x01<<13); //上升沿触发 
Ex_NVIC_Config(GPIO_C,4,FTIR); //void Ex_NVIC_Config(u8 GPIOx,u8 BITx,u8 TRIM) 
Ex_NVIC_Config(GPIO_B,10,FTIR);
Ex_NVIC_Config(GPIO_C,13,FTIR);
Ex_NVIC_Config(GPIO_A,0,FTIR);
    NVIC_Init(1,2,(u8)0x06,1); //初始化中断Key1   void NVIC_Init(uint8 NVIC_PreemptionPriority,uint8 NVIC_SubPriority,uint8 NVIC_Channel,uint8 NVIC_Group)
    NVIC_Init(1,3,(u8)0x0A,1); //初始化中断Key2
    NVIC_Init(1,4,(u8)0x028,1); //初始化中断Key3

LEDALL_OFF();
printf("Interrupt Initial.... \n");
while(1)
{
delay_ms(1000);
// Key_Value = Key_Scan();
// delay_ms(10);
// switch(Key_Value)
// {
// case 1:
// LEDALL_OFF();
// LED1_ON();
// break;
// case 2:
// LEDALL_OFF();
// LED2_ON();
// break;
// case 3:
// LEDALL_OFF();
// LED3_ON();
// break;
// case 4:
// LEDALL_OFF();
// LED4_ON();
// break;
// default:
// break;
// }
}
}

void EXTI0_IRQHandler(void)
{
    printf("中断0 \n");
LEDALL_OFF();
LED1_ON();
EXTI->R=1<<0;  //清除LINE0上的中断标志位  
}

void EXTI4_IRQHandler(void)
{
printf("中断4 \n");
LEDALL_OFF();
LED2_ON();
EXTI->R=1<<4;  //清除LINE0上的中断标志位  
}

void EXTI15_10_IRQHandler(void)
{
printf("中断10~15 \n");  
LEDALL_OFF();
LED3_ON();
EXTI->R=1<<13;  //清除LINE0上的中断标志位  
EXTI->R=1<<10;  //清除LINE0上的中断标志位  
}







正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2012-9-28 00:17:42 | 显示全部楼层
何不先用我的代码测试?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

6

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
93
金钱
93
注册时间
2012-9-11
在线时间
6 小时
 楼主| 发表于 2012-9-28 08:12:44 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
呵呵  谢谢! 
原来烧入程序后要重新上电才可以开启外部中断的...我一直烧入程序后 按复位键...所以外部中断一直没起作用....
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2012-9-28 10:09:49 | 显示全部楼层
回复【3楼】supertyc01:
--------------------------------
不是这个原因吧...
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

6

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
93
金钱
93
注册时间
2012-9-11
在线时间
6 小时
 楼主| 发表于 2012-9-28 21:28:33 | 显示全部楼层
回复【4楼】正点原子:
---------------------------------
我直接烧例程里的hex文件,如果不是重新上电也不行...
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2012-9-28 23:57:37 | 显示全部楼层
回复【5楼】supertyc01:
---------------------------------
不重新上电,程序运行么?(加一个DS0闪烁的提示)
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

6

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
93
金钱
93
注册时间
2012-9-11
在线时间
6 小时
 楼主| 发表于 2012-9-29 08:49:58 | 显示全部楼层
回复【6楼】正点原子:
---------------------------------
程序也运行,我在进入主循环前的一个 printf 可以正常显示出来,但是就是不能进中断服务程序....重新上电复位后就可以....
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165377
金钱
165377
注册时间
2010-12-1
在线时间
2111 小时
发表于 2012-9-29 13:34:34 | 显示全部楼层
这就真怪了,你用的我们的开发板?
如果是发代码上来,我测试下。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

6

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
93
金钱
93
注册时间
2012-9-11
在线时间
6 小时
 楼主| 发表于 2012-9-29 16:11:51 | 显示全部楼层
回复【8楼】正点原子:
---------------------------------
我用的是神州的开发板,参考你的程序的,感觉你写的教程比他们的好多了!!呵呵!
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-28 03:01

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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