学习资料
李想stm32视频教程49集 http://pan.baidu.com/s/1kTyt03P STM32的中断(上中下)外部中断(寄存器、库函数)
STM32的函数说明(中文).pdf http://download.csdn.net/detail/leytton/7630851
中断管理函数.pdf http://wenku.baidu.com/view/b90e5b82360cba1aa811dad3.html
概念基础
STM32共76个中断,16个内核中断,60个外部中断,即可屏蔽中断
中断分5组:0-4,所有中断只能放在同一组里
ISER[0]、ISER[1]是32位的中断使能寄存器数组,ISER[0]的bit0-31对应中断0-31、ISER[1]的bit0-27对应中断32-59,置1有效
ICER[0]、ICER[1]正好相反,是清除使能,置1有效
stm32中断抢占优先级和响应优先级有什么区别?
中断A抢占优先级比B高,那么A的中断可以在B里面触发,忽略响应优先级;
A和B抢占优先级相同,则A、B的响应优先级决定谁先响应;
抢占优先级高的可以打断抢占优先级低的中断,响应式则不能
数字越小,优先级越高
中断配置步骤
源代码
/*******************************************************************************
*
* 软件功能: 中断闪灯实验(软件延时方式) 按键中断
*
*******************************************************************************/
#include "stm32f10x.h"
#include
#include "delay.h"
void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void EXTI_Configuration(void);
/*************************************************
函数: int main(void)
功能: main主函数
参数: 无
返回: 无
**************************************************/
int main(void)
{
RCC_Configuration();
GPIO_Configuration();
delay_init(72);
NVIC_Configuration();
EXTI_Configuration();
GPIO_ResetBits(GPIOA,GPIO_Pin_0);//灭
GPIO_ResetBits(GPIOA,GPIO_Pin_2);//灭
while(1);
}
/*************************************************
函数: void RCC_Configuration(void)
功能: 复位和时钟控制 配置
参数: 无
返回: 无
**************************************************/
void RCC_Configuration(void)
{
ErrorStatus HSEStartUpStatus; //定义外部高速晶体启动状态枚举变量
RCC_DeInit(); //复位RCC外部设备寄存器到默认值
RCC_HSEConfig(RCC_HSE_ON); //打开外部高速晶振
HSEStartUpStatus = RCC_WaitForHSEStartUp(); //等待外部高速时钟准备好
if(HSEStartUpStatus == SUCCESS) //外部高速时钟已经准别好
{
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //开启FLASH预读缓冲功能,加速FLASH的读取。所有程序中必须的用法.位置:RCC初始化子函数里面,时钟起振之后
FLASH_SetLatency(FLASH_Latency_2); //flash操作的延时
RCC_HCLKConfig(RCC_SYSCLK_Div1); //配置AHB(HCLK)时钟等于==SYSCLK
RCC_PCLK2Config(RCC_HCLK_Div1); //配置APB2(PCLK2)钟==AHB时钟
RCC_PCLK1Config(RCC_HCLK_Div2); //配置APB1(PCLK1)钟==AHB1/2时钟
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //配置PLL时钟 == 外部高速晶体时钟 * 9 = 72MHz
RCC_PLLCmd(ENABLE); //使能PLL时钟
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) //等待PLL时钟就绪
{
}
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //配置系统时钟 = PLL时钟
while(RCC_GetSYSCLKSource() != 0x08) //检查PLL时钟是否作为系统时钟
{
}
}
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); //允许 GPIOB、AFIO时钟
}
/*************************************************
函数: void GPIO_Configuration(void)
功能: GPIO配置
参数: 无
返回: 无
**************************************************/
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO初始化结构体
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure); //PA用于输出控制LED灯
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_Init(GPIOB, &GPIO_InitStructure); //PB.0用于接受按键k1输入
}
void NVIC_Configuration(void) //中断分组和优先级配置 详见《STM32的函数说明(中文).pdf》P165
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //0组,先占优先级0位,从优先级4位
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //外部中断线 0 中断
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //0组无抢占优先级,所以只配置从优先级,即响应式优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能
NVIC_Init(& NVIC_InitStructure); //初始化配置
}
void EXTI_Configuration(void) //中断配置 //详见《STM32的函数说明(中文).pdf》 P99
{
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_ClearITPendingBit(EXTI_Line0);//清除 EXTI 线路挂起位
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //设置 EXTI 线路为中断请求
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //设置输入线路下降沿为中断请求
EXTI_InitStructure.EXTI_Line = EXTI_Line0; //外部中断线 0
EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能
EXTI_Init(& EXTI_InitStructure); //初始化配置
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource0); ///*将EXTI线0连接到PB0*/
}
/*********************************************************
中断服务程序
*********************************************************/
void EXTI0_IRQHandler() //按下按钮还是放开按钮是下降沿??
{
if(EXTI_GetITStatus(EXTI_Line0) == SET)//检查指定的EXTI线路触发请求发生与否,返回一个EXTI_Line新状态
{
EXTI_ClearITPendingBit(EXTI_Line0);//清除线路挂起位
EXTI_ClearFlag(EXTI_Line0);//清除中断挂起位
GPIO_SetBits(GPIOA,GPIO_Pin_0);//点亮LED
delay_ms(500);//延时
GPIO_ResetBits(GPIOA,GPIO_Pin_0);//灭
if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0)) GPIO_SetBits(GPIOA,GPIO_Pin_2);//点亮LED
else GPIO_ResetBits(GPIOA,GPIO_Pin_2);//灭
}
}
可另行参考文章:
STM32学习笔记之EXTI(外部中断)http://blog.sina.com.cn/s/blog_6623834301018woa.html
参考资料:STM32数据手册、网络资料
=========================================分割线=========================================
外部中断/事件控制器由19个产生事件/中断要求的边沿检测器组成。每个输入线可以独立地配置
输入类型(脉冲或挂起)和对应的触发事件(上升沿或下降沿或者双边沿都触发)。每个输入线都可以被独
立的屏蔽。挂起寄存器保持着状态线的中断要求。
=========================================分割线=========================================
19个中断如下:
17——EXTI线16连接到PVD输出
18——EXTI线17连接到RTC闹钟事件
19——EXTI线18连接到USB唤醒事件
注:有上图可知EXTI0连接的引脚为PA0、PB0、PC0、PD0、PE0、PF0、PG0,其他外部中断EXTI1——
EXTI15类似。所以在使用时尽量将需要的外部中断配置在不同的EXTIx上。
例如需要3个外部中断,我们可以配置到PA0、PB4、PG3上,此时每个中断都有自己的中断处理程
序段。如果配置到PA0、PB0、PC1,则PA0和PB0将公用一个中断程序段。当然如果特殊需要,也
可以这样设计。
=========================================分割线=========================================
配置使用方法:
初始化相应的GPIO管脚
配置外部中断源并进行中断源和GPIO的连接
编写相应中断源的中断处理程序
=========================================分割线=========================================
程序代码
初始化相应的GPIO管脚
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
注:GPIO的复用功能必须打开,如红字部分
配置外部中断源并进行中断源和GPIO的连接
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource0);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource1);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource8);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource9);
EXTI_InitStructure.EXTI_Line = EXTI_Line0|EXTI_Line1|EXTI_Line8|EXTI_Line9;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
编写相应中断源的中断处理程序
void EXTI0_IRQHandler(void)
{
if(Sys_Status > MIN_STATUS)
{
Sys_Status --;
}
EXTI_ClearITPendingBit(EXTI_Line0);
}
void EXTI1_IRQHandler(void)
{
PEout(2) = ~PEout(2);
EXTI_ClearITPendingBit(EXTI_Line1);
}
#define Exti_From_Pin8 0x00000100
#define Exti_From_Pin9 0x00000200
void EXTI9_5_IRQHandler(void)
{
u32 Temp = 0x00;
PEout(2) = ~PEout(2);
Temp = EXTI->PR; //取读是那个引脚的中断
switch(Temp)
{
case Exti_From_Pin8:
EXTI_ClearITPendingBit(EXTI_Line8);
break;
case Exti_From_Pin9:
if(Sys_Status < MAX_STATUS)
{
Sys_Status ++;
}
EXTI_ClearITPendingBit(EXTI_Line9);
break;
default:break;
}
}
=========================================分割线=========================================
中断处理程序说明,由于外部中断EXTI5——EXTI9公用了一个中断(EXTI10——EXTI15类似)所以要
区分不同的中断源需要进行相应的判断。如上EXTI9_5_IRQHandler中,通过取读EXTI->PR寄存器来判
断中断的来源。
上一篇:STM32单片机(3) 串口中断通信
下一篇:STM32单片机(1) 总记 学习资料+参考手册+LED灯
推荐阅读最新更新时间:2024-03-16 16:03