12月26日作业

main.c

#include "uart4.h"
#include "key_int.h"
#include "led.h"

void delay(int ms)
{
    int i,j;
    for(i = 0;i < ms;i++)
    {
        for(j = 0;j < 2000;j++);
    }
}

int main()
{
    //uart4_config();
    all_led_init();
    key1_it_config();
    key2_it_config();
    key3_it_config();
    while(1)
    {
        puts("waiting...\r\n");  
        delay(1000);
    }
}

key_int.c

#include "key_int.h"

void key1_it_config()
{
  //使能GPIOF时钟
  RCC->MP_AHB4ENSETR |= (0x1<<5);
  //设置PF9管脚为输入
  GPIOF->MODER &= (~(0x3<<18));
  //设置PF9作为EXTI9事件的输入
  EXTI->EXTICR3 &= (~(0x1f<<8));
  EXTI->EXTICR3 |= (0x05<<8);
  //设置下降沿使能检测EXTI9事件
  EXTI->FTSR1 |= (0x1<<9); 
  //设置EXIT9事件不屏蔽
  EXTI->C1IMR1 |= (0x1<<9);
  //GICD使能EXTI9(99号)中断
  GICD->ISENABLER[3] |= (0x1<<3);
  //GICD设置99号中断的优先级
  GICD->IPRIORITYR[24] &= (~(0x1f<<27));
  //选择器CPU0处理当前中断
  GICD->ITARGETSR[24] |= (0x1<<24);
  //全局使能组0中断被转发到GICC
  GICD->CTRL |= (0x1);
  //设置中断的优先级掩码
  GICC->PMR |= (0x1f<<3);
  //允许组0中断被CPU处理
  GICC->CTRL |= (0x1);
}
void key2_it_config()
{
  //使能GPIOF时钟
 //RCC->MP_AHB4ENSETR |= (0x1<<5);
  //设置PF7管脚为输入
  GPIOF->MODER &= (~(0x3<<14));
  //设置PF7作为EXTI7事件的输入
  EXTI->EXTICR2 &= (~(0x1f<<24));
  EXTI->EXTICR2 |= (0x05<<24);
  //设置下降沿使能检测EXTI7事件
  EXTI->FTSR1 |= (0x1<<7); 
  //设置EXIT7事件不屏蔽
  EXTI->C1IMR1 |= (0x1<<7);
  //GICD使能EXTI7(97号)中断
  GICD->ISENABLER[3] |= (0x1<<1);
  //GICD设置97号中断的优先级
  GICD->IPRIORITYR[24] &= (~(0x1f<<11));
  //选择器CPU0处理当前中断
  GICD->ITARGETSR[24] |= (0x1<<8);
  //全局使能组0中断被转发到GICC
  GICD->CTRL |= (0x1);
  //设置中断的优先级掩码
  GICC->PMR |= (0x1f<<3);
  //允许组0中断被CPU处理
  GICC->CTRL |= (0x1);
}
void key3_it_config()
{
  //使能GPIOF时钟
  //RCC->MP_AHB4ENSETR |= (0x1<<5);
  //设置PF8管脚为输入
  GPIOF->MODER &= (~(0x3<<16));
  //设置PF8作为EXTI8事件的输入
  EXTI->EXTICR3 &= (~(0x1f));
  EXTI->EXTICR3 |= (0x05);
  //设置下降沿使能检测EXTI8事件
  EXTI->FTSR1 |= (0x1<<8); 
  //设置EXIT8事件不屏蔽
  EXTI->C1IMR1 |= (0x1<<8);
  //GICD使能EXTI8(98号)中断
  GICD->ISENABLER[3] |= (0x1<<2);
  //GICD设置98号中断的优先级
  GICD->IPRIORITYR[24] &= (~(0x1f<<19));
  //选择器CPU0处理当前中断
  GICD->ITARGETSR[24] |= (0x1<<16);
  //全局使能组0中断被转发到GICC
  GICD->CTRL |= (0x1);
  //设置中断的优先级掩码
  GICC->PMR |= (0x1f<<3);
  //允许组0中断被CPU处理
  GICC->CTRL |= (0x1);
}

key_int.h

