cortex - A7核中断实验——基于STM32MP157A
一:按鍵中斷原理
異常中斷處理流程
分為保存現場和恢復現場兩部分
1:保存現場
? ? ? ? CPSR寄存器:當前程序狀態寄存器
? ? ? ? 此步驟由電腦自動完成,分為四大步三小步
? ? ? ? 1:保存CPSR寄存器中的值到SPSR_<mode>寄存器中(mode為對應的異常模式寄存器)
? ? ? ? 2:修改CPSR寄存器中的值
? ? ? ? ? ? ? ? 1> 修改CPSR寄存器的T位(狀態位),修改為ARM狀態
? ? ? ? ? ? ? ? 2> 根據需要,禁止相應的中斷位 I位/F位(分別對應IRQ、FIQ)
? ? ? ? ? ? ? ? 3> 修改CPSR寄存器的模式位,切換到對應的異常模式
? ? ? ? 3:保存函數返回地址到LR_<mode>寄存器中
? ? ? ? 4:PC指針指向異常向量表
CPSR寄存器部分位功能圖
T[5]:狀態位T=0:ARM狀態,執行arm指令集T=1:thumb狀態,執行thumb指令集 M[4:0]:模式位10000 User mode; 10001 FIQ mode; 10011 SVC mode;10111 Abort mode; 11011 Undef mode; 11111 System mode; 10110 Monitor mode; 10010 IRQ mode;?2:恢復現場
? ? ? ? 1:把SPSR_<mode>寄存器中值重新給到CPSR寄存器中
? ? ? ? 2:LR_<mode>寄存器中的值重新給PC寄存器
?
分析電路圖
?再去主板上找它們是什么引腳,以KEY1為例
KEY1為 PF9引腳,所以是GPIO控制器
至此我們可以確定,我們需要的是:
????????GIC控制器:通用的全局中斷控制器
? ? ? ? EXTI控制器:外部中斷事件控制器
? ? ? ? GPIO控制器:輸入輸出控制器,控制引腳
1.通過框圖分析可知:RCC章節/GPIOF章節/EXTI章節/GIC章節
2.需要分析GPIOF章節:設置引腳為輸入模式
3.需要分析EXTI章節:檢測中斷的觸發方式
4.需要分析GIC章節:設置GPIOF引腳對應的中斷號
二:分析芯片手冊
1.RCC章節分析
尋找對應總線
略過前幾篇文章做一次找一次的GPIOF,它在AHB4總線
EXTI也在AHB4總線(下面還能看到GPIOF)
?GIC中斷控制器在CA7總線
?
?意味著,該控制器(GIC、EXTI)系統會自動使能,不需要我們通過RCC手動使能
查找RCC_MP_AHB4ENSETR
0x50000A28地址的第5位置1,設置GPIOF控制器使能 RCC_MP_AHB4ENSETR[5] = 1 -------->設置GPIOF控制器使能工作2.GPIO章節分析
這次GPIO章節比較簡單,只需要設置為輸入模式即可
GPIOF_MODER[19:18] = 00------>KEY1輸入模式3.EXTI章節分析
?
?
?由該圖知,PF9引腳對應的控制器為:EXTI_EXTICR1.EXTI9
1)EXTI_EXTICR3寄存器
EXTI_EXTICRn寄存器每8位管理一個EXTI,一個寄存器32位,最多管理4個EXTI
因為KEY1引腳為PF9,所以,EXTICR寄存器編號為3(范圍為8~11引腳)
?
分析可知: key1------>PF9------>EXTI9--->9 / 4 = 2.....1--->EXTI_EXTICR3[15:8] = 0x05由此(尋找過程)得出公式 EXTI編號 / 4 = 商 ...... 余數 商+1 :對應的哪一個寄存器 余數*8:對應寄存器8位中的最低位2)EXTI_FTSR1寄存器
?
key1------>PF9------>EXTI9--->對應事件9--->EXTI_FTSR1[9] = 0x1EXTI_IMR1寄存器
key1------>PF9------>EXTI9--->對應事件9--->EXTI_IMR1[9] = 0x1--->中斷不屏蔽?EXTI_FPR1寄存器
rc_w1: rc--->可讀 w1--->寫1清除中斷掛起標志位 讀0:中斷沒有發生 讀1:中斷發生 寫0:表示沒有清除中斷掛起標志位 寫1:表示清除中斷掛起標志位所以: key1------>PF9------>EXTI9--->對應事件9--->EXTI_FPR1[9] = 0x1--->清除中斷掛起標志位4:GICD章節
GIC控制器分為GICC與GICD兩個
?
Software generated interrupts (SGI):軟件中斷號(ID:0~15) Private peripheral interrupts (PPI):私有的外設中斷號(ID:16~31) Shared peripheral interrupts (SPI):共享外設中斷號(ID:32~287)GICD_CTLR寄存器(GICD控制寄存器)
設置GICD層CPU0組使能 GICD_CTLR[0] = 1GICD_ISENABLERx寄存器(中斷使能寄存器)
GIC層一共管理288個中斷號(16個SGI,16個PPI,256個SPI) GICD_ISENABLERx每一位管理一個中斷號,所以一個寄存器最多管理32個中斷號 要想管理288個中斷號,需要 288 / 32 = 9個這樣的寄存器 key1------>PF9------>EXTI9--->對應事件9--->中斷號99--->GICD_ISENABLER3[3] = 1因此判斷,計算公式為: 中斷號 / 32 = 商 ...... 余數 商:中斷號對應要操作的寄存器 余數:中斷號對應操作寄存器的位數GICD_IPRIORITYRx寄存器(中斷優先級設置寄存器)
公式: 中斷號 / 4 = 商 ...... 余數商:中斷號對應要操作的寄存器余數*8+3:中斷號對應操作寄存器的位數 key1------>PF9------>EXTI9---> 對應事件9--->中斷號99---> 99 / 4 = 24 .... 3--->GICD_IPRIORITYR24[31:27]GICD_ITARGETSRx寄存器(中斷處理目標寄存器)
公式: 中斷號 / 4 = 商 ...... 余數 商:中斷號對應要操作的寄存器 余數*8:中斷號對應操作寄存器的位數 key1------>PF9------>EXTI9---> 對應事件9--->中斷號99---> 99 / 4 = 24 .... 3--->GGICD_ITARGETSR24[25:24] = 0bx10bx1----->分配給CPU0 0b1x----->分配給CPU1 0b11----->分配給CPU0和CPU1GICD_ICPENDRx寄存器(中斷清除掛起寄存器)
公式: 中斷號 / 32 = 商 ...... 余數 商:中斷號對應要操作的寄存器 余數:中斷號對應操作寄存器的位數key1------>PF9------>EXTI9---> 對應事件9--->中斷號99---> 99 / 32 = 3 .... 3--->GICD_ICPENDR3[3] = 1?5.GICC章節
GICC_CTLR寄存器(GICC控制寄存器)
CTRL[0] = 1 cpu組0使能GICC_PMR寄存器(中斷優先級設置寄存器)
該寄存器的值隨意設置,只需要比GICD層設計的中斷優先級的值要大(GICD_IPRIORITYRx)GICC_EOIR寄存器(GICC中斷結束寄存器)
GICC_EOIR作用:清除中斷號 GICC_EOIR[9:0]:清除按鍵的中斷號?三:代碼實現
直接根據前文分析出來的內容,填寫代碼即可,頭文件內采用現成的庫、
key.c文件
RCC與EXTI初始化
//初始化EXTI層 void pf9_exti_init() {/***********RCC初始化**************///使能GPIOFRCC->MP_AHB4ENSETR = (0x1 << 5);/*****GPIO章節初始化*****///設置PF9引腳為輸入模式//GPIOF_MODER[19:18] = 0b00GPIOF->MODER &= (~(0x3 << 18));/*******EXTI章節初始化********///1.設置PF9引腳和EXTI9控制器進行鏈接//EXIT_EXTICR3[15:8] = 0x05EXTI->EXTICR3 &= (~(0xff << 8)); //清零EXTI->EXTICR3 |= (0x05 << 8); //置1//2.設置PF9引腳檢測方式為下降沿//EXTI_FTSR1[9] = 0x01EXTI->FTSR1 |= (0x1 << 9);//3.設置PF9引腳中斷不屏蔽//EXTI_IMR1[9] = 0x01EXTI->C1IMR1 |= (0x01 << 9); }GICD初始化
//初始化GICD層 void pf9_gicd_init() {//設置GICD層全局中斷使能寄存器GICD->CTRL |= (0X01 << 0);//設置GICD層中斷使能寄存器//EXTI9-->99號-->GICD_ISENABLER[3][3] = 1GICD->ISENABLER[3] |= (0x1 << 3);//設置GICD層中斷優先級寄存器//99號中斷-->GICD_IPRIORITYR24[31:27] = 10 //數字隨意GICD->IPRIORITYR[24] &= (~(0x1F << 27)); //清零GICD->IPRIORITYR[24] |= (0x1 << 27);//設置GICD層中斷目標分配器//99號中斷 --> 99/4 = 24....3 --> GICD_ITARGETSR24[25:24] = 0bx1(x代表0、1任意值)GICD->ITARGETSR[24] &= (~(0x3 << 24));GICD->ITARGETSR[24] |= (0x1 << 24); }GICC初始化
//初始化GICC void pf9_gicc_init() {//設置GICC層全局中斷使能寄存器GICC->CTRL |= (0x1 << 0);//設置GICC層中斷優先級寄存器GICC->PMR &= (~(0x1F << 3));GICC->PMR |= (0xF << 3); //優先級設置為15 }為了初始化方便,整合到一起
//包裹pf9 void PF9_init() {pf9_exti_init();pf9_gicd_init();pf9_gicc_init(); }還要編寫中斷文件
do_irq.c文件
#include "key.h"extern void delay_ms(int ms);extern void printf(const char *fmt, ...);//unsigned int i = 0; void do_irq(void) {unsigned int num = 0;//獲取中斷信號num = GICC->IAR;switch(num){ /* 此處為省略的key2與key3的中斷事件case 97: delay_ms(500); //防按鍵抖動printf("key2######\n");//清除EXTI中斷掛起標志位EXTI->FPR1 |= (0x1 << 7);//清除GICD層中斷掛起標志位//key1-->PF9-->EXTI9-->事件9-->中斷號99//97 / 32 = 3...1GICD->ICPENDR[3] |= (0x1 << 1);break;case 98: delay_ms(500); //防按鍵抖動printf("key3######\n");//清除EXTI中斷掛起標志位EXTI->FPR1 |= (0x1 << 8);//清除GICD層中斷掛起標志位//key1-->PF9-->EXTI9-->事件9-->中斷號99//98 / 32 = 3...2GICD->ICPENDR[3] |= (0x1 << 2);break; */case 99:delay_ms(500); //防按鍵抖動printf("key1######\n");//清除EXTI中斷掛起標志位EXTI->FPR1 |= (0x1 << 9);//清除GICD層中斷掛起標志位//key1-->PF9-->EXTI9-->事件9-->中斷號99//99 / 32 = 3...3GICD->ICPENDR[3] |= (0x1 << 3);break;}//清除中斷信號GICC->EOIR &= (~(0x3FF << 0));GICC->EOIR |= num; }key.h文件
#ifndef __KEY_H__ #define __KEY_H__#include "stm32mp1xx_gpio.h" #include "stm32mp1xx_exti.h" #include "stm32mp1xx_rcc.h" #include "stm32mp1xx_gic.h"//初始化 /******KEY1----->PF9******/ //初始化EXTI層 void pf9_exti_init();//初始化GICD層 void pf9_gicd_init();//初始化GICC層 void pf9_gicc_init();//包裹pf9 void PF9_init();//此處本還有key2、key3的初始化,此處略 #endif實驗運行效果:
當按下開發板的對應按鈕后,會在串口界面輸出對應的按鍵號
?
總結
以上是生活随笔為你收集整理的cortex - A7核中断实验——基于STM32MP157A的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [MICCAI 2019 | CVPR
- 下一篇: android 视网膜黄斑检查 amsl