你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32学习笔记——外部中断EXTI

[复制链接]
烙馍菜盒 发布时间:2017-10-13 13:13
% V" n- f# j3 h/ R4 a

学习笔记

for   STM32F103C8

redesigned by zhang bin

2012-10-30

versionsV-0.1

All Rights Reserved

main.c如下,注释的比较详细,把下面的例子即说明都看明白基本上就可以用了:

//抢占级别高的会打断其他中断优先执行,而响应级别高的会在其他中断执行完优先执行。

//EXTI:外部中断/事件控制器

//EXTI控制器可以产生高达19个软件事件/中断请求

//19根线配置为中断源,将19根线配置为事件源,将19根线配置为软件中断/事件线,详见《STM32F103xxx使用手册》

//P135

//在这个文件中主要是进行各种初始化配置,包括GPIO配置、EXTI配置、系统时钟配置等

//中断服务程序则在stm32f10x_it.c文件中,该文件提供所有异常处理程序和外围中断服务程序的模板,详见该文件

#include "stm32f10x_lib.h"

EXTI_InitTypeDef EXTI_InitStructure;  //定义外部中断初始化结构体变量  内部含有4个成员 详见EXTI_InitTypeDef的定义

ErrorStatus HSEStartUpStatus; //定义错误状态变量,是枚举类型

void RCC_Configuration(void);

void GPIO_Configuration(void);

void NVIC_Configuration(void);

int main(void)

{

#ifdef DEBUG

  debug();

#endif

  

  RCC_Configuration();  //系统时钟配置   

  NVIC_Configuration(); //NVIC配置

   

  GPIO_Configuration();  //配置GPIO

  

   //STM32的外部中断不是固定的,是可以映射的。如EXTI6既可以映射到PB6也可以映射到PA6,详见外部中断/事件与GPIO的映射关系

   //IO端口注册至中断线(IO口映射到中断线N)

  //

  GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource6);  //选择GPIO管脚用作外部中断线路

  //第一个参数选择用作外部中断线源的GPIO端口  第二个参数是待设置的外部中断线路,可以是GPIO_PinSourcex(x可以0~15)

   

  //配置按钮中断线触发方式  设置中断配置结构体成员

  EXTI_InitStructure.EXTI_Line = EXTI_Line6; //选择外部中断线  EXTI_Line0~EXTI_Line1819根线

  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;   //设置为中断请求,可以为EXTI_Mode_Interrupt中断请求或者

  //EXTI_Mode_Event事件请求

  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //触发方式下降沿触发 还可以为EXTI_Trigger_Rising上升沿触发或者

  //EXTI_Trigger_Rising_Falling上升沿下降沿触发

  EXTI_InitStructure.EXTI_LineCmd = ENABLE; //中断线使能   ENABLE使能,DISABLE失能

  EXTI_Init(&EXTI_InitStructure); //根据参数结构体初始化EXTI中断

  

  EXTI_GenerateSWInterrupt(EXTI_Line6); //产生一个软件中断  EXTI_Line6中断允许

  //到此中断配置完成,可以写中断处理函数。

        

  while (1)

  {

  }

}

void RCC_Configuration(void)

{

//复位RCC外部设备寄存器到默认值

  RCC_DeInit();  

  //打开外部高速晶振

  RCC_HSEConfig(RCC_HSE_ON);

//等待外部高速时钟准备好

  HSEStartUpStatus = RCC_WaitForHSEStartUp();

  //外部高速时钟已经准别好

  if(HSEStartUpStatus == SUCCESS)  

  {

   

    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

   

    FLASH_SetLatency(FLASH_Latency_2);

  

   //配置AHB(HCLK)时钟=SYSCLK

    RCC_HCLKConfig(RCC_SYSCLK_Div1);

  

    //配置APB2(PCLK2)=AHB时钟

    RCC_PCLK2Config(RCC_HCLK_Div1);

    //配置APB1(PCLK1)=AHB 1/2时钟

    RCC_PCLK1Config(RCC_HCLK_Div2);  

    //配置ADC时钟=PCLK2 1/4

    RCC_ADCCLKConfig(RCC_PCLK2_Div4);

  

    //配置PLL时钟 == 外部高速晶体时钟*9 8MHz*9MHz=72MHz

    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

   

//配置ADC时钟= PCLK2/4

    RCC_ADCCLKConfig(RCC_PCLK2_Div4);

   //使能PLL时钟

    RCC_PLLCmd(ENABLE);  

   //等待PLL时钟就绪

    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)  

    {

    }

    //配置系统时钟 = PLL时钟

    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

   //检查PLL时钟是否作为系统时钟

    while(RCC_GetSYSCLKSource() != 0x08)  

    {

    }

  }

   

  

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOB

                         | RCC_APB2Periph_AFIO, ENABLE);

   //使能GPIOAGPIOBAFIOAPB2

}