#ifndef __KEY_IT_H__
#define __KEY_IT_H__

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

void key1_it_config();
void key2_it_config();
void key3_it_config();

#endif

do_irq.c

#include "key_int.h"
#include "led.h"
#include "uart4.h"
extern void printf(const char *fmt, ...);
unsigned int i = 0;
void do_irq(void) 
{
  int irqno = (GICC->IAR & 0x3ff);

  switch (irqno)
  {
  case 99: //key1
    led1_on();
    //GPIOE->ODR |= (0x1<<10);
    puts("led1_on\r\n");  
    //清除GICD的中断排队标志
    GICD->ICPENDR[3] |= (0x1<<3);
    //清除exti的事件触发标志
    EXTI->FPR1 |= (0x1<<9);
    break;
  case 97: //key2
    led2_on();
    puts("led2_on\r\n");  
    //清除GICD的中断排队标志
    GICD->ICPENDR[3] |= (0x1<<1);
    //清除exti的事件触发标志
    EXTI->FPR1 |= (0x1<<7);
    break;
  case 98: //key3
    led1_off();
    led2_off();
    puts("led1_off\r\n");  
    puts("led2_off\r\n");  
    //清除GICD的中断排队标志
    GICD->ICPENDR[3] |= (0x1<<2);
    //清除exti的事件触发标志
    EXTI->FPR1 |= (0x1<<8);
    break;  
  }
  //清除中断号
  GICC->EOIR = irqno;
}

led.c

#include "led.h"
void all_led_init()
{
    RCC_GPIO_LED |= (0X3<<4);//时钟使能
    GPIOE_LED->moder &=(~(0X3<<20));//设置PE10输出
    GPIOE_LED->moder |= (0X1<<20);
    //设置PE10为推挽输出
    GPIOE_LED->otyper &=(~(0x1<<10));
    //PE10为低速输出
    GPIOE_LED->ospeedr &= (~(0x3<<20));
    //设置无上拉下拉
    GPIOE_LED->pupdr &= (~(0x3<<20));

    //LED2
    GPIOF_LED->moder &=(~(0X3<<20));//设置Pf10输出
    GPIOF_LED->moder |= (0X1<<20);
    //设置Pf10为推挽输出
    GPIOF_LED->otyper &=(~(0x1<<10));
    //Pf10为低速输出
    GPIOF_LED->ospeedr &= (~(0x3<<20));
    //设置无上拉下拉
    GPIOF_LED->pupdr &= (~(0x3<<20));

    //LED3
    GPIOE_LED->moder &=(~(0X3<<16));//设置PE8输出
    GPIOE_LED->moder |= (0X1<<16);
    //设置PE8为推挽输出
    GPIOE_LED->otyper &=(~(0x1<<8));
    //PE8为低速输出
    GPIOE_LED->ospeedr &= (~(0x3<16));
    //设置无上拉下拉
    GPIOE_LED->pupdr &= (~(0x3<<16));
}
void led1_on()
{
    GPIOE_LED->odr |= (0x1<<10);
}

void led1_off()
{
    GPIOE_LED->odr &= (~(0x1<<10));
}
void led2_on()
{
    GPIOF_LED->odr |= (0x1<<10);
}

void led2_off()
{
    GPIOF_LED->odr &= (~(0x1<<10));
}
void led3_on()
{
    GPIOE_LED->odr |= (0x1<<8);
}

void led3_off()
{
    GPIOE_LED->odr &= (~(0x1<<8));
    
}

led.h

#ifndef __LED_H__
#define __LED_H__

typedef struct{
    unsigned int moder;
    unsigned int otyper;
    unsigned int ospeedr;
    unsigned int pupdr;
    unsigned int idr;
    unsigned int  odr;
    unsigned int bsrr;
}gpio_ttt;
#define GPIOE_LED ((gpio_ttt*)0X50006000)
#define GPIOF_LED ((gpio_ttt*)0X50007000)
#define RCC_GPIO_LED (*(unsigned int*)0x50000a28)


void all_led_init();
void led1_on();
void led1_off();
void led2_on();
void led2_off();
void led3_on();
void led3_off();

#endif

效果演示