ARM day9 (按键中断控制led亮灭)

这篇具有很好参考价值的文章主要介绍了ARM day9 (按键中断控制led亮灭)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 保存现场

异常的处理流程,保存现场会做哪些事情(四大步三小步) ---->CPU自动完成

1.保存CPSR寄存器中的值,到SPSR_<mode>寄存器中

2.修改CPSR寄存器对应的位

        1>修改CPSR寄存器对应的状态位(T位)

        2>根据需要,禁止相应中断位(I位 / F位)

        3>修改CPSR寄存器的模式位,修改为对应的异常模式

3.保存函数的返回地址到LR寄存器中

4.修改PC指针指向对应的异常向量表

恢复现场

1.恢复SPSR_<mode>寄存器中的值给到CPSR寄存器中

2.恢复LR寄存器中的值给到PC

ARM day9 (按键中断控制led亮灭),ARM,arm开发,单片机,嵌入式硬件 

 

key.h

#ifndef __KEY_H__
#define __KEY_H__

#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"
#include "stm32mp1xx_uart.h"
#include "stm32mp1xx_exti.h"
#include "stm32mp1xx_gic.h"


//事件号
#define EXTI_7 7
#define EXTI_8 8
#define EXTI_9 9

//中断号
#define EXTI7 97
#define EXTI8 98
#define EXTI9 99

//key_exit初始化
void hal_key_exti_init(volatile unsigned int exti,gpio_t* gpiox,volatile unsigned int* style);

//key_gic初始化
void hal_key_gic_init(unsigned int extid);

/********LED*章节*********/
//寄存器的模型
typedef enum{
	INPUT,  	//输入 0
	OUTPUT,   	//输出 1 
	ALT, 		//2
	ANALOG, 	//3
}gpio_moder_t;
//寄存器输出类型
typedef enum{
	PP, 	//推挽 0
	OD, 	//开漏 1
}gpio_otyper_t;
//寄存器数据输出速率
typedef enum{
	LOW, 	//低速 00
	MED, 	//中速 01
	HIGH, 	//高速 10
	HIGHEST,//超高速 11
}gpio_ospeedr_t;
//上下拉电阻寄存器
typedef enum{
	NO_PUPDR, 	//禁止 0
	PU,  		//上拉 1
	PD, 		//下拉 2
}gpio_pupdr_t;

//高低电平
typedef enum{
	GPIO_RESET_T,  	//低电平 0
	GPIO_SET_T, 	//高电平 1
}gpio_odr_t;

typedef struct{
	gpio_moder_t moder; 	//引脚模式
	gpio_otyper_t otyper; 	//输出类型
	gpio_ospeedr_t ospeedr; //输出速度
	gpio_pupdr_t pupdr; 	//是否上下拉
}gpio_init_t;


//LED_GPIO初始化
void hal_led_gpio_init(gpio_t* gpiox,unsigned int pin,gpio_init_t* init);

//LED_操作
void operate_led(gpio_t* gpiox,unsigned int pin);

//LED_ON
void turn_on(gpio_t* gpiox,unsigned int pin);

//LED_OFF
void turn_off(gpio_t* gpiox,unsigned int pin);

#endif

key.c

#include "key.h"
extern void delay_ms(int ms);

//key_exit初始化
void hal_key_exti_init(unsigned int exti,gpio_t* gpiox,volatile unsigned int* style)
{
	//   RCC章节初始化
	//  1.GPIO使能
	//
	//unsigned int a = (unsigned int)(gpiox - GPIOA)/256;

	RCC->MP_AHB4ENSETR |= (0x1 << 5);

	//    GPIO章节初始化GPIOF_MODER
	gpiox->MODER &= (~(0x3 << exti*2));

	//   EXTI章节初始化 
	//2.设置EXTI选择寄存器 EXTI_EXITCRx
	*(&(EXTI->EXTICR1) + (exti/4)) &= (~(0xff << (exti%4)*8)); 
	*(&(EXTI->EXTICR1) + (exti/4)) |= (5 << (exti%4)*8);
	/*	

		switch(exti/4)
		{
		case 1:
		EXTI->EXTICR2 &= (~(0xff << (exti%4)*8));
		EXTI->EXTICR2 |= (0x5 << (exti%4)*8);
		break;
		case 2:
		EXTI->EXTICR3 &= (~(0xff << (exti%4)*8));
		EXTI->EXTICR3 |= (0x5 << (exti%4)*8);
		break;
		case 3:
		EXTI->EXTICR4 &= (~(0xff << (exti%4)*8));
		EXTI->EXTICR4 |= (0x5 << (exti%4)*8);
		break;
		}
		*/
	//2.设置中断通信为下降沿触发EXTI_FTSR1
	*style |= (0x1 << exti);

	//3.设置中断不屏蔽EXTI_C1IMR1
	EXTI->C1IMR1 |= (0x1 << exti);
}