void GPIO_Configuration(void)

{

  GPIO_InitTypeDef GPIO_InitStructure;   //定义配置GPIO的结构体

   

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //选中第8个脚

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;       //推挽输出

  GPIO_Init(GPIOB, &GPIO_InitStructure); //用配置好的结构体初始化GPIOB PB8用于驱动led

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;   //选中6

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   //配置浮空输入

  GPIO_Init(GPIOB, &GPIO_InitStructure);  //初始化GPIOB   PB6脚连接外部中断线6的中断源

  //所有的端口都有外部中断的能力,为了使用外部中断线,端口必须配置为输入模式

}

void NVIC_Configuration(void)  //配置嵌套向量中断控制器

{

  NVIC_InitTypeDef NVIC_InitStructure;//定义初始化NVIC的结构体变量

  

#ifdef  VECT_TAB_RAM  

    //配置向量表基址

  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);   //分配中断向量表

#else  

   

  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);   

#endif

  

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);  //设置中断优先级

  //设置优先级分组:先占优先级和从优先级  输入参数设定优先级分组位长度  本例中NVIC_PriorityGroup_1:先占优先级1为,从优先级3

  //详见《STM32函数说明》P165

  //优先级分组只能设定一次

  

  //EXTI5-9共用一个中断源,EXTI10-15共用一个中断源

     //详见详见《STM32函数说明》P166

  NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel; //中断通道  指定IRQ通道 这里指定外部中断线9-5中断  因为使用的是EXTI6

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =  0;  //设定指定IRQ通道的先占优先级

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//设定指定IRQ通道的从优先级

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  //设定指定IRQ通道中断使能  DISABLE失能

  NVIC_Init(&NVIC_InitStructure);//根据结构体中指定的参数初始化NVIC中断

}

#ifdef  DEBUG

void assert_failed(u8* file, u32 line)

{

  

  

  while (1)

  {

  }

}

#endif

stm32f10x_it.c文件中的中断服务函数如下:

void EXTI9_5_IRQHandler(void) //外线路5-9的中断处理程序

{

  if(EXTI_GetITStatus(EXTI_Line6) != RESET) //检测制定的EXTI6线路触发请求是否发生。  

  //该函数检查指定的EXTI线路出发请求是否发生

  {

      //其实就是对PB8取反

    GPIO_WriteBit(GPIOB, GPIO_Pin_8, (BitAction)((1-GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_8))));

//该函数可以对指定的端口位进行操作  指定端口和位,然后指定操作。第三个参数指定待写入的值

//该参数必须取枚举类型BitAction的其中一个值,可以是Bit_RESET:清除数据端口位和Bit_SET:设置数据端口位

//GPIO_ReadOutputDataBit()函数读取指定的IO端口管脚的输出,参数指定端口和位

//EXTI_ClearFlag(EXTI_Line6);    //清除中断标志位(必须)   我在网上看到要求必须,但是在本例中并没有这句

   

    EXTI_ClearITPendingBit(EXTI_Line6); //清除EXTI线路挂起位

  }

}


  b( l+ g; _. t* j2 z
收藏 评论1 发布时间:2017-10-13 13:13

举报

1个回答
大陶 回答时间:2017-10-18 13:29:30
很好的帖子 以后可以直接拿来用的

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版