MPU中断处理

key_init.h

cpp 复制代码
#ifndef __KEY_INIT_H_

#define __KEY_INIT_H_

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

void key_init();

#endif

key_init.c

cpp 复制代码
#include "key_init.h"

void key_init(){
    
    /**
     * key1 引脚 PF9
     * key2 引脚 PF7
     * kry3 引脚 PF8
    */

    //使能PF时钟
    RCC->MP_AHB4ENSETR |= (0X1 << 5);
    //设置引脚模式位输入,00为输入
    GPIOF->MODER &= (~(0X3 << 18)); //key1
    GPIOF->MODER &= (~(0X3 << 14)); //key2
    GPIOF->MODER &= (~(0X3 << 16)); //key3
    
    /**
     * GPIO的外设的组别有A-K组,每一个GPIO组有16个引脚
     * 这16个引脚都有对应的EXIT管理:EXIT0-15
     * EXIT又是由 4 个 EXITCR管理(EXTICR 0-3)
     * EXTICR 0 : EXTI 0-3
     * EXTICR 1 : EXTI 4-7
     * EXTICR 2 : EXTI 8-11
     * EXTICR 3 : EXTI 12-15
     * key1 PE9->EXTI9->EXTICR3
     * key2 PE7->EXTI7->EXTICR2
     * key3 PE8->EXTI8->EXTICR3
     */
    //设置对应引脚得EXTI事件
    //清空
    EXTI->EXTICR3 &= (~(0XFF << 8)); //key1
    EXTI->EXTICR2 &= (~(0XFF << 24));//key2
    EXTI->EXTICR3 &= (~(0XFF << 0)); //key3
    //设置为PF外设触发
    EXTI->EXTICR3 |= (0X5 << 8); //key1
    EXTI->EXTICR2 |= (0X5 << 24);//key2
    EXTI->EXTICR3 |= (0X5 << 0); //key3

    //设置下降沿检测,也就是引脚电平下降时触发
    EXTI->FTSR1 |= (0X1 << 9); //key1
    EXTI->FTSR1 |= (0X1 << 7); //key2
    EXTI->FTSR1 |= (0X1 << 8); //key3

    //取消事件屏蔽
    EXTI->C1IMR1 |= (0X1 << 9); //key1
    EXTI->C1IMR1 |= (0X1 << 7); //key2
    EXTI->C1IMR1 |= (0X1 << 8); //key3

    /**
     * 一共有287个中断事件
     * 每个寄存器有32位,也就是有9个寄存器去管理
     * key1->EXTI9-> 99 -> 99/32=3余3 -> 第 3 个寄存器的第3位
     * key2->EXTI7-> 97 -> 99/32=3余1 -> 第 3 个寄存器的第1位
     * key3->EXTI8-> 98 -> 99/32=3余2 -> 第 3 个寄存器的第2位
     * 
    */
    //全局使能对应中断号
    GICD->ISENABLER[3] |= (0X1 << 3); //key1
    GICD->ISENABLER[3] |= (0X1 << 1); //key2
    GICD->ISENABLER[3] |= (0X1 << 2); //key3

    /** 
     * 一共有287个中断事件
     * 每个中断事件的优先级容量为5位,也就是说只有32个优先级
     * 但是每个寄存器只有32位,还要字节对齐,所以无法容纳足够 5个 中断事件,只能容纳 4个
     * 而且设置的字节偏移了 3 位,所以
     * key1->99-> 99/4=24余3 -> IPRIORITYR 24 的第 3 个
     * key1->97-> 97/4=24余1 -> IPRIORITYR 24 的第 1 个
     * key1->98-> 98/4=24余2 -> IPRIORITYR 24 的第 2 个
     * 将其设置为 0 就是最高优先级
     */
    //设置中断优先级
    GICD->IPRIORITYR[24] &= (~(0X1F << 27)); //key1
    GICD->IPRIORITYR[24] &= (~(0X1F << 11)); //key2
    GICD->IPRIORITYR[24] &= (~(0X1F << 19)); //key3

    /**
     * 一共287个中断事件
     * 每个寄存器只存放了4个事件,每 2 位对应一个事件,字节对齐,其偏移量位0
     * 01:处理器1处理事件
     * 10:处理器2处理事件
     * key1->99-> 99/4=24余3 -> IPRIORITYR 24 的第 3 个
     * key1->97-> 97/4=24余1 -> IPRIORITYR 24 的第 1 个
     * key1->98-> 98/4=24余2 -> IPRIORITYR 24 的第 2 个
     */
    //设置处理中断的处理器
    GICD->ITARGETSR[24] |= (0X1 << 24); //key1
    GICD->ITARGETSR[24] |= (0X1 << 8);  //key2
    GICD->ITARGETSR[24] |= (0X1 << 16); //key3

    //允许中断可以被转发到核0中
    GICD->CTRL |= (0X1 << 0);

    //设置中断的优先级掩码为最低优先级
    //当优先级掩码比中断优先级底时,中断才能转发
    GICC->PMR |= (0X1F << 3);

    //允许优先级掩码中断转发到核0中
    GICC->CTRL |= (0X1 << 0);
}