//key_gic初始化
void hal_key_gic_init(unsigned int extid)
{

	//       GICD章节初始化
	//1.设置GICD层组控制器使能
	GICD->CTRL |= 0x1;

	//2.设置GICD层中断设置使能寄存器
	GICD->ISENABLER[extid/32] |= (0x1 << extid%32);

	//3.设置GICD层中断优先级寄存器
	GICD->IPRIORITYR[extid/4] &= (~(0x1f << ((extid%4)*8+3)));

	//4.设置GICD层中断目标分配寄存器
	GICD->ITARGETSR[extid/4] &= (~(0x3 << (extid%4)*8));
	GICD->ITARGETSR[extid/4] |= (0x1 << (extid%4)*8);

	//       GICC章节初始化
	//1.设置GICC层控制使能寄存器
	GICC->CTRL |= (0x1 << 0);

	//2.设置GICC层中断优先级寄存器
	GICC->PMR |= (0x1f << 3);

}




/********LED*章节*********/
//LED_GPIO初始化
void hal_led_gpio_init(gpio_t* gpiox,unsigned int pin,gpio_init_t* init)
{
	// moder; 	//引脚模式
	gpiox->MODER &= (~(0x3  << pin*2));
	gpiox->MODER |= (init->moder << pin*2);

	// otyper; 	//输出类型
	gpiox->OTYPER &= (~(0x1 << pin));
	gpiox->OTYPER |= (init->otyper << pin);


	// ospeedr; //输出速度
	gpiox->OSPEEDR &= (~(0x3 << pin));
	gpiox->OSPEEDR |= (init->ospeedr << pin*2 );


	// pupdr; 	//是否上下拉
	gpiox->PUPDR &= (~(0x3 << pin*2));
	gpiox->PUPDR |= (init->pupdr << pin*2);

}

//LED_操作
void operate_led(gpio_t* gpiox,unsigned int pin)
{
	if((gpiox->ODR & (0x1 << pin)) == 0)
	{
		turn_on(gpiox,pin);
	}
	else
	{
		turn_off(gpiox,pin);
	}
}

//LED_ON
void turn_on(gpio_t* gpiox,unsigned int pin)
{
	gpiox->ODR |= (0x1 << pin);
}

//LED_OFF
void turn_off(gpio_t* gpiox,unsigned int pin)
{
	gpiox->ODR &= (~(0x1 << pin));
}



do_irq.c

#include "key.h"

extern void printf(const char *fmt, ...);
void do_irq(void) 
{
	unsigned int num;
	//获取中断号 IAR[9:0]
	num = GICC->IAR & (0x3ff);

	//判断中断号
	//99--->KEY1
	//98--->KEY3
	//97--->KEY2

	switch(num)
	{
	case 97:
		printf("key2 pressed!!!!!!\n");
		//LED2
		operate_led(GPIOF,10);
		//1.消除EXTI层中断挂起标志位 FPR1 [9] = 1
		EXTI->FPR1 |= (0x1 << 7);
		//2.消除GICD层中断挂起标志位 ICPENDR[3] |= (0x1 << 3) 
		GICD->ICPENDR[num/32] |= (0x1 << (num%32));
		break;
	case 98:
		printf("key3 pressed!!!!!!\n");
		//LED1
		operate_led(GPIOE,10);
		//1.消除EXTI层中断挂起标志位 FPR1 [9] = 1
		EXTI->FPR1 |= (0x1 << 8);
		//2.消除GICD层中断挂起标志位 ICPENDR[3] |= (0x1 << 3) 
		GICD->ICPENDR[num/32] |= (0x1 << (num%32));
		break;
	case 99:
		printf("key1 pressed!!!!!!\n");
		//LED3
		operate_led(GPIOE,8);
		//1.消除EXTI层中断挂起标志位 FPR1 [9] = 1
		EXTI->FPR1 |= (0x1 << 9);
		//2.消除GICD层中断挂起标志位 ICPENDR[3] |= (0x1 << 3) 
		GICD->ICPENDR[num/32] |= (0x1 << (num%32));
		break;
	}
	//3.消除GICC层挂起标志位
	GICC->EOIR = num;

}


main.c

#include "key.h"

