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;
}
相关推荐
SY师弟5 分钟前
51单片机基础部分——数码管显示
单片机·嵌入式硬件·51单片机
Geometry Fu12 分钟前
物联网控制技术期末复习 知识点总结 第二章 单片机
单片机·嵌入式硬件·物联网·51单片机·期末复习
阿超爱嵌入式25 分钟前
STM32学习之看门狗(理论篇)
stm32·嵌入式硬件·学习
真的想上岸啊31 分钟前
学习STC51单片机27(芯片为STC89C52RCRC)
单片机·嵌入式硬件·学习
壹~1 小时前
详解开漏输出和推挽输出
单片机·嵌入式硬件
czhaii4 小时前
轴承排列自动运行 定时器 外中断 PWM部分程序
嵌入式硬件
暴力求解11 小时前
C语言---动态内存管理、柔性数组
c语言·开发语言·算法
whoarethenext12 小时前
C/C++ OpenCV 矩阵运算
c语言·c++·opencv·矩阵运算
@老蝴12 小时前
C语言 — 动态内存管理
android·c语言·开发语言