module.h

cpp 复制代码
#ifndef __MODULE_H_

#define __MODULE_H_

#include "stm32mp1xx_gpio.h"
#include "stm32mp1xx_rcc.h"

typedef enum{
    LED_1,
    LED_2,
    LED_3
}Led_t;

typedef enum{
    CMD_ON,
    CMD_OFF
}Cmd_t;

void module_init();
void module_led_ctrl(Led_t led, Cmd_t cmd);
void module_fan_ctrl(Cmd_t cmd);
void module_motor_ctrl(Cmd_t cmd);
void module_buzzer_ctrl(Cmd_t cmd);


#endif

module.c

cpp 复制代码
#include "module.h"


void module_init(){
    //时钟使能
    RCC->MP_AHB4ENSETR |= (0X1 << 1); //PB
    RCC->MP_AHB4ENSETR |= (0X1 << 4); //PE
    RCC->MP_AHB4ENSETR |= (0X1 << 5); //PF
    //模式选择
    //模式位复位
    GPIOE->MODER &= (~(0X3 << 20)); //LED1
    GPIOF->MODER &= (~(0X3 << 20)); //LED2
    GPIOE->MODER &= (~(0X3 << 16)); //LED3
    GPIOE->MODER &= (~(0X3 << 18)); //FAN
    GPIOF->MODER &= (~(0X3 << 12)); //MOTOR
    GPIOB->MODER &= (~(0X3 << 12)); //BUZZER
    //模式位置位
    GPIOE->MODER |= (0X1 << 20); //LED1
    GPIOF->MODER |= (0X1 << 20); //LED2
    GPIOE->MODER |= (0X1 << 16); //LED3
    GPIOE->MODER |= (0X1 << 18); //FAN
    GPIOF->MODER |= (0X1 << 12); //MOTOR
    GPIOB->MODER |= (0X1 << 12); //BUZZER
    
    //推挽输出设置
    GPIOE->OTYPER &= (~(0X3 << 10)); //LED1
    GPIOF->OTYPER &= (~(0X3 << 10)); //LED2
    GPIOE->OTYPER &= (~(0X3 << 8));  //LED3
    GPIOE->OTYPER &= (~(0X3 << 9));  //FAN
    GPIOF->OTYPER &= (~(0X3 << 6));  //MOTOR
    GPIOB->OTYPER &= (~(0X3 << 6));  //BUZZER

    //低速输出设置    
    GPIOE->OSPEEDR &= (~(0X3 << 20)); //LED1
    GPIOF->OSPEEDR &= (~(0X3 << 20)); //LED2
    GPIOE->OSPEEDR &= (~(0X3 << 16)); //LED3
    GPIOE->OSPEEDR &= (~(0X3 << 18)); //FAN
    GPIOF->OSPEEDR &= (~(0X3 << 12)); //MOTOR
    GPIOB->OSPEEDR &= (~(0X3 << 12)); //BUZZER
    
    //无上下拉电阻设置
    GPIOE->PUPDR &= (~(0X3 << 20)); //LED1
    GPIOF->PUPDR &= (~(0X3 << 20)); //LED2
    GPIOE->PUPDR &= (~(0X3 << 16)); //LED3
    GPIOE->PUPDR &= (~(0X3 << 18)); //FAN
    GPIOF->PUPDR &= (~(0X3 << 12)); //MOTOR
    GPIOB->PUPDR &= (~(0X3 << 12)); //BUZZER
}
//LED灯模组
void module_led_ctrl(Led_t led, Cmd_t cmd){
    switch(led){
        case LED_1:
        if(cmd == CMD_ON){
            GPIOE->ODR |= (0X1 << 10);
        }else if(cmd == CMD_OFF){
            GPIOE->ODR &= (~(0X1 << 10));
        }
        break;
        case LED_2:
        if(cmd == CMD_ON){
            GPIOF->ODR |= (0X1 << 10);
        }else if(cmd == CMD_OFF){
            GPIOF->ODR &= (~(0X1 << 10));
        }
        break;
        case LED_3:
        if(cmd == CMD_ON){
            GPIOE->ODR |= (0X1 << 8);
        }else if(cmd == CMD_OFF){
            GPIOE->ODR &= (~(0X1 << 8));
        }
        break;
    }
}
//风扇模组
void module_fan_ctrl(Cmd_t cmd){
    if(cmd == CMD_ON){
        GPIOE->ODR |= (0X1 << 9);
    }else if(cmd == CMD_OFF){
        GPIOE->ODR &= (~(0X1 << 9));
    }
}
//马达模组
void module_motor_ctrl(Cmd_t cmd){
    if(cmd == CMD_ON){
        GPIOF->ODR |= (0X1 << 6);
    }else if(cmd == CMD_OFF){
        GPIOF->ODR &= (~(0X1 << 6));
    }
}
//蜂鸣器模组
void module_buzzer_ctrl(Cmd_t cmd){
    if(cmd == CMD_ON){
        GPIOB->ODR |= (0X1 << 6);
    }else if(cmd == CMD_OFF){
        GPIOB->ODR &= (~(0X1 << 6));
    }
}