extern void printf(const char *fmt, ...);
void delay_ms(int ms)
{
	int i,j;
	for(i = 0; i < ms;i++)
		for (j = 0; j < 1800; j++);
}

void hal_exti_init()
{
	hal_key_exti_init(EXTI_7,GPIOF,&EXTI->FTSR1);
	hal_key_exti_init(EXTI_8,GPIOF,&EXTI->FTSR1);
	hal_key_exti_init(EXTI_9,GPIOF,&EXTI->FTSR1);
}

void hal_gic_init()
{
	hal_key_gic_init(EXTI7);
	hal_key_gic_init(EXTI8);
	hal_key_gic_init(EXTI9);
}
void hal_led_init()
{
	//RCC使能
	RCC->MP_AHB4ENSETR |= (0x3 << 4);
	//设定init
	gpio_init_t init = {OUTPUT,PP,LOW,NO_PUPDR};

	//LED1 PE10
	hal_led_gpio_init(GPIOE,10,&init);
	//LED2 PF10
	hal_led_gpio_init(GPIOF,10,&init);
	//LED3 PE8
	hal_led_gpio_init(GPIOE,8,&init);
}

int main()
{
	//exti初始化
	hal_exti_init();

	//gic初始化
	hal_gic_init();

	//led初始化
	hal_led_init();

	hal_put_string("KEY TEXT READY\n");
	while(1){}
	return 0;
}

ARM day9 (按键中断控制led亮灭),ARM,arm开发,单片机,嵌入式硬件

ARM day9 (按键中断控制led亮灭),ARM,arm开发,单片机,嵌入式硬件文章来源地址https://www.toymoban.com/news/detail-537159.html

到了这里,关于ARM day9 (按键中断控制led亮灭)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ARM_day7:按键中断

    实现三个按键中断,按键按下时,LED灯亮  mykey.h mykey.c main.c do_irq.c  

    2024年04月22日
    浏览(31)
  • ARM按键中断控制事件

    main.c

    2024年02月08日
    浏览(30)
  • 51单片机按键控制LED亮灭

    通过单片机按键控制LED亮灭与传统电路的物理逻辑不同,在物理逻辑中开关控制电路的通断来控制LED的亮灭,而通过单片机完成该项目至于要不断地读取按键所连接IO口的电平来判断对LED连接的IO口输出的电平即可。 原理图如下:  根据原理图,我们可以发现按键按下时P2.1口

    2023年04月18日
    浏览(49)
  • STM32之通过按键控制LED灯亮灭

    之前我们已经实现了LED灯的亮灭,我们对LED灯的结构应该有一个大致的了解。接下来我们对按键控制led进行学习。 首先我们要了解一下按键的结构。按键结构如图。  由此可知,此处我们有两种按键,一种是普通的按键KEY0, KEY1(KEY2),他们连接的串口分别是PE4, PE3(PE2),对应

    2024年02月08日
    浏览(50)
  • arm:day9

    1。思维导图  2..I2C实验,检测温度和湿度 iic.h si7006.h iic.c si7006.c main.c  

    2024年02月10日
    浏览(42)
  • ARM开发,stm32mp157a-A7核中断实验(实现按键中断功能)

    ---key.h头文件--- ---key.c函数实现--- ---do_irq.c终端处理函数--- ---main.c测试文件---

    2024年02月11日
    浏览(41)
  • ARM_day9 按钮控制LED灯、蜂鸣器、风扇实验

    key.h key.c   do_irq.c main.c  

    2024年02月07日
    浏览(43)
  • 【STM32】按键控制LED亮灭实验——GPIO、LED、KEY、SYS

    无锁存时:当按下独立按钮时LED亮,松开LED灭。 锁存时:当按下独立按钮时LED亮,松开LED仍亮,再按下独立按钮时LED熄灭。 硬件部分 软件部分 1、引入头文件 2、主函数 首先时钟、led、按键初始化 锁存时:当按下独立按钮时LED亮,松开LED仍亮,再按下独立按钮时LED熄灭。常

    2024年02月08日
    浏览(95)
  • 设计分享|单片机独立按键控制4个LED灯亮灭

    目录 具体实现功能 设计介绍 51单片机简介 设计思路 设计内容 仿真图(protues8.7) 程序(Keil5) 具体实现功能 单片机四个按键分别控制四个LED的亮灭! 设计介绍 51单片机简介 51单片是一种低功耗、高性能CMOS-8位微控制器,具有8K可编程Flash存储器,使得其为众多嵌入式控制应

    2024年02月06日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包