OpenEdv-开源电子网

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

关于软件触发外部中断寄存器EXTI->SWIER的用途,实验已经成功。

[复制链接]

170

主题

917

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1824
金钱
1824
注册时间
2013-4-13
在线时间
63 小时
发表于 2014-6-16 00:54:27 | 显示全部楼层 |阅读模式
关于外部中断寄存器EXTI->SWIER的用途,刚开始我也是云里雾里,感觉手册说的不是很清楚。凭借自己对EXTI->SWIER功能的理解做了一个实验;实验原理是:定义两个中断线EXTI0(PA0)和EXTI13(PC13)用来管理两个按键KEY0和KEY1,然后编写中断服务函数,中断服务函数的思路是,按下KEY0时,在LCD上显示“SWIER+KEY0:”;按下KEY1时就将LCD上显示的SWIER+KEY0:”清除掉以证明KEY1按键已按下,同时也证明了外部中断线EXTI13已经触发(主函数会有相关的操作)。下面是两个中断服务函数(至于配置和分组函数就不贴出来了):
void EXTI0_IRQHandler(void)    //KEY0按键
{
    if(EXTI_GetITStatus(EXTI_Line0) != RESET) 
      {

        LCD_DispStr(20, 80, (uint8_t *)"SWIER+KEY0:", RED);  //显示SWIER+KEY0:
       EXTI_ClearITPendingBit(EXTI_Line0);    
     }  
}
void EXTI15_10_IRQHandler(void)  //KEY1按键
{
   if(EXTI_GetITStatus(EXTI_Line13) != RESET) 
   {
       // LCD_DispStr(20, 60, (uint8_t *)"SWIER+KEY1:", RED);
        LCD_DispStr(20, 80, (uint8_t *)"SWIER+KEY0:", WHITE);    //清除LCD显示的SWIER+KEY0:
        EXTI_ClearITPendingBit(EXTI_Line13);     
        EXTI->SWIER=0;  //清除EXTI->SWIER寄存器相应的位,这种写法有点不规范,其实是应该将EXTI->SWIER寄存器的bit13清零即复位
   }  
}
主函数:
int main(void)
{  u8 m=0;
  LCD_Init();
  LED_GPIO_Config();
 delay_init();
 uart_init(9600);

  EXTI_PC13_Config(); 
  EXTI_PA0_Config();

  LCD_Clear(0, 0, 240, 320, WHITE);
 

  EXTI->IMR|=1<<13;//  
  EXTI->EMR|=1<<13;//
  EXTI->SWIER=0;

while( 1 )
{
    m++;
   LCD_DispNumber(100, 100, m, WHITE); //显示m的值
   delay_ms(500);
 
  if(m==10)
   {
     EXTI->SWIER|=1<<13;  //软件触发中断线13,
      m=0;
   
   }
}

主函数其实很简单,程序运行之后,先按下KEY0按键这时会在LCD上显示“SWIER+KEY0”;同时,在LCD上每隔500ms显示一次m的值,当m等于10的时候
 EXTI->SWIER寄存器的bit13位置1,这时就相当于按下KEY1按键只不过是由程序执行的,这时LCD上显示的SWIER+KEY0”会被清除;证明外部中断线EXTI13已经触发


手艺人要内外兼修。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2014-6-16 01:00:09 | 显示全部楼层
谢谢分享。。。。。。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2019-4-28
在线时间
3 小时
发表于 2022-7-11 03:39:59 | 显示全部楼层
我自己改了按键实验,发现两个小瑕疵:1、main函数里EXTI_EMR寄存器不需要设置,2、清除SWIER标志手册里介绍的是通过往PR寄存器对应位写1来实现。下面是代码,通过3个按键控制2个LED和蜂鸣器翻转输出。
key.c文件代码:
#include "key.h"
#include "delay.h"

void KEY_Init()
{
        GPIO_InitTypeDef GPIO_InitTypeDef_KEY;
        NVIC_InitTypeDef NVIC_InitStruct;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);
        GPIO_InitTypeDef_KEY.GPIO_Mode = GPIO_Mode_IPU;
        GPIO_InitTypeDef_KEY.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4;
        GPIO_Init(GPIOE,&GPIO_InitTypeDef_KEY);
       
        GPIO_InitTypeDef_KEY.GPIO_Mode = GPIO_Mode_IPD;
        GPIO_InitTypeDef_KEY.GPIO_Pin = GPIO_Pin_0;
        GPIO_Init(GPIOA,&GPIO_InitTypeDef_KEY);
       
        NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn;
        NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
        NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 3;
        NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
        NVIC_Init(&NVIC_InitStruct);
       
        NVIC_InitStruct.NVIC_IRQChannel = EXTI1_IRQn;
        NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
        NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 3;
        NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;
        NVIC_Init(&NVIC_InitStruct);
       
        NVIC_InitStruct.NVIC_IRQChannel = EXTI2_IRQn;
        NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
        NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 3;
        NVIC_InitStruct.NVIC_IRQChannelSubPriority = 3;
        NVIC_Init(&NVIC_InitStruct);
}

