打印
[应用相关]

STM32笔记之外部中断GPIO

[复制链接]
385|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ym0sly|  楼主 | 2022-3-30 16:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
IO, ST, gp, pi
b)        初始化函数定义:
void EXTI_Configuration(void); //定义IO中断初始化函数
c)        初始化函数调用:
EXTI_Configuration();//IO中断初始化函数调用简单应用:
d)        初始化函数:
void EXTI_Configuration(void)
{
  EXTI_InitTypeDef EXTI_InitStructure;        //EXTI初始化结构定义

EXTI_ClearITPendingBit(EXTI_LINE_KEY_BUTTON);//清除中断标志
   GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource3);//管脚选择
   GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource4);
     GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource5);
     GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource6);

    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//事件选择
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//触发模式
  EXTI_InitStructure.EXTI_Line = EXTI_Line3 | EXTI_Line4; //线路选择
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;//启动中断
  EXTI_Init(&EXTI_InitStructure);//初始化
}

使用特权

评论回复
沙发
ym0sly|  楼主 | 2022-3-30 16:08 | 只看该作者
e)        RCC初始化函数中开启I/O时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);

GPIO初始化函数中定义输入I/O管脚。
//IO输入,GPIOA的4脚输入
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;         //上拉输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);                //初始化
f)        在NVIC的初始化函数里面增加以下代码打开相关中断:
  NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel;        //通道
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//占先级
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                        //响应级
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //启动
  NVIC_Init(&NVIC_InitStructure);                                                                //初始化

使用特权

评论回复
板凳
ym0sly|  楼主 | 2022-3-30 16:10 | 只看该作者
g)        在stm32f10x_it.c文件中找到void USART1_IRQHandler函数,在其中添入执行代码。一般最少三个步骤:先使用if语句判断是发生那个中断,然后清除中断标志位,最后给字符串赋值,或做其他事情。
  if(EXTI_GetITStatus(EXTI_Line3) != RESET)                                  //判断中断发生来源
   { EXTI_ClearITPendingBit(EXTI_Line3);                                          //清除中断标志
    USART_SendData(USART1, 0x41);                                              //发送字符“a”
    GPIO_WriteBit(GPIOB, GPIO_Pin_2, (BitAction)(1-GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_2)));//LED发生明暗交替
}

使用特权

评论回复
地板
ym0sly|  楼主 | 2022-3-30 16:11 | 只看该作者
h)        中断注意事项:
中断发生后必须清除中断位,否则会出现死循环不断发生这个中断。然后需要对中断类型进行判断再执行代码。
使用EXTI的I/O中断,在完成RCC与GPIO硬件设置之后需要做三件事:初始化EXTI、NVIC开中断、编写中断执行代码。

使用特权

评论回复
5
ym0sly|  楼主 | 2022-3-30 16:14 | 只看该作者
我在板子上要使用PB11作为外部中断,使用stm32f10x_stdperiphere_library

在例子程序中只找到了使用PA3 PA4的,这些线可以直接挂在EXTI3 EXTI4中断上。

在STM32F10X的中断向量表中,在EXTI9-5 和EXTI15-10 看来我只能用EXTI15-10了。

使用特权

评论回复
6
ym0sly|  楼主 | 2022-3-30 16:16 | 只看该作者
附上初始化程序

void ShuttleKeyInit(void){
  GPIO_InitTypeDef GPIO_InitStructure;
  EXTI_InitTypeDef EXTI_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
  HT_STM_KEYInit(KNOBRIGHT);
  /* Enable GPIOD clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  
  
  
/* Configure PB.11 as input floating */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource11);
  
  // Configure EXTI Line11 to generate an interrupt on falling edge
  EXTI_InitStructure.EXTI_Line = EXTI_Line11;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);



  /* Enable the EXTI15_10 Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //EXTI15_10_IRQChannel;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

使用特权

评论回复
7
ym0sly|  楼主 | 2022-3-31 15:25 | 只看该作者
中断服务程序

/*******************************************************************************
* Function Name  : EXTI3_IRQHandler
* Description    : This function handles External interrupt Line 3 request.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void EXTI15_10_IRQHandler(void)
{
  
if(EXTI_GetITStatus(EXTI_Line11) != RESET)
  {
//    DISABLE_PB11_INT;
  if(HT_STM_KEYRead(KNOBRIGHT))
    g_Shuttle = LEFTTURN;
  else
    g_Shuttle = RIGHTTURN;
  EXTI_ClearITPendingBit(EXTI_Line11);
  }
}

使用特权

评论回复
8
ym0sly|  楼主 | 2022-3-31 15:28 | 只看该作者
中断服务程序要力求精简,不然会死机。没搞明白是为什么。
******************************************************************************
端口上的16个外部中断的任意一个中断号,可映射到一组引脚的任意一个(记住这里,是组中的任意一个)。

使用特权

评论回复
9
ym0sly|  楼主 | 2022-3-31 15:29 | 只看该作者
举例来说:
    外部中断号3,只可以映射到引脚PA3、PB3、PC3、PD3、PE3、PF3、PG3这一组中的任意一个(是一个,不是多个)引脚上,而不能映射其它引脚上。
    同理,外部中断号4,只可以映射到引脚PA4、PB4、PC4、PD4、PE4、PF4、PG4这一组中的任意一个引脚上,而不能映射其它引脚上。

使用特权

评论回复
10
ym0sly|  楼主 | 2022-3-31 15:30 | 只看该作者
另外,外部中断只有7个处理接口,外部中断号0~4,才具有独立的中断处理接口,外部中断号5~9,共享一个中断处理接口,外部中断号10~15,共享一个中断处理接口。

使用特权

评论回复
11
ym0sly|  楼主 | 2022-3-31 15:30 | 只看该作者

    基于上述原因,外部中断尽量只使用引脚号0~4,或5~9中的某一个,或10~15中的某一个,以简化中断处理的编写,同时也会缩短外部中断的处理时间(外部中断号5~9、10~15,如果不止对应一个中断号,则需要在中断处理程序来确定是哪个引脚产生的中断)。

使用特权

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

本版积分规则

28

主题

327

帖子

2

粉丝