中断interrupt

中断的读取方式

上升沿 下降沿 变电平
在这里插入图片描述

会分别在接收输入端口的
电平的上升段
电平的下降段
与电平的变化段

产生中断信号

f103上的可用中断

在这里插入图片描述
这取决于c8t6上保留的接口所可用的功能
在这里插入图片描述

中断在单片机硬件中的输入逻辑

在这里插入图片描述

STM32中断的使用感受

stm32f103c8t6的固件库函数
封装程度并不高
不论是
直接对应到不同的中断处理器的中断处理函数
在这里插入图片描述
还是
中断的数据结构体编译中
中断输入模式(定义中断输入线 )
与中断标志位
的分两个结构体定义
这里以PA4的中断输入为例
NVIC.h

#ifndef __NVIC_H
#define __NVIC_H	 
#include "sys.h"


extern u8 INT_MARK;//中断标志位


void KEYPAD4x4_INT_INIT (void);

#endif

NVIC.c

void KEYPAD4x4_INT_INIT (void){	 //按键中断初始化
	NVIC_InitTypeDef  NVIC_InitStruct;	//定义结构体变量
	EXTI_InitTypeDef  EXTI_InitStruct;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //启动GPIO时钟 (需要与复用时钟一同启动)     
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO , ENABLE);//配置端口中断需要启用复用时钟

	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource4);  //定义 GPIO  中断
	
	EXTI_InitStruct.EXTI_Line=EXTI_Line4;  //定义中断线
	EXTI_InitStruct.EXTI_LineCmd=ENABLE;              //中断使能
	EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;     //中断模式为 中断
	//EXTI_Mode_Interrupt = 0x00,			中断模式
  	//EXTI_Mode_Event = 0x04					事件模式
	EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;   //取决于外围电路的输入方式,此处采用下降沿触发
	//EXTI_Trigger_Rising = 0x08,			上升沿触发
  	//EXTI_Trigger_Falling = 0x0C,  	下降沿触发
	//EXTI_Trigger_Rising_Falling = 0x10		变化触发
	
	EXTI_Init(& EXTI_InitStruct);
	
	NVIC_InitStruct.NVIC_IRQChannel=EXTI4_IRQn;   //中断线     
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;  //使能中断
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;  //抢占优先级 2
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=2;     //子优先级  2
	//注意在sys.c中设置优先级
	/*
	void NVIC_Configuration(void)
	{ //嵌套中断向量控制器 的设置
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	//设置NVIC中断分组2:2位抢占优先级,2位响应优先级
	}
	*/
	NVIC_Init(& NVIC_InitStruct);
	}
	
	void  EXTI4_IRQHandler(void){
	if(EXTI_GetITStatus(EXTI_Line4)!=RESET){//判断某个线上的中断是否发生 
		INT_MARK=1;//标志位置1,表示有按键中断
		EXTI_ClearITPendingBit(EXTI_Line4);   //清除 LINE 上的中断标志位
	}     

——————————————
而其结构体的定义为
stm32f10x_exti.c

typedef struct
{
  uint32_t EXTI_Line;               /*!< Specifies the EXTI lines to be enabled or disabled.
                                         This parameter can be any combination of @ref EXTI_Lines */
   
  EXTIMode_TypeDef EXTI_Mode;       /*!< Specifies the mode for the EXTI lines.
                                         This parameter can be a value of @ref EXTIMode_TypeDef */

  EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines.
                                         This parameter can be a value of @ref EXTIMode_TypeDef */

  FunctionalState EXTI_LineCmd;     /*!< Specifies the new state of the selected EXTI lines.
                                         This parameter can be set either to ENABLE or DISABLE */ 
}EXTI_InitTypeDef;

misc.h

typedef struct
{
  uint8_t NVIC_IRQChannel;                    /*!< Specifies the IRQ channel to be enabled or disabled.
                                                   This parameter can be a value of @ref IRQn_Type 
                                                   (For the complete STM32 Devices IRQ Channels list, please
                                                    refer to stm32f10x.h file) */

  uint8_t NVIC_IRQChannelPreemptionPriority;  /*!< Specifies the pre-emption priority for the IRQ channel
                                                   specified in NVIC_IRQChannel. This parameter can be a value
                                                   between 0 and 15 as described in the table @ref NVIC_Priority_Table */

  uint8_t NVIC_IRQChannelSubPriority;         /*!< Specifies the subpriority level for the IRQ channel specified
                                                   in NVIC_IRQChannel. This parameter can be a value
                                                   between 0 and 15 as described in the table @ref NVIC_Priority_Table */

  FunctionalState NVIC_IRQChannelCmd;         /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel
                                                   will be enabled or disabled. 
                                                   This parameter can be set either to ENABLE or DISABLE */   
} NVIC_InitTypeDef;

甚至可以直接通过其固件库的编译
看出其在硬件设计上的思路 甚至是设计细节。。。
极其繁琐

so,
my advice is to find a more reliable and well-packed head-fiile for NVIC and EXTI interrupt to use
or you need to

  1. 确定找到中断的输入端口(当然你在此之前就开启了GPIO时钟与复用时钟并定义了结构体变量)
    然后对应上图表格分别设置
  2. EXTI
    1 中断入口(中断所使用的标志位)(只能使用对应标志位,但此语句又必须要经过编译,可以理解为这样一句话“他要上厕所,所以他去厕所了”)
    2 中断使能(你还需要在进厕所前打个卡申请一下)
    3 设置中断的使用模式与触发模式(这个没什么好说的,根据需求弄)
  3. NVIC
    1 对应中断线的使用来对应确定哪个中断处理函数的使用(蹲下之前按照你是谁给你指定个坑位,不然就error炸坑)
    2 中断线使能(蹲下之前再打个卡申请一下)
    3 设置中断优先级(先看抢占优先级,再看子优先级)
  4. 最后编译中断的读取函数,并在函数内改变标志位INT_MARK(终于,你蹲了下来,静静等待着括约肌的收缩。。。)

中断的编译就是如此复杂
让我不禁想吐槽
为什么要在软件中写两个一定绑定的结构体呢?
在两个绑定的结构体之上还要写几个一定绑定的结构体数据呢?
N***,等我把这几个中断的结构体一个一个自己全部编译完
程序都跑完了
H桥都过载了
LED灯珠都烧完了
人工智能都起义了
捏麻麻的我孙子都出生了
!!!

所以我只有,且只有这个建议
要么,自己写一个结构体,可以自动对中断内容进行设置并编译
还要么,直接上Github上找个能用的直接代替完事算了

我甚至觉得这东西就是拿来给初学者加深stm32了解程度的。。。当然也不一定,毕竟我也是初学者,等后面如果我有学习到这一相关部分并有了深入的的了解明白其编译的其他用心的话,我会继续更新(当然?也许?咕咕咕)

洋桃版使用实例

#include "stm32f10x.h" //STM32头文件
#include "sys.h"
#include "delay.h"
#include "relay.h"
#include "oled0561.h"

#include "KEYPAD4x4.h"
#include "NVIC.h"


int main (void){//主程序
   u8 s;
   delay_ms(500); //上电时等待其他器件就绪
   RCC_Configuration(); //系统时钟初始化 
   RELAY_Init();//继电器初始化

   I2C_Configuration();//I2C初始化
   OLED0561_Init(); //OLED初始化
   OLED_DISPLAY_8x16_BUFFER(0,"   YoungTalk    "); //显示字符串
   OLED_DISPLAY_8x16_BUFFER(3," KEYPAD4x4 TEST "); //显示字符串

   INT_MARK=0;//标志位清0

   NVIC_Configuration();//设置中断优先级
   KEYPAD4x4_Init();//阵列键盘初始化
   KEYPAD4x4_INT_INIT();//阵列键盘的中断初始化

   
   	u8 INT_TIME;	//用于记录使用中断的次数
   	INT_TIME = 0while(1){

   	//其他程序内容
   	if( INT_TIME == 99)  INT_TIME = 0;
   	OLED_DISPLAY_8x16_BUFFER(4,"times of INT");
   	OLED_DISPLAY_8x16(6,13*8,INT_TIME/10+0x30);//
   	OLED_DISPLAY_8x16(6,14*8,INT_TIME%10+0x30);//
   	

   	if(INT_MARK){ //中断标志位为1表示有按键中断
   		INT_TIME++;
   		INT_MARK=0;//标志位清0
   		s=KEYPAD4x4_Read();//读出按键值
   		if(s!=0){ //如按键值不是0,也就是说有按键操作,则判断为真
   			//-------------------------"----------------"
   			OLED_DISPLAY_8x16_BUFFER(6," KEY NO.        "); //显示字符串
   			OLED_DISPLAY_8x16(6,8*8,s/10+0x30);//
   			OLED_DISPLAY_8x16(6,9*8,s%10+0x30);//
   		}
   	}
   }
}

总而言之,在程序中
外部中断使用的中心思想
就是

通过程序以某种方式去查询一个
可由外围硬件编程或改变的标记值
以此来更改CPU所处理的任务与线程
优先处理外围电路的请求
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值