unsigned char KEY_Scan(unsigned char mode)
{
        static unsigned char key_up_bit = 1;
        if(mode)
        {
                key_up_bit =1;
        }
        if(key_up_bit && (KEY0 == 0 ||KEY1 == 0 ||KEY_UP == 1))
        {
                key_up_bit = 0;
                delay_ms(15);
                if(KEY0==0)
                {
                        return 1;
                }
                else if(KEY1==0)
                {
                        return 2;
                }
                else if(KEY_UP==1)
                {
                        return 3;
                }
        }
        else if(KEY0 == 1 && KEY1 == 1 && KEY_UP == 0)
        {
                key_up_bit = 1;
        }
        return 0;
}

void EXTI0_IRQHandler(void)
{
        if(EXTI_GetITStatus(EXTI_Line0) != 0)
        {
                if(GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_5) != 0)
                {
                       
                        GPIO_WriteBit(GPIOB,GPIO_Pin_5,Bit_RESET);
                       
                }else
                {
                       
                        GPIO_WriteBit(GPIOB,GPIO_Pin_5,Bit_SET);
               
                }
               
        }
       
       
        EXTI->PR |= 0x0001 ;

}


void EXTI1_IRQHandler(void)
{
        if(EXTI_GetITStatus(EXTI_Line1) != 0)
        {
                if(GPIO_ReadOutputDataBit(GPIOE,GPIO_Pin_5) != 0)
                {
                       
                        GPIO_WriteBit(GPIOE,GPIO_Pin_5,Bit_RESET);
                       
                }else
                {
                       
                        GPIO_WriteBit(GPIOE,GPIO_Pin_5,Bit_SET);
               
                }
               
        }
       
       
        EXTI->PR |= 0x0001<<1 ;

}


void EXTI2_IRQHandler(void)
{
        if(EXTI_GetITStatus(EXTI_Line2) != 0)
        {
               
                if(GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_8) != 0)
                {
                       
                        GPIO_WriteBit(GPIOB,GPIO_Pin_8,Bit_RESET);
                       
                }else
                {
                       
                        GPIO_WriteBit(GPIOB,GPIO_Pin_8,Bit_SET);
               
                }
               
               
        }
       
       
        EXTI->PR |= 0x0001<<2 ;

}
       
main函数代码:
#include "stm32f10x.h"
#include "key.h"
#include "led.h"
#include "beep.h"
#include "delay.h"

int main()
{
        unsigned char key_value;
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        LED_Init();
        BEEP_Init();
        KEY_Init();
        delay_init();
        EXTI->IMR |= 0x07;//0000 0111
        while(1)
        {
                key_value = KEY_Scan(0);
                if(key_value)
                {
                        switch(key_value)
                        {
                                case 1:
                                        EXTI->SWIER |= 0x0001;break;
                                       
                                case 2:
                                        EXTI->SWIER |= 0x0001<<1;break;
                                       
                                case 3:
                                        EXTI->SWIER |= 0x0001<<2;break;
                        }
                }        else delay_ms(10);
        }
}




       
       



       
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-26 17:57

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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