从零开始学习stm32(三)

从零开始学习stm32(三)

思考:如何实现以下功能?

  • 串口回显
  • LED循环闪烁(间隔1秒)
  • 任务1与任务2不会互相干扰

中断

​ 系统停止当前正在运行的程序转到其他服务,可能是程序接受了比自身优先级高的请求,或者是人为设置中断,中断时属于正常现象。

硬中断

​ 由硬件产生

软件中断

​ 软中断是由当前正在运行的进程所产生。

中断处理过程

  • 当异常中断发生时,系统处理完当前指令后,将跳转到相应的异常中断程序处执行。
  • 异常中断程序处理完成后,程序返回到发生中断指令的下一条指令处执行。
  • 进入异常中断时,要保存呗中断的程序执行现场,在从异常中断处理程序退出时,要恢复被中断的程序的执行现场。

EXTI基本概念

中断产生的根本原因

​ 单片机系统正在运行时,往往时一个单纯的封闭系统。但有些时候需要外部干预,因此可通过中断的方式进行。

中断和事件

​ ** 中断时软件级,stm32中断线路产生的输入信号到NVIC,在执行中断服务函数。

​ ** 事件时硬件级的,stm32事件线产生后回传输一个脉冲信号给其他外设使用。

​ 事件机制提供了一个完全由硬件自动完成触发到产生结果的通道,不需要软件参与,降低了CPU负荷,节省了中断资源,提高了相应速度,是利用硬件来提升CPU芯片处理事件能力的一个有效方法。

​ ** 中断相应函数

  • 一种处理中断相应的函数,遵行特定原型声明的c函数,运行在中断上下文。

  • 中断处理函数不能被阻塞,其内部的程序必须运行非常快

  • 告诉硬件已经收到了它发出的中断,中断服务程序通常分为两半,上半部:只执行哪些可以很快执行的代码,如向硬件确认已收到中断号等。下半部:执行中断触发需要完成的其他工作

  • 执行在中断上下文中的代码注意事项,中断上下文的代码不能进入休眠,中断处理程序应该尽快结束

    中断原理

    外部信号从输入线管脚进入。

    经过边沿检测电路

    通过或门中断挂起请求寄存器,如果中断屏蔽寄存器对应位为0,则该请求信号不能传输到与门另一端,实现中断屏蔽

    第三节

    NVIC基本概念

    内嵌向量中断控制器--------与内核紧密相连,内核外设

    中断优先级

    ​ 包括两个优先级:抢占优先级和子优先级

    ​ 所有的优先级可编程的中断源都需要指定这两种优先级。

    ​ 抢占优先级:决定是否可以产生中断嵌套

    ​ 子优先级:决定中断响应顺序

    ​ 若两种优先级一样,则看中断源在中断向量表中的偏移量,偏移量小的先响应。

    NVIC寄存器

    • NVIC_ISERx/NVIC_ICERx 中断使能(设置/清除)寄存器
    • NVIC_ISPRx /NVIC_ICPRx中断挂起设置/清除寄存器
    • NVIC_IABRx 激活位寄存器
    • NVIC_IPRx 中断优先级寄存器
    • NVIC_STIR 软件触发中断寄存器
外部中断思路
  • 根据原理图确定相应的外部中断信号线
  • 配置外部中断
    • 选择EXTI的信号源
    • 选择EXTI类型:中断、事件
    • 选择EXTI的触发模式:上升沿、下降沿
    • EXTI使能

代码

头文件

//key.h
typedef enum{
	PRESS,RESS
}KEY_orp;

typedef enum {
	CHECK,INTERRUPT
}MODE;

#define KEY_MODE INTERRUPT
 
extern void key_exit_init(void);
extern void key_nvic_init(void);
extern void KEY_Init(MODE mode);
extern void delay_us(u8 time);
extern u8 key_read(void);
extern u8 flag;

c文件

//key.c
#include<stm32f10x_rcc.h>
#include<stm32f10x_gpio.h>
#include<stm32f10x_rcc.h>
#include<stm32f10x_exti.h>
#include<misc.h>
#include<key.h>
//PB12,KEY高电平有效
//当按键不被按下的时候,它一直稳定在低电平--下拉
void delay_us(u8 time){
	while(time--){
		int i = 1000;
		while(i--);
	}
}


void key_exit_init(void){
    EXTI_InitTypeDef KEY_exit;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource12);
    KEY_exit.EXTI_Line = EXTI_Line12;
    KEY_exit.EXTI_Mode = EXTI_Mode_Interrupt;
    KEY_exit.EXTI_Trigger = EXTI_Trigger_Rising;
    KEY_exit.EXTI_LineCmd = ENABLE;

    EXTI_Init(&KEY_exit);
}

void key_nvic_init(void){
    NVIC_InitTypeDef key_nvic;
    key_nvic.NVIC_IRQChannel = EXTI15_10_IRQn;
    key_nvic.NVIC_IRQChannelSubPriority = 0;
    key_nvic.NVIC_IRQChannelPreemptionPriority = 1;
    key_nvic.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&key_nvic);
}



void KEY_Init(MODE mode){
    GPIO_InitTypeDef KEY;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    //结构体初始化
    KEY.GPIO_Mode = GPIO_Mode_IPD;
    KEY.GPIO_Pin = GPIO_Pin_12;
    //GPIO初始化
    GPIO_Init(GPIOB, &KEY);
		
		if (INTERRUPT == mode){
				key_exit_init();
				key_nvic_init();
		}else{}

}


//读取按键
u8 key_read(void){
		u8 result = 0;
		delay_us(10);
		result = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12);
		//按键去抖
		if (result == PRESS){
			return 0;
		}else{
			 return 1;
		}
}
u8 flag = 0;
void EXTI15_10_IRQHandler(void){
    if (SET == EXTI_GetITStatus(EXTI_Line12)){
        flag = !flag;
    }
		EXTI_ClearITPendingBit(EXTI_Line12);
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花甲09

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值