微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > STM32外部中断学习笔记

STM32外部中断学习笔记

时间:11-20 来源:互联网 点击:

  1. void)
  2. {
  3. delay_ms(10);//消抖
  4. if(KEY2==1)//按键2
  5. {
  6. LED0=!LED0;
  7. LED1=!LED1;
  8. }
  9. EXTI->PR=1<0;//清除LINE0上的中断标志位
  10. }
  11. //外部中断15~10服务程序
  12. voidEXTI15_10_IRQHandler(void)
  13. {
  14. delay_ms(10);//消抖
  15. if(KEY0==0)//按键0
  16. {
  17. LED0=!LED0;
  18. }elseif(KEY1==0)//按键1
  19. {
  20. LED1=!LED1;
  21. }
  22. EXTI->PR=1<13;//清除LINE13上的中断标志位
  23. EXTI->PR=1<15;//清除LINE15上的中断标志位
  24. }
  25. //外部中断初始化程序
  26. //初始化PA0,PA13,PA15为中断输入.
  27. voidEXTIX_Init(void)
  28. {
  29. RCC->APB2ENR=1<2;//使能PORTA时钟
  30. JTAG_Set(JTAG_SWD_DISABLE);//关闭JTAG和SWD
  31. GPIOA->CRL&=0XFFFFFFF0;//PA0设置成输入
  32. GPIOA->CRL=0X08;
  33. GPIOA->CRH&=0X0F0FFFFF;//PA13,15设置成输入
  34. GPIOA->CRH=0X80800;
  35. GPIOA->ODR=1<13;//PA13上拉,PA0默认下拉
  36. GPIOA->ODR=1<15;//PA15上拉
  37. Ex_NVIC_Config(GPIO_A,0,RTIR);//上升沿触发
  38. Ex_NVIC_Config(GPIO_A,13,FTIR);//下降沿触发
  39. Ex_NVIC_Config(GPIO_A,15,FTIR);//下降沿触发
  40. MY_NVIC_Init(2,2,EXTI0_IRQChannel,2);//抢占2,子优先级2,组2
  41. MY_NVIC_Init(2,1,EXTI15_10_IRQChannel,2);//抢占2,子优先级1,组2
  42. }

其中的两个函数:Ex_NVIC_Config(GPIO_A,0,RTIR);和MY_NVIC_Init(2,2,EXTI0_IRQChannel,2);这两个函数都是在sys.c里定义,分别完成了步骤2、3、4.函数原型如下:

[cpp]view plaincopy

  1. //外部中断配置函数
  2. //只针对GPIOA~G;不包括PVD,RTC和USB唤醒这三个
  3. //参数:GPIOx:0~6,代表GPIOA~G;BITx:需要使能的位;TRIM:触发模式,1,下升沿;2,上降沿;3,任意电平触发
  4. //该函数一次只能配置1个IO口,多个IO口,需多次调用
  5. //该函数会自动开启对应中断,以及屏蔽线
  6. //待测试...
  7. voidEx_NVIC_Config(u8GPIOx,u8BITx,u8TRIM)
  8. {
  9. u8EXTADDR;
  10. u8EXTOFFSET;
  11. EXTADDR=BITx/4;//得到中断寄存器组的编号
  12. EXTOFFSET=(BITx%4)*4;
  13. RCC->APB2ENR=0x01;//使能io复用时钟
  14. AFIO->EXTICR[EXTADDR]&=~(0xF
  15. AFIO->EXTICR[EXTADDR]=GPIOx
  16. //自动设置
  17. EXTI->IMR=1
  18. //EXTI->EMR=1
  19. if(TRIM&0x01)EXTI->FTSR=1
  20. if(TRIM&0x02)EXTI->RTSR=1
  21. }

这个函数完成了两个步骤:

2、开启IO口复用时钟,设置IO口与中断线的映射关系

3、开启与该IO口相对的线上的中断/时间,设置触发条件

[cpp]view plaincopy

  1. //设置NVIC
  2. //NVIC_PreemptionPriority:抢占优先级
  3. //NVIC_SubPriority:响应优先级
  4. //NVIC_Channel:中断编号
  5. //NVIC_Group:中断分组0~4
  6. //注意优先级不能超过设定的组的范围!否则会有意想不到的错误
  7. //组划分:
  8. //组0:0位抢占优先级,4位响应优先级
  9. //组1:1位抢占优先级,3位响应优先级
  10. //组2:2位抢占优先级,2位响应优先级
  11. //组3:3位抢占优先级,1位响应优先级
  12. //组4:4位抢占优先级,0位响应优先级
  13. //NVIC_SubPriority和NVIC_PreemptionPriority的原则是,数值越小,越优先
  14. //CHECKOK
  15. //100329
  16. voidMY_NVIC_Init(u8NVIC_PreemptionPriority,u8NVIC_SubPriority,u8NVIC_Channel,u8NVIC_Group)
  17. {
  18. u32temp;
  19. u8IPRADDR=NVIC_Channel/4;//每组只能存4个,得到组地址
  20. u8IPROFFSET=NVIC_Channel%4;//在组内的偏移
  21. IPROFFSET=IPROFFSET*8+4;//得到偏移的确切位置
  22. MY_NVIC_PriorityGroupConfig(NVIC_Group);//设置分组
  23. temp=NVIC_PreemptionPriority<(4-NVIC_Group);
  24. temp=NVIC_SubPriority&(0x0f>>NVIC_Group);
  25. temp&=0xf;//取低四位
  26. if(NVIC_Channel<32)NVIC->ISER[0]=1
  27. elseNVIC->ISER[1]=1<(NVIC_Channel-32);
  28. NVIC->IPR[IPRADDR]=temp


Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top