main.c

cpp 复制代码
#include "key_init.h"
#include "module.h"
#include "delay.h"

extern void printf(const char *fmt, ...);
int main()
{

	key_init();
	// key1_init();
	// key2_init();
	// key3_init();

	module_init();
	module_led_ctrl(LED_1, CMD_ON);
	module_led_ctrl(LED_2, CMD_ON);
	module_led_ctrl(LED_3, CMD_ON);
	delay_ms(1000);
	module_led_ctrl(LED_1, CMD_OFF);
	module_led_ctrl(LED_2, CMD_OFF);
	module_led_ctrl(LED_3, CMD_OFF);


	printf("Init\n");

	while (1);
	

	return 0;
}
相关推荐
9稳2 小时前
基于单片机的小功率数控调频发射器设计
数据库·单片机·嵌入式硬件·51单片机
LaoZhangGong1232 小时前
解决“KEIL5软件模拟仿真无法打印浮点数”之问题
经验分享·单片机·嵌入式硬件·float·仿真
犹若故人归2 小时前
计算机网络、嵌入式等常见问题简答
java·网络·嵌入式硬件·计算机网络·intellij-idea
zhangzhangkeji2 小时前
c/c++ 里的进程间通信 , 管道 pipe 编程举例
c语言·c++
2401_843785233 小时前
C语言 扫雷程序设计
c语言·算法
LS_learner3 小时前
Arduino IDE刷微控制器并下载对应固件的原由
嵌入式硬件
xiebingsuccess4 小时前
去耦电容理解:“耦”了什么?非要“去”了?
单片机·嵌入式硬件
就叫飞六吧4 小时前
Keil C51 与 Keil MDK(ARM-stm32?):嵌入式开发的利器
arm开发·stm32·嵌入式硬件
又熟了4 小时前
stm32新建工程
stm32·单片机·嵌入式硬件
毒丐5 小时前
GCC使用说明
linux·c语言·c++