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;
}